From 662f619ba2ad13573fe786b7ed46f195a8e078c0 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 9 Jun 2010 16:44:26 +0900 Subject: [PATCH] Rewrite. --- README | 9 +- configure.ac | 3 +- docs/reference/eek/Makefile.am | 4 +- docs/reference/eek/eek-docs.sgml | 8 +- eek/Makefile.am | 37 +- eek/eek-clutter-key-actor.c | 561 ++++++++++++++++++++++ eek/eek-clutter-key-actor.h | 60 +++ eek/eek-clutter-key.c | 543 ++------------------- eek/eek-clutter-key.h | 11 +- eek/eek-clutter-keyboard.c | 303 +++--------- eek/eek-clutter-keyboard.h | 18 +- eek/eek-clutter-private.c | 31 -- eek/eek-clutter-private.h | 34 -- eek/eek-clutter-section.c | 333 +++---------- eek/eek-clutter-section.h | 8 +- eek/eek-container.c | 157 ++++++ eek/eek-container.h | 79 +++ eek/eek-element.c | 235 +++++++++ eek/eek-element.h | 77 +++ eek/eek-gtk-key.c | 350 -------------- eek/eek-gtk-key.h | 56 --- eek/eek-gtk-keyboard.c | 298 ------------ eek/eek-gtk-keyboard.h | 57 --- eek/eek-gtk-private.c | 31 -- eek/eek-gtk-private.h | 34 -- eek/eek-gtk-section.c | 345 ------------- eek/eek-gtk-section.h | 56 --- eek/eek-gtk.h | 26 - eek/eek-gtk.pc.in | 30 -- eek/eek-key.c | 797 ++++++++++++++++++------------- eek/eek-key.h | 35 +- eek/eek-keyboard.c | 375 ++++++++++----- eek/eek-keyboard.h | 50 +- eek/eek-layout.c | 50 +- eek/eek-layout.h | 27 +- eek/eek-private.c | 234 --------- eek/eek-private.h | 36 -- eek/eek-section.c | 583 +++++++++++----------- eek/eek-section.h | 126 ++--- eek/eek-simple-key.c | 439 ----------------- eek/eek-simple-key.h | 55 --- eek/eek-simple-keyboard.c | 217 --------- eek/eek-simple-keyboard.h | 57 --- eek/eek-simple-section.c | 352 -------------- eek/eek-simple-section.h | 56 --- eek/eek-types.c | 6 + eek/eek-types.h | 2 + eek/eek-xkb-layout.c | 124 ++--- eek/eek-xkb-layout.h | 4 +- examples/Makefile.am | 5 +- examples/eek-clutter-xkb-test.c | 27 +- tests/Makefile.am | 6 +- tests/eek-simple-test.c | 90 ++-- 53 files changed, 2653 insertions(+), 4894 deletions(-) create mode 100644 eek/eek-clutter-key-actor.c create mode 100644 eek/eek-clutter-key-actor.h delete mode 100644 eek/eek-clutter-private.c delete mode 100644 eek/eek-clutter-private.h create mode 100644 eek/eek-container.c create mode 100644 eek/eek-container.h create mode 100644 eek/eek-element.c create mode 100644 eek/eek-element.h delete mode 100644 eek/eek-gtk-key.c delete mode 100644 eek/eek-gtk-key.h delete mode 100644 eek/eek-gtk-keyboard.c delete mode 100644 eek/eek-gtk-keyboard.h delete mode 100644 eek/eek-gtk-private.c delete mode 100644 eek/eek-gtk-private.h delete mode 100644 eek/eek-gtk-section.c delete mode 100644 eek/eek-gtk-section.h delete mode 100644 eek/eek-gtk.h delete mode 100644 eek/eek-gtk.pc.in delete mode 100644 eek/eek-private.c delete mode 100644 eek/eek-private.h delete mode 100644 eek/eek-simple-key.c delete mode 100644 eek/eek-simple-key.h delete mode 100644 eek/eek-simple-keyboard.c delete mode 100644 eek/eek-simple-keyboard.h delete mode 100644 eek/eek-simple-section.c delete mode 100644 eek/eek-simple-section.h diff --git a/README b/README index c0940d01..d18e8218 100644 --- a/README +++ b/README @@ -40,13 +40,8 @@ and an XKB-based layout engine: 10: /* Apply the layout to the keyboard. */ 11: eek_keyboard_set_layout (keyboard, layout); 12: -13: clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard)); - -To use GTK+-based keyboard elements instead of Clutter, simply replace -line 8 and 13 with: - - 8: keyboard = eek_gtk_keyboard_new (); -13: gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(keyboard)); +13: clutter_group_add (CLUTTER_GROUP(stage), +14: eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard))); Footnotes: [1] http://en.wikipedia.org/wiki/Builder_pattern diff --git a/configure.ac b/configure.ac index c33a52b7..333d89b2 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,5 @@ docs/reference/Makefile docs/reference/eek/Makefile eek/eek.pc eek/eek-clutter.pc -eek/eek-xkb.pc -eek/eek-gtk.pc]) +eek/eek-xkb.pc]) AC_OUTPUT diff --git a/docs/reference/eek/Makefile.am b/docs/reference/eek/Makefile.am index 372625b7..0237c254 100644 --- a/docs/reference/eek/Makefile.am +++ b/docs/reference/eek/Makefile.am @@ -77,8 +77,7 @@ EXTRA_HFILES= # Header files to ignore when scanning. Use base file name, no paths # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES= eek-private.h \ - eek-clutter-private.h \ - eek-keysyms.h \ + eek-keysym.h \ $(NULL) # Images to copy into HTML directory. @@ -103,7 +102,6 @@ GTKDOC_CFLAGS = $(GOBJECT2_CFLAGS) GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \ $(top_srcdir)/eek/libeek-clutter.la \ $(top_srcdir)/eek/libeek-xkb.la \ - $(top_srcdir)/eek/libeek-gtk.la \ $(GOBJECT2_LIBS) \ $(CLUTTER_LIBS) \ $(XKB_LIBS) \ diff --git a/docs/reference/eek/eek-docs.sgml b/docs/reference/eek/eek-docs.sgml index 262f1161..de2970a1 100644 --- a/docs/reference/eek/eek-docs.sgml +++ b/docs/reference/eek/eek-docs.sgml @@ -14,6 +14,8 @@ Base classes and interfaces + + @@ -30,12 +32,6 @@ XKB layout engine - - GTK keyboard elements - - - - Object Hierarchy diff --git a/eek/Makefile.am b/eek/Makefile.am index 73d07660..eaa8db9b 100644 --- a/eek/Makefile.am +++ b/eek/Makefile.am @@ -16,25 +16,21 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA -lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la libeek-gtk.la +lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la libeek_la_SOURCES = \ eek-layout.c \ eek-layout.h \ + eek-element.c \ + eek-element.h \ + eek-container.c \ + eek-container.h \ eek-keyboard.c \ eek-keyboard.h \ eek-section.c \ eek-section.h \ eek-key.c \ eek-key.h \ - eek-simple-keyboard.c \ - eek-simple-keyboard.h \ - eek-simple-section.c \ - eek-simple-section.h \ - eek-simple-key.c \ - eek-simple-key.h \ - eek-private.c \ - eek-private.h \ eek-types.h \ eek-types.c \ eek-keysym.h \ @@ -54,8 +50,8 @@ libeek_clutter_la_SOURCES = \ eek-clutter-section.h \ eek-clutter-key.c \ eek-clutter-key.h \ - eek-clutter-private.c \ - eek-clutter-private.h \ + eek-clutter-key-actor.c \ + eek-clutter-key-actor.h \ eek-clutter.h \ $(NULL) @@ -70,23 +66,10 @@ libeek_xkb_la_SOURCES = \ libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS) libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS) -libeek_gtk_la_SOURCES = \ - eek-gtk-keyboard.c \ - eek-gtk-keyboard.h \ - eek-gtk-section.c \ - eek-gtk-section.h \ - eek-gtk-key.c \ - eek-gtk-key.h \ - eek-gtk-private.c \ - eek-gtk-private.h \ - eek-gtk.h \ - $(NULL) - -libeek_gtk_la_CFLAGS = $(GTK2_CFLAGS) -libeek_gtk_la_LIBADD = libeek.la $(GTK2_LIBS) - eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek eek_HEADERS = \ + $(top_srcdir)/eek/eek-element.h \ + $(top_srcdir)/eek/eek-container.h \ $(top_srcdir)/eek/eek-keyboard.h \ $(top_srcdir)/eek/eek-section.h \ $(top_srcdir)/eek/eek-key.h \ @@ -111,7 +94,7 @@ eek-keyname-keysym-labels.h: keyname-keysym-labels.txt $(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@ pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = eek.pc eek-clutter.pc eek-xkb.pc eek-gtk.pc +pkgconfig_DATA = eek.pc eek-clutter.pc eek-xkb.pc DISTCLEANFILES = \ eek-special-keysym-labels.h \ diff --git a/eek/eek-clutter-key-actor.c b/eek/eek-clutter-key-actor.c new file mode 100644 index 00000000..0bdaae92 --- /dev/null +++ b/eek/eek-clutter-key-actor.c @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-clutter-key-actor + * @short_description: Custom #ClutterActor drawing a key shape + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include "eek-clutter-key-actor.h" +#include "eek-keysym.h" +#include +#include + +#define noKBDRAW_DEBUG + +G_DEFINE_TYPE (EekClutterKeyActor, eek_clutter_key_actor, + CLUTTER_TYPE_GROUP); + +#define EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorPrivate)) + +struct _EekClutterKeyActorPrivate +{ + EekKey *key; + ClutterActor *texture; +}; + +static gboolean on_event (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data); +static ClutterActor *get_texture (EekClutterKeyActor *actor); +static void draw_key_on_layout (EekKey *key, + PangoLayout *layout); + +static void +eek_clutter_key_actor_real_paint (ClutterActor *self) +{ + EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE (self); + PangoLayout *layout; + PangoRectangle logical_rect = { 0, }; + CoglColor color; + ClutterGeometry geom; + EekBounds bounds; + + eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds); + clutter_actor_set_anchor_point_from_gravity (self, + CLUTTER_GRAVITY_CENTER); + clutter_actor_set_position (self, + bounds.x + bounds.width / 2, + bounds.y + bounds.height / 2); + + if (!priv->texture) { + priv->texture = get_texture (EEK_CLUTTER_KEY_ACTOR(self)); + clutter_actor_set_position (priv->texture, 0, 0); + clutter_container_add_actor (CLUTTER_CONTAINER(self), priv->texture); + } + + CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)-> + paint (self); + + /* Draw the label on the key. */ + layout = clutter_actor_create_pango_layout (self, NULL); + draw_key_on_layout (priv->key, layout); + pango_layout_get_extents (layout, NULL, &logical_rect); + + /* FIXME: Color should be configurable through a property. */ + cogl_color_set_from_4ub (&color, 0x80, 0x00, 0x00, 0xff); + clutter_actor_get_allocation_geometry (self, &geom); + cogl_pango_render_layout (layout, + (geom.width - logical_rect.width / PANGO_SCALE) / 2, + (geom.height - logical_rect.height / PANGO_SCALE) / 2, + &color, + 0); + g_object_unref (layout); +} + +/* FIXME: This is a workaround for the bug + * http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer + * says this is not a right way to solve the original problem. + */ +static void +eek_clutter_key_actor_real_get_preferred_width (ClutterActor *self, + gfloat for_height, + gfloat *min_width_p, + gfloat *natural_width_p) +{ + EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE (self); + PangoLayout *layout; + + /* Draw the label on the key - just to validate the glyph cache. */ + layout = clutter_actor_create_pango_layout (self, NULL); + draw_key_on_layout (priv->key, layout); + cogl_pango_ensure_glyph_cache_for_layout (layout); + g_object_unref (layout); + + CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)-> + get_preferred_width (self, for_height, min_width_p, natural_width_p); +} + +static void +eek_clutter_key_actor_finalize (GObject *object) +{ + EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(object); + + clutter_group_remove_all (CLUTTER_GROUP(object)); + g_object_unref (priv->key); + if (priv->texture) + g_object_unref (priv->texture); + G_OBJECT_CLASS (eek_clutter_key_actor_parent_class)->finalize (object); +} + +static void +eek_clutter_key_actor_class_init (EekClutterKeyActorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + + g_type_class_add_private (gobject_class, + sizeof (EekClutterKeyActorPrivate)); + + klass->outline_textures = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + g_free); + + actor_class->paint = eek_clutter_key_actor_real_paint; + /* FIXME: This is a workaround for the bug + * http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer + * says this is not a right way to solve the original problem. + */ + actor_class->get_preferred_width = + eek_clutter_key_actor_real_get_preferred_width; + + gobject_class->finalize = eek_clutter_key_actor_finalize; +} + +static void +eek_clutter_key_actor_init (EekClutterKeyActor *self) +{ + EekClutterKeyActorPrivate *priv; + + priv = self->priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(self); + priv->key = NULL; + priv->texture = NULL; + clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE); + g_signal_connect (self, "event", G_CALLBACK (on_event), NULL); +} + +ClutterActor * +eek_clutter_key_actor_new (EekKey *key) +{ + EekClutterKeyActor *actor; + + actor = g_object_new (EEK_TYPE_CLUTTER_KEY_ACTOR, NULL); + actor->priv->key = key; + g_object_ref (actor->priv->key); + return CLUTTER_ACTOR(actor); +} + +static void +on_key_animate_complete (ClutterAnimation *animation, + gpointer user_data) +{ + ClutterActor *actor = (ClutterActor*)user_data; + + /* reset after effect */ + clutter_actor_set_opacity (actor, 0xff); + clutter_actor_set_scale (actor, 1.0, 1.0); +} + +static void +key_enlarge (ClutterActor *actor) +{ + clutter_actor_set_scale (actor, 1.0, 1.0); + clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150, + "scale-x", 1.5, + "scale-y", 1.5, + NULL); +} + +static void +key_shrink (ClutterActor *actor) +{ + clutter_actor_set_scale (actor, 1.5, 1.5); + clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150, + "scale-x", 1.0, + "scale-y", 1.0, + NULL); +} + +static gboolean +on_event (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data) +{ + if (clutter_event_get_source (event) == actor) { + EekClutterKeyActorPrivate *priv = + EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor); + ClutterActor *section; + + g_return_val_if_fail (priv, FALSE); + /* Make sure the enlarged key show up on the keys which belong + to other sections. */ + section = clutter_actor_get_parent (actor); + clutter_actor_raise_top (section); + clutter_actor_raise_top (actor); + if (event->type == CLUTTER_BUTTON_PRESS) { + key_enlarge (actor); + g_signal_emit_by_name (priv->key, "pressed"); + } else if (event->type == CLUTTER_BUTTON_RELEASE) { + key_shrink (actor); + g_signal_emit_by_name (priv->key, "released"); + } + } + return FALSE; +} + +static gdouble +length (gdouble x, gdouble y) +{ + return sqrt (x * x + y * y); +} + +static gdouble +point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny) +{ + return ax * nx + ay * ny; +} + +static void +normal_form (gdouble ax, gdouble ay, + gdouble bx, gdouble by, + gdouble * nx, gdouble * ny, gdouble * d) +{ + gdouble l; + + *nx = by - ay; + *ny = ax - bx; + + l = length (*nx, *ny); + + *nx /= l; + *ny /= l; + + *d = point_line_distance (ax, ay, *nx, *ny); +} + +static void +inverse (gdouble a, gdouble b, gdouble c, gdouble d, + gdouble * e, gdouble * f, gdouble * g, gdouble * h) +{ + gdouble det; + + det = a * d - b * c; + + *e = d / det; + *f = -b / det; + *g = -c / det; + *h = a / det; +} + +static void +multiply (gdouble a, gdouble b, gdouble c, gdouble d, + gdouble e, gdouble f, gdouble * x, gdouble * y) +{ + *x = a * e + b * f; + *y = c * e + d * f; +} + +static void +intersect (gdouble n1x, gdouble n1y, gdouble d1, + gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y) +{ + gdouble e, f, g, h; + + inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h); + multiply (e, f, g, h, d1, d2, x, y); +} + + +/* draw an angle from the current point to b and then to c, + * with a rounded corner of the given radius. + */ +static void +rounded_corner (cairo_t * cr, + gdouble bx, gdouble by, + gdouble cx, gdouble cy, gdouble radius) +{ + gdouble ax, ay; + gdouble n1x, n1y, d1; + gdouble n2x, n2y, d2; + gdouble pd1, pd2; + gdouble ix, iy; + gdouble dist1, dist2; + gdouble nx, ny, d; + gdouble a1x, a1y, c1x, c1y; + gdouble phi1, phi2; + + cairo_get_current_point (cr, &ax, &ay); +#ifdef KBDRAW_DEBUG + printf (" current point: (%f, %f), radius %f:\n", ax, ay, + radius); +#endif + + /* make sure radius is not too large */ + dist1 = length (bx - ax, by - ay); + dist2 = length (cx - bx, cy - by); + + radius = MIN (radius, MIN (dist1, dist2)); + + /* construct normal forms of the lines */ + normal_form (ax, ay, bx, by, &n1x, &n1y, &d1); + normal_form (bx, by, cx, cy, &n2x, &n2y, &d2); + + /* find which side of the line a,b the point c is on */ + if (point_line_distance (cx, cy, n1x, n1y) < d1) + pd1 = d1 - radius; + else + pd1 = d1 + radius; + + /* find which side of the line b,c the point a is on */ + if (point_line_distance (ax, ay, n2x, n2y) < d2) + pd2 = d2 - radius; + else + pd2 = d2 + radius; + + /* intersect the parallels to find the center of the arc */ + intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy); + + nx = (bx - ax) / dist1; + ny = (by - ay) / dist1; + d = point_line_distance (ix, iy, nx, ny); + + /* a1 is the point on the line a-b where the arc starts */ + intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y); + + nx = (cx - bx) / dist2; + ny = (cy - by) / dist2; + d = point_line_distance (ix, iy, nx, ny); + + /* c1 is the point on the line b-c where the arc ends */ + intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y); + + /* determine the first angle */ + if (a1x - ix == 0) + phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2; + else if (a1x - ix > 0) + phi1 = atan ((a1y - iy) / (a1x - ix)); + else + phi1 = M_PI + atan ((a1y - iy) / (a1x - ix)); + + /* determine the second angle */ + if (c1x - ix == 0) + phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2; + else if (c1x - ix > 0) + phi2 = atan ((c1y - iy) / (c1x - ix)); + else + phi2 = M_PI + atan ((c1y - iy) / (c1x - ix)); + + /* compute the difference between phi2 and phi1 mod 2pi */ + d = phi2 - phi1; + while (d < 0) + d += 2 * M_PI; + while (d > 2 * M_PI) + d -= 2 * M_PI; + +#ifdef KBDRAW_DEBUG + printf (" line 1 to: (%f, %f):\n", a1x, a1y); +#endif + if (!(isnan (a1x) || isnan (a1y))) + cairo_line_to (cr, a1x, a1y); + + /* pick the short arc from phi1 to phi2 */ + if (d < M_PI) + cairo_arc (cr, ix, iy, radius, phi1, phi2); + else + cairo_arc_negative (cr, ix, iy, radius, phi1, phi2); + +#ifdef KBDRAW_DEBUG + printf (" line 2 to: (%f, %f):\n", cx, cy); +#endif + cairo_line_to (cr, cx, cy); +} + +void +draw_rounded_polygon (cairo_t *cr, + gboolean filled, + gdouble radius, + EekPoint *points, + gint num_points) +{ + gint i, j; + + cairo_move_to (cr, + (gdouble) (points[num_points - 1].x + + points[0].x) / 2, + (gdouble) (points[num_points - 1].y + + points[0].y) / 2); + + +#ifdef KBDRAW_DEBUG + printf (" rounded polygon of radius %f:\n", radius); +#endif + for (i = 0; i < num_points; i++) { + j = (i + 1) % num_points; + rounded_corner (cr, (gdouble) points[i].x, + (gdouble) points[i].y, + (gdouble) (points[i].x + points[j].x) / 2, + (gdouble) (points[i].y + points[j].y) / 2, + radius); +#ifdef KBDRAW_DEBUG + printf (" corner (%d, %d) -> (%d, %d):\n", + points[i].x, points[i].y, points[j].x, + points[j].y); +#endif + }; + cairo_close_path (cr); + + if (filled) + cairo_fill (cr); + else + cairo_stroke (cr); +} + +static ClutterActor * +create_texture_for_key (EekKey *key) +{ + ClutterActor *texture; + cairo_t *cr; + cairo_pattern_t *pat; + EekOutline *outline; + EekBounds bounds; + + outline = eek_key_get_outline (EEK_KEY(key)); + eek_element_get_bounds (EEK_ELEMENT(key), &bounds); + + texture = clutter_cairo_texture_new (bounds.width, bounds.height); + cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture)); + cairo_set_line_width (cr, 1); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0); + cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1); + cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1); + + cairo_set_source (cr, pat); + + draw_rounded_polygon (cr, + TRUE, + outline->corner_radius, + outline->points, + outline->num_points); + + cairo_pattern_destroy (pat); + + cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5); + draw_rounded_polygon (cr, + FALSE, + outline->corner_radius, + outline->points, + outline->num_points); + cairo_destroy (cr); + return texture; +} + +static ClutterActor * +get_texture (EekClutterKeyActor *actor) +{ + ClutterActor *texture; + GHashTable *outline_textures; + EekOutline *outline; + + outline_textures = EEK_CLUTTER_KEY_ACTOR_GET_CLASS(actor)-> + outline_textures; + + outline = eek_key_get_outline (actor->priv->key); + texture = g_hash_table_lookup (outline_textures, outline); + if (texture == NULL) { + texture = create_texture_for_key (actor->priv->key); + g_hash_table_insert (outline_textures, outline, texture); + } else + texture = clutter_clone_new (texture); + return texture; +} + +static void +draw_text_on_layout (PangoLayout *layout, + const gchar *text, + gdouble scale) +{ + PangoFontDescription *font_desc; + +#define FONT_SIZE (720 * 50) + /* FIXME: Font should be configurable through a property. */ + font_desc = pango_font_description_from_string ("Sans"); + pango_font_description_set_size (font_desc, FONT_SIZE * scale); + pango_layout_set_font_description (layout, font_desc); + pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); + pango_layout_set_text (layout, text, -1); + pango_font_description_free (font_desc); +} + +static void +draw_key_on_layout (EekKey *key, + PangoLayout *layout) +{ + PangoLayout *buffer; + PangoRectangle logical_rect = { 0, }; + EekBounds bounds; + guint keysym; + const gchar *label, *empty_label = ""; + gdouble scale_x, scale_y; + + eek_element_get_bounds (EEK_ELEMENT(key), &bounds); + keysym = eek_key_get_keysym (key); + if (keysym == EEK_INVALID_KEYSYM) + return; + label = eek_keysym_to_string (keysym); + if (!label) + label = empty_label; + + /* Compute the layout extents. */ + buffer = pango_layout_copy (layout); + draw_text_on_layout (buffer, label, 1.0); + pango_layout_get_extents (buffer, NULL, &logical_rect); + scale_x = scale_y = 1.0; + if (PANGO_PIXELS(logical_rect.width) > bounds.width) + scale_x = bounds.width / PANGO_PIXELS(logical_rect.width); + if (PANGO_PIXELS(logical_rect.height) > bounds.height) + scale_y = bounds.height / PANGO_PIXELS(logical_rect.height); + g_object_unref (buffer); + + /* Actually draw on the layout */ + draw_text_on_layout (layout, + label, + (scale_x < scale_y ? scale_x : scale_y) * 0.8); + if (label != empty_label) + g_free ((gpointer)label); +} diff --git a/eek/eek-clutter-key-actor.h b/eek/eek-clutter-key-actor.h new file mode 100644 index 00000000..110f7110 --- /dev/null +++ b/eek/eek-clutter-key-actor.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CLUTTER_KEY_ACTOR_H +#define EEK_CLUTTER_KEY_ACTOR_H 1 + +#include +#include "eek-key.h" + +G_BEGIN_DECLS +#define EEK_TYPE_CLUTTER_KEY_ACTOR (eek_clutter_key_actor_get_type()) +#define EEK_CLUTTER_KEY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActor)) +#define EEK_CLUTTER_KEY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorClass)) +#define EEK_IS_CLUTTER_KEY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR)) +#define EEK_IS_CLUTTER_KEY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEY_ACTOR)) +#define EEK_CLUTTER_KEY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorClass)) + +typedef struct _EekClutterKeyActor EekClutterKeyActor; +typedef struct _EekClutterKeyActorClass EekClutterKeyActorClass; +typedef struct _EekClutterKeyActorPrivate EekClutterKeyActorPrivate; + +struct _EekClutterKeyActor +{ + /*< private >*/ + ClutterGroup parent; + + /*< private >*/ + EekClutterKeyActorPrivate *priv; +}; + +struct _EekClutterKeyActorClass +{ + /*< private >*/ + ClutterGroupClass parent_class; + + /* outline pointer -> ClutterTexture */ + GHashTable *outline_textures; +}; + +GType eek_clutter_key_actor_get_type (void) G_GNUC_CONST; +ClutterActor *eek_clutter_key_actor_new (EekKey *key); + +G_END_DECLS +#endif /* EEK_CLUTTER_KEY_ACTOR_H */ diff --git a/eek/eek-clutter-key.c b/eek/eek-clutter-key.c index 8c6f52aa..f1ed84a7 100644 --- a/eek/eek-clutter-key.c +++ b/eek/eek-clutter-key.c @@ -20,205 +20,52 @@ /** * SECTION:eek-clutter-key - * @short_description: #EekKey implemented as a #ClutterActor - * - * The #EekClutterKey class implements the #EekKeyIface interface as a - * #ClutterActor. + * @short_description: #EekKey embedding a #ClutterActor */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ + #include "eek-clutter-key.h" -#include "eek-simple-key.h" -#include "eek-keysym.h" +#include "eek-clutter-key-actor.h" -enum { - PROP_0, - PROP_KEYCODE, - PROP_KEYSYMS, - PROP_COLUMN, - PROP_ROW, - PROP_OUTLINE, - PROP_BOUNDS, - PROP_GROUP, - PROP_LEVEL, - PROP_LAST -}; - -static void eek_key_iface_init (EekKeyIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekClutterKey, eek_clutter_key, - CLUTTER_TYPE_GROUP, - G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY, - eek_key_iface_init)); +G_DEFINE_TYPE (EekClutterKey, eek_clutter_key, EEK_TYPE_KEY); #define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate)) struct _EekClutterKeyPrivate { - EekSimpleKey *simple; + ClutterActor *actor; }; -static guint -eek_clutter_key_real_get_keycode (EekKey *self) +static void +eek_clutter_key_real_set_name (EekElement *self, + const gchar *name) { EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - g_return_val_if_fail (priv, EEK_INVALID_KEYCODE); - return eek_key_get_keycode (EEK_KEY(priv->simple)); + EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)-> + set_name (self, name); + + g_return_if_fail (priv->actor); + + clutter_actor_set_name (CLUTTER_ACTOR(priv->actor), name); } static void -eek_clutter_key_real_set_keysyms (EekKey *self, - guint *keysyms, - gint groups, - gint levels) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels); -} - -static void -eek_clutter_key_real_get_keysyms (EekKey *self, - guint **keysyms, - gint *groups, - gint *levels) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_get_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels); -} - -static gint -eek_clutter_key_real_get_groups (EekKey *self) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - return eek_key_get_groups (EEK_KEY(priv->simple)); -} - -static guint -eek_clutter_key_real_get_keysym (EekKey *self) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_INVALID_KEYSYM); - return eek_key_get_keysym (EEK_KEY(priv->simple)); -} - -static void -eek_clutter_key_real_set_index (EekKey *self, - gint column, - gint row) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_index (EEK_KEY(priv->simple), column, row); -} - -static void -eek_clutter_key_real_get_index (EekKey *self, - gint *column, - gint *row) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_get_index (EEK_KEY(priv->simple), column, row); -} - -static void -eek_clutter_key_real_set_outline (EekKey *self, EekOutline *outline) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_outline (EEK_KEY(priv->simple), outline); -} - -static EekOutline * -eek_clutter_key_real_get_outline (EekKey *self) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, NULL); - return eek_key_get_outline (EEK_KEY(priv->simple)); -} - -static void -eek_clutter_key_real_set_bounds (EekKey *self, EekBounds *bounds) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_bounds (EEK_KEY(priv->simple), bounds); - - clutter_actor_set_anchor_point_from_gravity (CLUTTER_ACTOR(self), - CLUTTER_GRAVITY_CENTER); - clutter_actor_set_position (CLUTTER_ACTOR(self), - bounds->x + bounds->width / 2, - bounds->y + bounds->height / 2); -} - -static void -eek_clutter_key_real_get_bounds (EekKey *self, +eek_clutter_key_real_set_bounds (EekElement *self, EekBounds *bounds) { EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - g_return_if_fail (priv); - return eek_key_get_bounds (EEK_KEY(priv->simple), bounds); -} + EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)-> + set_bounds (self, bounds); -static void -eek_clutter_key_real_set_keysym_index (EekKey *self, - gint group, - gint level) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + g_return_if_fail (priv->actor); - g_return_if_fail (priv); - eek_key_set_keysym_index (EEK_KEY(priv->simple), group, level); -} - -static void -eek_clutter_key_real_get_keysym_index (EekKey *self, gint *group, gint *level) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - return eek_key_get_keysym_index (EEK_KEY(priv->simple), group, level); -} - -static void -eek_key_iface_init (EekKeyIface *iface) -{ - iface->get_keycode = eek_clutter_key_real_get_keycode; - iface->set_keysyms = eek_clutter_key_real_set_keysyms; - iface->get_keysyms = eek_clutter_key_real_get_keysyms; - iface->get_groups = eek_clutter_key_real_get_groups; - iface->get_keysym = eek_clutter_key_real_get_keysym; - iface->set_index = eek_clutter_key_real_set_index; - iface->get_index = eek_clutter_key_real_get_index; - iface->set_outline = eek_clutter_key_real_set_outline; - iface->get_outline = eek_clutter_key_real_get_outline; - iface->set_bounds = eek_clutter_key_real_set_bounds; - iface->get_bounds = eek_clutter_key_real_get_bounds; - iface->set_keysym_index = eek_clutter_key_real_set_keysym_index; - iface->get_keysym_index = eek_clutter_key_real_get_keysym_index; -} - -static void -eek_clutter_key_dispose (GObject *object) -{ - clutter_group_remove_all (CLUTTER_GROUP(object)); - G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object); + clutter_actor_set_position (priv->actor, bounds->x, bounds->y); + clutter_actor_set_size (priv->actor, bounds->width, bounds->height); } static void @@ -226,358 +73,40 @@ eek_clutter_key_finalize (GObject *object) { EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); - g_object_unref (priv->simple); + if (priv->actor) { + clutter_group_remove_all (CLUTTER_GROUP(priv->actor)); + g_object_unref (priv->actor); + } G_OBJECT_CLASS (eek_clutter_key_parent_class)->finalize (object); } -static void -draw_text_on_layout (PangoLayout *layout, - const gchar *text, - gdouble scale) -{ - PangoFontDescription *font_desc; - -#define FONT_SIZE (720 * 50) - /* FIXME: Font should be configurable through a property. */ - font_desc = pango_font_description_from_string ("Sans"); - pango_font_description_set_size (font_desc, FONT_SIZE * scale); - pango_layout_set_font_description (layout, font_desc); - pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); - pango_layout_set_text (layout, text, -1); - pango_font_description_free (font_desc); -} - -static void -draw_key_on_layout (EekKey *key, - PangoLayout *layout) -{ - PangoLayout *buffer; - PangoRectangle logical_rect = { 0, }; - EekBounds bounds; - guint keysym; - const gchar *label, *empty_label = ""; - gdouble scale_x, scale_y; - - eek_key_get_bounds (key, &bounds); - keysym = eek_key_get_keysym (key); - if (keysym == EEK_INVALID_KEYSYM) - return; - label = eek_keysym_to_string (keysym); - if (!label) - label = empty_label; - - /* Compute the layout extents. */ - buffer = pango_layout_copy (layout); - draw_text_on_layout (buffer, label, 1.0); - pango_layout_get_extents (buffer, NULL, &logical_rect); - scale_x = scale_y = 1.0; - if (PANGO_PIXELS(logical_rect.width) > bounds.width) - scale_x = bounds.width / PANGO_PIXELS(logical_rect.width); - if (PANGO_PIXELS(logical_rect.height) > bounds.height) - scale_y = bounds.height / PANGO_PIXELS(logical_rect.height); - g_object_unref (buffer); - - /* Actually draw on the layout */ - draw_text_on_layout (layout, - label, - (scale_x < scale_y ? scale_x : scale_y) * 0.8); - if (label != empty_label) - g_free ((gpointer)label); -} - -static void -eek_clutter_key_paint (ClutterActor *self) -{ - PangoLayout *layout; - PangoRectangle logical_rect = { 0, }; - CoglColor color; - ClutterGeometry geom; - EekBounds bounds; - gfloat width, height; - gfloat x, y; - - g_return_if_fail (CLUTTER_IS_ACTOR(self)); - g_return_if_fail (EEK_IS_KEY(self)); - - /* Draw the background texture first. */ - CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->paint (self); - - /* Draw the label on the key. */ - layout = clutter_actor_create_pango_layout (self, NULL); - draw_key_on_layout (EEK_KEY(self), layout); - pango_layout_get_extents (layout, NULL, &logical_rect); - - /* FIXME: Color should be configurable through a property. */ - cogl_color_set_from_4ub (&color, 0x80, 0x00, 0x00, 0xff); - clutter_actor_get_allocation_geometry (self, &geom); - cogl_pango_render_layout (layout, - (geom.width - logical_rect.width / PANGO_SCALE) / 2, - (geom.height - logical_rect.height / PANGO_SCALE) / 2, - &color, - 0); - g_object_unref (layout); -} - -/* FIXME: This is a workaround for the bug - * http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer - * says this is not a right way to solve the original problem. - */ -static void -eek_clutter_key_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - PangoLayout *layout; - - /* Draw the label on the key - just to validate the glyph cache. */ - layout = clutter_actor_create_pango_layout (self, NULL); - draw_key_on_layout (EEK_KEY(self), layout); - cogl_pango_ensure_glyph_cache_for_layout (layout); - g_object_unref (layout); - - CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->get_preferred_width - (self, for_height, min_width_p, natural_width_p); -} - -static void -eek_clutter_key_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - /* Properties which affect the appearance of the key as a - ClutterActor. */ - case PROP_BOUNDS: - eek_key_set_bounds (EEK_KEY(object), - g_value_get_boxed (value)); - break; - case PROP_OUTLINE: - eek_key_set_outline (EEK_KEY(object), - g_value_get_pointer (value)); - break; - /* Otherwise delegate to priv->simple or the parent. */ - case PROP_KEYCODE: - case PROP_KEYSYMS: - case PROP_COLUMN: - case PROP_GROUP: - case PROP_ROW: - case PROP_LEVEL: - g_object_set_property (G_OBJECT(priv->simple), - g_param_spec_get_name (pspec), - value); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_clutter_key_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); - EekBounds bounds; - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_BOUNDS: - eek_key_get_bounds (EEK_KEY(object), &bounds); - g_value_set_boxed (value, &bounds); - break; - case PROP_KEYCODE: - case PROP_KEYSYMS: - case PROP_COLUMN: - case PROP_ROW: - case PROP_OUTLINE: - case PROP_GROUP: - case PROP_LEVEL: - g_object_get_property (G_OBJECT(priv->simple), - g_param_spec_get_name (pspec), - value); - break; - default: - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - static void eek_clutter_key_class_init (EekClutterKeyClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + EekElementClass *element_class = EEK_ELEMENT_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (EekClutterKeyPrivate)); - actor_class->paint = eek_clutter_key_paint; - /* FIXME: This is a workaround for the bug - * http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer - * says this is not a right way to solve the original problem. - */ - actor_class->get_preferred_width = eek_clutter_key_get_preferred_width; - - gobject_class->set_property = eek_clutter_key_set_property; - gobject_class->get_property = eek_clutter_key_get_property; - gobject_class->finalize = eek_clutter_key_finalize; - gobject_class->dispose = eek_clutter_key_dispose; - - g_object_class_override_property (gobject_class, - PROP_KEYCODE, - "keycode"); - g_object_class_override_property (gobject_class, - PROP_KEYSYMS, - "keysyms"); - g_object_class_override_property (gobject_class, - PROP_COLUMN, - "column"); - g_object_class_override_property (gobject_class, - PROP_ROW, - "row"); - g_object_class_override_property (gobject_class, - PROP_OUTLINE, - "outline"); - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); - g_object_class_override_property (gobject_class, - PROP_GROUP, - "group"); - g_object_class_override_property (gobject_class, - PROP_LEVEL, - "level"); -} - -static void -on_key_animate_complete (ClutterAnimation *animation, - gpointer user_data) -{ - ClutterActor *actor = (ClutterActor*)user_data; - - /* reset after effect */ - clutter_actor_set_opacity (actor, 0xff); - clutter_actor_set_scale (actor, 1.0, 1.0); -} - -static void -key_enlarge (ClutterActor *actor) -{ - clutter_actor_set_scale (actor, 1.0, 1.0); - clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150, - "scale-x", 1.5, - "scale-y", 1.5, - NULL); -} - -static void -key_shrink (ClutterActor *actor) -{ - clutter_actor_set_scale (actor, 1.5, 1.5); - clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150, - "scale-x", 1.0, - "scale-y", 1.0, - NULL); -} - -static gboolean -on_event (ClutterActor *actor, - ClutterEvent *event, - gpointer user_data) -{ - g_return_val_if_fail (EEK_IS_KEY(actor), FALSE); - if (clutter_event_get_source (event) == actor) { - ClutterActor *section; - - /* Make sure the enlarged key show up on the keys which belong - to other sections. */ - section = clutter_actor_get_parent (actor); - clutter_actor_raise_top (section); - clutter_actor_raise_top (actor); - if (event->type == CLUTTER_BUTTON_PRESS) - key_enlarge (actor); - else if (event->type == CLUTTER_BUTTON_RELEASE) - key_shrink (actor); - } - return FALSE; + element_class->set_name = eek_clutter_key_real_set_name; + element_class->set_bounds = eek_clutter_key_real_set_bounds; + gobject_class->finalize = eek_clutter_key_finalize; } static void eek_clutter_key_init (EekClutterKey *self) { EekClutterKeyPrivate *priv; - - priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); - priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEY, NULL); - - clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE); - g_signal_connect (self, "event", G_CALLBACK (on_event), NULL); + priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE (self); + priv->actor = NULL; } ClutterActor * -eek_clutter_key_create_texture (EekClutterKey *key) +eek_clutter_key_get_actor (EekClutterKey *key) { - EekOutline *outline; - EekBounds bounds; - ClutterActor *texture; - cairo_t *cr; - cairo_pattern_t *pat; - - outline = eek_key_get_outline (EEK_KEY(key)); - eek_key_get_bounds (EEK_KEY(key), &bounds); - - texture = clutter_cairo_texture_new (bounds.width, bounds.height); - cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture)); - cairo_set_line_width (cr, 1); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - - pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0); - cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1); - cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1); - - cairo_set_source (cr, pat); - - eek_cairo_draw_rounded_polygon (cr, - TRUE, - outline->corner_radius, - outline->points, - outline->num_points); - - cairo_pattern_destroy (pat); - - cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5); - eek_cairo_draw_rounded_polygon (cr, - FALSE, - outline->corner_radius, - outline->points, - outline->num_points); - cairo_destroy (cr); - return texture; -} - -/** - * eek_clutter_key_set_texture: - * @key: an #EekClutterKey - * @texture: an #ClutterActor - * - * Set the background texture of @key to @texture. - */ -void -eek_clutter_key_set_texture (EekClutterKey *key, - ClutterActor *texture) -{ - clutter_actor_set_position (texture, 0, 0); - clutter_container_add_actor (CLUTTER_CONTAINER(key), texture); + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key); + if (!priv->actor) + priv->actor = eek_clutter_key_actor_new (EEK_KEY(key)); + return priv->actor; } diff --git a/eek/eek-clutter-key.h b/eek/eek-clutter-key.h index 7c775fe0..bf795ccc 100644 --- a/eek/eek-clutter-key.h +++ b/eek/eek-clutter-key.h @@ -38,7 +38,7 @@ typedef struct _EekClutterKeyPrivate EekClutterKeyPrivate; struct _EekClutterKey { /*< private >*/ - ClutterGroup parent; + EekKey parent; /*< private >*/ EekClutterKeyPrivate *priv; @@ -47,14 +47,11 @@ struct _EekClutterKey struct _EekClutterKeyClass { /*< private >*/ - ClutterGroupClass parent_class; + EekKeyClass parent_class; }; -GType eek_clutter_key_get_type (void) G_GNUC_CONST; - -ClutterActor *eek_clutter_key_create_texture (EekClutterKey *key); -void eek_clutter_key_set_texture (EekClutterKey *key, - ClutterActor *texture); +GType eek_clutter_key_get_type (void) G_GNUC_CONST; +ClutterActor *eek_clutter_key_get_actor (EekClutterKey *key); G_END_DECLS #endif /* EEK_CLUTTER_KEY_H */ diff --git a/eek/eek-clutter-keyboard.c b/eek/eek-clutter-keyboard.c index 7df85163..9b2c435c 100644 --- a/eek/eek-clutter-keyboard.c +++ b/eek/eek-clutter-keyboard.c @@ -20,31 +20,18 @@ /** * SECTION:eek-clutter-keyboard - * @short_description: #EekKeyboard implemented as a #ClutterActor - * - * The #EekClutterKeyboard class implements the #EekKeyboardIface - * interface as a #ClutterActor. + * @short_description: #EekKeyboard embedding a #ClutterActor */ +#include + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #include "eek-clutter-keyboard.h" -#include "eek-clutter-private.h" -#include "eek-simple-keyboard.h" +#include "eek-keyboard.h" -enum { - PROP_0, - PROP_BOUNDS, - PROP_LAST -}; - -static void eek_keyboard_iface_init (EekKeyboardIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekClutterKeyboard, eek_clutter_keyboard, - CLUTTER_TYPE_GROUP, - G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD, - eek_keyboard_iface_init)); +G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, EEK_TYPE_KEYBOARD); #define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate)) @@ -52,254 +39,104 @@ G_DEFINE_TYPE_WITH_CODE (EekClutterKeyboard, eek_clutter_keyboard, struct _EekClutterKeyboardPrivate { - EekSimpleKeyboard *simple; - gint group; - gint level; + ClutterActor *actor; }; static void -eek_clutter_keyboard_real_set_bounds (EekKeyboard *self, - EekBounds *bounds) +eek_clutter_keyboard_real_set_name (EekElement *self, + const gchar *name) { EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); - g_return_if_fail (priv); - eek_keyboard_set_bounds (EEK_KEYBOARD(priv->simple), bounds); - clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y); - clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->width, bounds->height); + EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)-> + set_name (self, name); + + g_return_if_fail (priv->actor); + + clutter_actor_set_name (priv->actor, name); } static void -eek_clutter_keyboard_real_get_bounds (EekKeyboard *self, - EekBounds *bounds) +eek_clutter_keyboard_real_set_bounds (EekElement *self, + EekBounds *bounds) { EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); - g_return_if_fail (priv); - return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds); + EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)-> + set_bounds (self, bounds); + + g_return_if_fail (priv->actor); + + clutter_actor_set_position (priv->actor, bounds->x, bounds->y); + clutter_actor_set_size (priv->actor, bounds->width, bounds->height); } static void -eek_clutter_keyboard_real_set_keysym_index (EekKeyboard *self, - gint group, - gint level) +key_pressed_event (EekSection *section, + EekKey *key, + EekKeyboard *keyboard) { - EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); - gint num_sections, num_keys, i, j; - - g_return_if_fail (priv); - priv->group = group; - priv->level = level; - num_sections = clutter_group_get_n_children (CLUTTER_GROUP(self)); - for (i = 0; i < num_sections; i++) { - ClutterActor *section; - - section = clutter_group_get_nth_child (CLUTTER_GROUP(self), i); - g_return_if_fail (EEK_IS_CLUTTER_SECTION(section)); - num_keys = clutter_group_get_n_children (CLUTTER_GROUP(section)); - for (j = 0; j < num_keys; j++) { - ClutterActor *key; - - key = clutter_group_get_nth_child (CLUTTER_GROUP(section), j); - g_return_if_fail (EEK_IS_CLUTTER_KEY(key)); - eek_key_set_keysym_index (EEK_KEY(key), group, level); - } - } + g_signal_emit_by_name (keyboard, "key-pressed", key); } static void -eek_clutter_keyboard_real_get_keysym_index (EekKeyboard *self, - gint *group, - gint *level) +key_released_event (EekSection *section, + EekKey *key, + EekKeyboard *keyboard) { - EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - *group = priv->group; - *level = priv->level; + g_signal_emit_by_name (keyboard, "key-released", key); } static EekSection * -eek_clutter_keyboard_real_create_section (EekKeyboard *self, - const gchar *name, - gint angle, - EekBounds *bounds) +eek_clutter_keyboard_real_create_section (EekKeyboard *self) { EekSection *section; + ClutterActor *actor; - g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(self)); + section = g_object_new (EEK_TYPE_CLUTTER_SECTION, NULL); + g_return_val_if_fail (section, NULL); + g_object_ref_sink (section); - section = g_object_new (EEK_TYPE_CLUTTER_SECTION, - "name", name, - "angle", angle, - "bounds", bounds, - NULL); + g_signal_connect (section, "key-pressed", G_CALLBACK(key_pressed_event), self); + g_signal_connect (section, "key-released", G_CALLBACK(key_released_event), self); - clutter_container_add_actor (CLUTTER_CONTAINER(self), - CLUTTER_ACTOR(section)); + EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), + EEK_ELEMENT(section)); + + actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(self)); + clutter_container_add_actor + (CLUTTER_CONTAINER(actor), + eek_clutter_section_get_actor (EEK_CLUTTER_SECTION(section))); return section; } -static void -eek_clutter_keyboard_real_foreach_section (EekKeyboard *self, - GFunc func, - gpointer user_data) -{ - EekClutterCallbackData data; - - g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(self)); - - data.func = func; - data.user_data = user_data; - - clutter_container_foreach (CLUTTER_CONTAINER(self), - eek_clutter_callback, - &data); -} - -static void -eek_clutter_keyboard_real_set_layout (EekKeyboard *self, - EekLayout *layout) -{ - g_return_if_fail (EEK_IS_KEYBOARD(self)); - g_return_if_fail (EEK_IS_LAYOUT(layout)); - - EEK_LAYOUT_GET_CLASS(layout)->apply_to_keyboard (layout, self); - if (g_object_is_floating (layout)) - g_object_unref (layout); -} - -static void -eek_keyboard_iface_init (EekKeyboardIface *iface) -{ - iface->set_bounds = eek_clutter_keyboard_real_set_bounds; - iface->get_bounds = eek_clutter_keyboard_real_get_bounds; - iface->set_keysym_index = eek_clutter_keyboard_real_set_keysym_index; - iface->get_keysym_index = eek_clutter_keyboard_real_get_keysym_index; - iface->create_section = eek_clutter_keyboard_real_create_section; - iface->foreach_section = eek_clutter_keyboard_real_foreach_section; - iface->set_layout = eek_clutter_keyboard_real_set_layout; -} - -static void -eek_clutter_keyboard_dispose (GObject *object) -{ - clutter_group_remove_all (CLUTTER_GROUP(object)); - G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object); -} - static void eek_clutter_keyboard_finalize (GObject *object) { EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); - g_object_unref (priv->simple); + if (priv->actor) { + clutter_group_remove_all (CLUTTER_GROUP(priv->actor)); + g_object_unref (priv->actor); + } G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->finalize (object); } -static void -eek_clutter_keyboard_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_BOUNDS: - eek_keyboard_set_bounds (EEK_KEYBOARD(object), - g_value_get_boxed (value)); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_clutter_keyboard_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_BOUNDS: - eek_keyboard_set_bounds (EEK_KEYBOARD(object), - g_value_get_boxed (value)); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_clutter_keyboard_paint (ClutterActor *self) -{ - CLUTTER_ACTOR_CLASS (eek_clutter_keyboard_parent_class)->paint (self); -} - static void eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + EekElementClass *element_class = EEK_ELEMENT_CLASS (klass); + EekKeyboardClass *keyboard_class = EEK_KEYBOARD_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (EekClutterKeyboardPrivate)); - gobject_class->set_property = eek_clutter_keyboard_set_property; - gobject_class->get_property = eek_clutter_keyboard_get_property; - gobject_class->finalize = eek_clutter_keyboard_finalize; - gobject_class->dispose = eek_clutter_keyboard_dispose; - - actor_class->paint = eek_clutter_keyboard_paint; - - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); -} - -static gboolean -on_event (ClutterActor *actor, - ClutterEvent *event, - gpointer user_data) -{ - EekKeyboard *keyboard; - EekKey *key; - ClutterActor *source; - - g_return_val_if_fail (EEK_IS_KEYBOARD(user_data), FALSE); - keyboard = EEK_KEYBOARD(user_data); - - source = clutter_event_get_source (event); - if (!EEK_IS_KEY(source)) - return FALSE; - key = EEK_KEY(source); - if (event->type == CLUTTER_BUTTON_PRESS) { - guint keysym; - gint group, level; - - keysym = eek_key_get_keysym (EEK_KEY(source)); - if (keysym == 0xFFE1 || keysym == 0xFFE2) { - eek_keyboard_get_keysym_index (keyboard, &group, &level); - if (level == 0) - eek_keyboard_set_keysym_index (keyboard, group, 1); - else - eek_keyboard_set_keysym_index (keyboard, group, 0); - } - } - return FALSE; + keyboard_class->create_section = eek_clutter_keyboard_real_create_section; + element_class->set_name = eek_clutter_keyboard_real_set_name; + element_class->set_bounds = eek_clutter_keyboard_real_set_bounds; + gobject_class->finalize = eek_clutter_keyboard_finalize; } static void @@ -308,11 +145,7 @@ eek_clutter_keyboard_init (EekClutterKeyboard *self) EekClutterKeyboardPrivate *priv; priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); - priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL); - priv->group = priv->level = 0; - - clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE); - g_signal_connect (self, "event", G_CALLBACK(on_event), self); + priv->actor = NULL; } /** @@ -326,10 +159,28 @@ EekKeyboard* eek_clutter_keyboard_new (gfloat width, gfloat height) { + EekKeyboard *keyboard; EekBounds bounds; - bounds.x = bounds.y = 0; + keyboard = g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, NULL); + g_return_val_if_fail (keyboard, NULL); + + /* Can't call set_bounds of this class since it needs priv->actor + initialized */ + memset (&bounds, 0, sizeof bounds); bounds.width = width; bounds.height = height; - return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, "bounds", &bounds, NULL); + EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)-> + set_bounds (EEK_ELEMENT(keyboard), &bounds); + return keyboard; +} + +ClutterActor * +eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard) +{ + EekClutterKeyboardPrivate *priv = + EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard); + if (!priv->actor) + priv->actor = clutter_group_new (); + return priv->actor; } diff --git a/eek/eek-clutter-keyboard.h b/eek/eek-clutter-keyboard.h index 534c00b3..9c03b7a7 100644 --- a/eek/eek-clutter-keyboard.h +++ b/eek/eek-clutter-keyboard.h @@ -25,20 +25,20 @@ G_BEGIN_DECLS #define EEK_TYPE_CLUTTER_KEYBOARD (eek_clutter_keyboard_get_type()) -#define EEK_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekKeyboard)) +#define EEK_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboard)) #define EEK_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass)) #define EEK_IS_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEYBOARD)) #define EEK_IS_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEYBOARD)) #define EEK_CLUTTER_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass)) -typedef struct _EekClutterKeyboard EekClutterKeyboard; -typedef struct _EekClutterKeyboardClass EekClutterKeyboardClass; +typedef struct _EekClutterKeyboard EekClutterKeyboard; +typedef struct _EekClutterKeyboardClass EekClutterKeyboardClass; typedef struct _EekClutterKeyboardPrivate EekClutterKeyboardPrivate; struct _EekClutterKeyboard { /*< private >*/ - ClutterGroup parent; + EekKeyboard parent; EekClutterKeyboardPrivate *priv; }; @@ -46,13 +46,13 @@ struct _EekClutterKeyboard struct _EekClutterKeyboardClass { /*< private >*/ - ClutterGroupClass parent_class; + EekKeyboardClass parent_class; }; -GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST; - -EekKeyboard *eek_clutter_keyboard_new (gfloat width, - gfloat height); +GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST; +EekKeyboard *eek_clutter_keyboard_new (gfloat width, + gfloat height); +ClutterActor *eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard); G_END_DECLS #endif /* EEK_CLUTTER_KEYBOARD_H */ diff --git a/eek/eek-clutter-private.c b/eek/eek-clutter-private.c deleted file mode 100644 index 44cc262d..00000000 --- a/eek/eek-clutter-private.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "eek-clutter-private.h" - -void -eek_clutter_callback (ClutterActor *actor, gpointer user_data) -{ - EekClutterCallbackData *data = user_data; - data->func (actor, data->user_data); -} diff --git a/eek/eek-clutter-private.h b/eek/eek-clutter-private.h deleted file mode 100644 index 89ab30d9..00000000 --- a/eek/eek-clutter-private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_CLUTTER_PRIVATE_H -#define EEK_CLUTTER_PRIVATE_H 1 - -#include -#include - -struct _EekClutterCallbackData { - GFunc func; - gpointer user_data; -}; -typedef struct _EekClutterCallbackData EekClutterCallbackData; - -void eek_clutter_callback (ClutterActor *actor, gpointer user_data); - -#endif /* EEK_CLUTTER_PRIVATE_H */ diff --git a/eek/eek-clutter-section.c b/eek/eek-clutter-section.c index a8d9bc9e..562b633c 100644 --- a/eek/eek-clutter-section.c +++ b/eek/eek-clutter-section.c @@ -20,350 +20,159 @@ /** * SECTION:eek-clutter-section - * @short_description: #EekSection implemented as a #ClutterActor - * - * The #EekClutterSection class implements the #EekSectionIface - * interface as a #ClutterActor. + * @short_description: #EekSection embedding a #ClutterActor */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ + #include "eek-clutter-section.h" -#include "eek-clutter-private.h" -#include "eek-simple-section.h" -#include -enum { - PROP_0, - PROP_COLUMNS, - PROP_ROWS, - PROP_ANGLE, - PROP_BOUNDS, - PROP_LAST -}; - -static void eek_section_iface_init (EekSectionIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekClutterSection, eek_clutter_section, - CLUTTER_TYPE_GROUP, - G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION, - eek_section_iface_init)); +G_DEFINE_TYPE (EekClutterSection, eek_clutter_section, EEK_TYPE_SECTION); #define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate)) struct _EekClutterSectionPrivate { - EekSimpleSection *simple; - GHashTable *key_outline_texture_hash; /* outline pointer -> texture */ + ClutterActor *actor; }; static void -eek_clutter_section_real_set_rows (EekSection *self, - gint rows) +eek_clutter_section_real_set_name (EekElement *self, + const gchar *name) { EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - g_return_if_fail (priv); - eek_section_set_rows (EEK_SECTION(priv->simple), rows); -} + EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)-> + set_name (self, name); -static gint -eek_clutter_section_real_get_rows (EekSection *self) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + g_return_if_fail (priv->actor); - g_return_val_if_fail (priv, -1); - return eek_section_get_rows (EEK_SECTION(priv->simple)); + clutter_actor_set_name (priv->actor, name); } static void -eek_clutter_section_real_set_columns (EekSection *self, - gint row, - gint columns) +eek_clutter_section_real_set_bounds (EekElement *self, + EekBounds *bounds) { EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - g_return_if_fail (priv); - eek_section_set_columns (EEK_SECTION(priv->simple), row, columns); -} + EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)-> + set_bounds (self, bounds); -static gint -eek_clutter_section_real_get_columns (EekSection *self, - gint row) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + g_return_if_fail (priv->actor); - g_return_val_if_fail (priv, -1); - return eek_section_get_columns (EEK_SECTION(priv->simple), row); -} - -static void -eek_clutter_section_real_set_orientation (EekSection *self, - gint row, - EekOrientation orientation) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_orientation (EEK_SECTION(priv->simple), row, orientation); -} - -static EekOrientation -eek_clutter_section_real_get_orientation (EekSection *self, - gint row) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_ORIENTATION_INVALID); - return eek_section_get_orientation (EEK_SECTION(priv->simple), row); + clutter_actor_set_position (priv->actor, bounds->x, bounds->y); + clutter_actor_set_size (priv->actor, bounds->width, bounds->height); } static void eek_clutter_section_real_set_angle (EekSection *self, - gint angle) + gint angle) { EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - g_return_if_fail (priv); - eek_section_set_angle (EEK_SECTION(priv->simple), angle); - clutter_actor_set_rotation (CLUTTER_ACTOR(self), + EEK_SECTION_CLASS (eek_clutter_section_parent_class)-> + set_angle (self, angle); + + g_return_if_fail (priv->actor); + + clutter_actor_set_rotation (priv->actor, CLUTTER_Z_AXIS, - angle, - 0, - 0, - 0); -} - -static gint -eek_clutter_section_real_get_angle (EekSection *self) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, 0); - eek_section_get_angle (EEK_SECTION(priv->simple)); + eek_section_get_angle (self), + 0, 0, 0); } static void -eek_clutter_section_real_set_bounds (EekSection *self, - EekBounds *bounds) +pressed_event (EekKey *key, gpointer user_data) { - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_bounds (EEK_SECTION(priv->simple), bounds); - clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y); - clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->width, bounds->height); + g_signal_emit_by_name (user_data, "key-pressed", key); } static void -eek_clutter_section_real_get_bounds (EekSection *self, - EekBounds *bounds) +released_event (EekKey *key, gpointer user_data) { - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - return eek_section_get_bounds (EEK_SECTION(priv->simple), bounds); + g_signal_emit_by_name (user_data, "key-released", key); } static EekKey * eek_clutter_section_real_create_key (EekSection *self, - const gchar *name, - guint keycode, - guint *keysyms, - gint num_groups, - gint num_levels, gint column, - gint row, - EekOutline *outline, - EekBounds *bounds) + gint row) { - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); EekKey *key; - EekKeysymMatrix matrix; - gint columns, rows; - ClutterActor *texture; + gint num_columns, num_rows; + EekOrientation orientation; + ClutterActor *actor; - g_return_val_if_fail (priv, NULL); + num_rows = eek_section_get_n_rows (self); + g_return_val_if_fail (0 <= row && row < num_rows, NULL); + eek_section_get_row (self, row, &num_columns, &orientation); + g_return_val_if_fail (column < num_columns, NULL); - rows = eek_section_get_rows (self); - g_return_val_if_fail (0 <= row && row < rows, NULL); - columns = eek_section_get_columns (self, row); - g_return_val_if_fail (column < columns, NULL); - - matrix.data = keysyms; - matrix.num_groups = num_groups; - matrix.num_levels = num_levels; key = g_object_new (EEK_TYPE_CLUTTER_KEY, - "name", name, - "keycode", keycode, - "keysyms", &matrix, "column", column, "row", row, - "outline", outline, - "bounds", bounds, NULL); g_return_val_if_fail (key, NULL); + g_object_ref_sink (key); + + g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self); + g_signal_connect (key, "released", G_CALLBACK(released_event), self); - texture = g_hash_table_lookup (priv->key_outline_texture_hash, outline); - if (texture == NULL) { - texture = eek_clutter_key_create_texture (EEK_CLUTTER_KEY(key)); - g_hash_table_insert (priv->key_outline_texture_hash, outline, texture); - } else - texture = clutter_clone_new (texture); + EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), + EEK_ELEMENT(key)); + + actor = eek_clutter_section_get_actor (EEK_CLUTTER_SECTION(self)); + clutter_container_add_actor + (CLUTTER_CONTAINER(actor), + eek_clutter_key_get_actor (EEK_CLUTTER_KEY(key))); - eek_clutter_key_set_texture (EEK_CLUTTER_KEY(key), texture); - clutter_container_add_actor (CLUTTER_CONTAINER(self), - CLUTTER_ACTOR(key)); return key; } -static void -eek_clutter_section_real_foreach_key (EekSection *self, - GFunc func, - gpointer user_data) -{ - EekClutterCallbackData data; - - g_return_if_fail (EEK_IS_CLUTTER_SECTION(self)); - - data.func = func; - data.user_data = user_data; - - clutter_container_foreach (CLUTTER_CONTAINER(self), - eek_clutter_callback, - &data); -} - -static void -eek_section_iface_init (EekSectionIface *iface) -{ - iface->set_rows = eek_clutter_section_real_set_rows; - iface->get_rows = eek_clutter_section_real_get_rows; - iface->set_columns = eek_clutter_section_real_set_columns; - iface->get_columns = eek_clutter_section_real_get_columns; - iface->set_orientation = eek_clutter_section_real_set_orientation; - iface->get_orientation = eek_clutter_section_real_get_orientation; - iface->set_angle = eek_clutter_section_real_set_angle; - iface->get_angle = eek_clutter_section_real_get_angle; - iface->set_bounds = eek_clutter_section_real_set_bounds; - iface->get_bounds = eek_clutter_section_real_get_bounds; - iface->create_key = eek_clutter_section_real_create_key; - iface->foreach_key = eek_clutter_section_real_foreach_key; -} - -static void -eek_clutter_section_dispose (GObject *object) -{ - clutter_group_remove_all (CLUTTER_GROUP(object)); - G_OBJECT_CLASS (eek_clutter_section_parent_class)->dispose (object); -} - static void eek_clutter_section_finalize (GObject *object) { EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); - g_object_unref (priv->simple); + if (priv->actor) { + clutter_group_remove_all (CLUTTER_GROUP(priv->actor)); + g_object_unref (priv->actor); + } G_OBJECT_CLASS (eek_clutter_section_parent_class)->finalize (object); } -static void -eek_clutter_section_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); - - switch (prop_id) { - case PROP_ANGLE: - eek_section_set_angle (EEK_SECTION(object), - g_value_get_int (value)); - break; - case PROP_BOUNDS: - eek_section_set_bounds (EEK_SECTION(object), - g_value_get_boxed (value)); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_clutter_section_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); - EekBounds bounds; - - switch (prop_id) { - case PROP_ANGLE: - g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); - break; - case PROP_BOUNDS: - eek_section_get_bounds (EEK_SECTION(object), &bounds); - g_value_set_boxed (value, &bounds); - break; - default: - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_clutter_section_paint (ClutterActor *self) -{ - ClutterGeometry geom; - - CLUTTER_ACTOR_CLASS (eek_clutter_section_parent_class)->paint (self); - - //clutter_actor_get_allocation_geometry (self, &geom); - //cogl_set_source_color4ub (0x80, 0x00, 0x00, 0xff); - //cogl_rectangle (0, 0, geom.width, geom.height); -} - static void eek_clutter_section_class_init (EekClutterSectionClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + EekElementClass *element_class = EEK_ELEMENT_CLASS (klass); + EekSectionClass *section_class = EEK_SECTION_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate)); - gobject_class->set_property = eek_clutter_section_set_property; - gobject_class->get_property = eek_clutter_section_get_property; - gobject_class->finalize = eek_clutter_section_finalize; - gobject_class->dispose = eek_clutter_section_dispose; - - actor_class->paint = eek_clutter_section_paint; - - g_object_class_override_property (gobject_class, - PROP_ANGLE, - "angle"); - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); + section_class->set_angle = eek_clutter_section_real_set_angle; + section_class->create_key = eek_clutter_section_real_create_key; + element_class->set_name = eek_clutter_section_real_set_name; + element_class->set_bounds = eek_clutter_section_real_set_bounds; + gobject_class->finalize = eek_clutter_section_finalize; } static void eek_clutter_section_init (EekClutterSection *self) { EekClutterSectionPrivate *priv; - priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self); - priv->simple = g_object_new (EEK_TYPE_SIMPLE_SECTION, NULL); - priv->key_outline_texture_hash = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - g_free); + priv->actor = NULL; +} + +ClutterActor * +eek_clutter_section_get_actor (EekClutterSection *section) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(section); + if (!priv->actor) + priv->actor = clutter_group_new (); + return priv->actor; } diff --git a/eek/eek-clutter-section.h b/eek/eek-clutter-section.h index 09baabbb..790c24c4 100644 --- a/eek/eek-clutter-section.h +++ b/eek/eek-clutter-section.h @@ -38,19 +38,19 @@ typedef struct _EekClutterSectionPrivate EekClutterSectionPrivate; struct _EekClutterSection { /*< private >*/ - ClutterGroup parent; + EekSection parent; - /*< private >*/ EekClutterSectionPrivate *priv; }; struct _EekClutterSectionClass { /*< private >*/ - ClutterGroupClass parent_class; + EekSectionClass parent_class; }; -GType eek_clutter_section_get_type (void) G_GNUC_CONST; +GType eek_clutter_section_get_type (void) G_GNUC_CONST; +ClutterActor *eek_clutter_section_get_actor (EekClutterSection *section); G_END_DECLS #endif /* EEK_CLUTTER_SECTION_H */ diff --git a/eek/eek-container.c b/eek/eek-container.c new file mode 100644 index 00000000..e2784bcf --- /dev/null +++ b/eek/eek-container.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-container + * @short_description: Base class of a keyboard container + * + * The #EekContainerClass class represents a keyboard container, which + * shall be used to implement #EekKeyboard and #EekSection. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-container.h" + +enum { + CHILD_ADDED, + CHILD_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_ABSTRACT_TYPE (EekContainer, eek_container, EEK_TYPE_ELEMENT); + +#define EEK_CONTAINER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate)) + + +struct _EekContainerPrivate +{ + GSList *children; +}; + +static void +eek_container_real_add_child (EekContainer *self, + EekElement *child) +{ + EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self); + + g_return_if_fail (EEK_IS_ELEMENT(child)); + g_object_ref (child); + priv->children = g_slist_prepend (priv->children, child); +} + +static void +eek_container_real_remove_child (EekContainer *self, + EekElement *child) +{ + EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self); + GSList *head; + + g_return_if_fail (EEK_IS_ELEMENT(child)); + head = g_slist_find (priv->children, child); + g_return_if_fail (head); + g_object_unref (child); + priv->children = g_slist_remove_link (priv->children, head); +} + +static void +eek_container_real_foreach_child (EekContainer *self, + EekCallback callback, + gpointer user_data) +{ + EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self); + GSList *head; + + for (head = priv->children; head; head = g_slist_next (head)) + (*callback) (EEK_ELEMENT(head->data), user_data); +} + +static void +eek_container_finalize (GObject *object) +{ + EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object); + GSList *head; + + for (head = priv->children; head; head = g_slist_next (head)) + g_object_unref (head->data); + g_slist_free (priv->children); + G_OBJECT_CLASS(eek_container_parent_class)->finalize (object); +} + +static void +eek_container_class_init (EekContainerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (gobject_class, + sizeof (EekContainerPrivate)); + + klass->add_child = eek_container_real_add_child; + klass->remove_child = eek_container_real_remove_child; + klass->foreach_child = eek_container_real_foreach_child; + + gobject_class->finalize = eek_container_finalize; + + signals[CHILD_ADDED] = + g_signal_new ("child-added", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(EekContainerClass, child_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + EEK_TYPE_ELEMENT); + + signals[CHILD_REMOVED] = + g_signal_new ("child-removed", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(EekContainerClass, child_removed), + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + EEK_TYPE_ELEMENT); +} + +static void +eek_container_init (EekContainer *self) +{ + EekContainerPrivate *priv; + + priv = self->priv = EEK_CONTAINER_GET_PRIVATE(self); + priv->children = NULL; +} + +void +eek_container_foreach_child (EekContainer *container, + EekCallback callback, + gpointer user_data) +{ + g_return_if_fail (EEK_IS_CONTAINER(container)); + EEK_CONTAINER_GET_CLASS(container)->foreach_child (container, + callback, + user_data); +} diff --git a/eek/eek-container.h b/eek/eek-container.h new file mode 100644 index 00000000..8a099af8 --- /dev/null +++ b/eek/eek-container.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CONTAINER_H +#define EEK_CONTAINER_H 1 + +#include "eek-element.h" + +G_BEGIN_DECLS + +#define EEK_TYPE_CONTAINER (eek_container_get_type()) +#define EEK_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CONTAINER, EekContainer)) +#define EEK_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CONTAINER, EekContainerClass)) +#define EEK_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CONTAINER)) +#define EEK_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CONTAINER)) +#define EEK_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CONTAINER, EekContainerClass)) + +typedef struct _EekContainer EekContainer; +typedef struct _EekContainerClass EekContainerClass; +typedef struct _EekContainerPrivate EekContainerPrivate; + +typedef void (*EekCallback) (EekElement *element, gpointer user_data); + +struct _EekContainer +{ + /*< private >*/ + EekElement parent; + + /*< public >*/ + EekContainerPrivate *priv; +}; + +struct _EekContainerClass +{ + /*< private >*/ + EekElementClass parent_class; + + void (* add_child) (EekContainer *self, + EekElement *element); + + void (* remove_child) (EekContainer *self, + EekElement *element); + + /*< public >*/ + void (* foreach_child) (EekContainer *self, + EekCallback callback, + gpointer user_data); + + /* signals */ + void (* child_added) (EekContainer *self, + EekElement *element); + void (* child_removed) (EekContainer *self, + EekElement *element); +}; + +GType eek_container_get_type (void) G_GNUC_CONST; + +void eek_container_foreach_child (EekContainer *self, + EekCallback callback, + gpointer user_data); + +G_END_DECLS +#endif /* EEK_CONTAINER_H */ diff --git a/eek/eek-element.c b/eek/eek-element.c new file mode 100644 index 00000000..68c68485 --- /dev/null +++ b/eek/eek-element.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-element + * @short_description: Base class of a keyboard element + * + * The #EekElementClass class represents a keyboard element, which + * shall be used to implement #EekKeyboard, #EekSection, or #EekKey. + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-element.h" + +enum { + PROP_0, + PROP_NAME, + PROP_BOUNDS, + PROP_LAST +}; + +G_DEFINE_ABSTRACT_TYPE (EekElement, eek_element, G_TYPE_INITIALLY_UNOWNED); + +#define EEK_ELEMENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate)) + + +struct _EekElementPrivate +{ + gchar *name; + EekBounds bounds; +}; + +static void +eek_element_real_set_name (EekElement *self, + const gchar *name) +{ + EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); + + priv->name = g_strdup (name); + + g_object_notify (G_OBJECT(self), "name"); +} + +static G_CONST_RETURN gchar * +eek_element_real_get_name (EekElement *self) +{ + EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); + + return priv->name; +} + +static void +eek_element_real_set_bounds (EekElement *self, + EekBounds *bounds) +{ + EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); + + priv->bounds = *bounds; +} + +static void +eek_element_real_get_bounds (EekElement *self, + EekBounds *bounds) +{ + EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); + + g_return_if_fail (bounds); + *bounds = priv->bounds; + + g_object_notify (G_OBJECT(self), "bounds"); +} + +static void +eek_element_finalize (GObject *object) +{ + EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object); + + g_free (priv->name); +} + +static void +eek_element_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + g_return_if_fail (EEK_IS_ELEMENT(object)); + switch (prop_id) { + case PROP_NAME: + eek_element_set_name (EEK_ELEMENT(object), + g_value_get_string (value)); + break; + case PROP_BOUNDS: + eek_element_set_bounds (EEK_ELEMENT(object), + g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eek_element_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekBounds bounds; + + g_return_if_fail (EEK_IS_ELEMENT(object)); + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, eek_element_get_name (EEK_ELEMENT(object))); + break; + case PROP_BOUNDS: + eek_element_get_bounds (EEK_ELEMENT(object), &bounds); + g_value_set_boxed (value, &bounds); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eek_element_class_init (EekElementClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, + sizeof (EekElementPrivate)); + + klass->set_name = eek_element_real_set_name; + klass->get_name = eek_element_real_get_name; + klass->set_bounds = eek_element_real_set_bounds; + klass->get_bounds = eek_element_real_get_bounds; + + gobject_class->set_property = eek_element_set_property; + gobject_class->get_property = eek_element_get_property; + gobject_class->finalize = eek_element_finalize; + + /** + * EekElement:name: + * + * The name of #EekElement. + */ + pspec = g_param_spec_string ("name", + "Name", + "Name", + NULL, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_NAME, + pspec); + + /** + * EekElement:bounds: + * + * The bounding box of #EekElement. + */ + pspec = g_param_spec_boxed ("bounds", + "Bounds", + "Bounding box of the element", + EEK_TYPE_BOUNDS, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_BOUNDS, + pspec); +} + +static void +eek_element_init (EekElement *self) +{ + EekElementPrivate *priv; + + priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self); + priv->name = NULL; + memset (&priv->bounds, 0, sizeof priv->bounds); +} + +void +eek_element_set_name (EekElement *element, + const gchar *name) +{ + g_return_if_fail (EEK_IS_ELEMENT(element)); + EEK_ELEMENT_GET_CLASS(element)->set_name (element, name); +} + +G_CONST_RETURN gchar * +eek_element_get_name (EekElement *element) +{ + g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL); + return EEK_ELEMENT_GET_CLASS(element)->get_name (element); +} + +void +eek_element_set_bounds (EekElement *element, + EekBounds *bounds) +{ + g_return_if_fail (EEK_IS_ELEMENT(element)); + EEK_ELEMENT_GET_CLASS(element)->set_bounds (element, bounds); +} + +void +eek_element_get_bounds (EekElement *element, + EekBounds *bounds) +{ + g_return_if_fail (EEK_IS_ELEMENT(element)); + EEK_ELEMENT_GET_CLASS(element)->get_bounds (element, bounds); +} diff --git a/eek/eek-element.h b/eek/eek-element.h new file mode 100644 index 00000000..e54494cf --- /dev/null +++ b/eek/eek-element.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_ELEMENT_H +#define EEK_ELEMENT_H 1 + +#include +#include "eek-types.h" + +G_BEGIN_DECLS +#define EEK_TYPE_ELEMENT (eek_element_get_type()) +#define EEK_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_ELEMENT, EekElement)) +#define EEK_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_ELEMENT, EekElementClass)) +#define EEK_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_ELEMENT)) +#define EEK_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_ELEMENT)) +#define EEK_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_ELEMENT, EekElementClass)) + +typedef struct _EekElement EekElement; +typedef struct _EekElementClass EekElementClass; +typedef struct _EekElementPrivate EekElementPrivate; + +struct _EekElement +{ + /*< private >*/ + GInitiallyUnowned parent; + + EekElementPrivate *priv; +}; + +struct _EekElementClass +{ + /*< private >*/ + GInitiallyUnownedClass parent_class; + + void (* set_name) (EekElement *element, + const gchar *name); + + G_CONST_RETURN gchar *(* get_name) (EekElement *element); + + void (* set_bounds) (EekElement *element, + EekBounds *bounds); + + void (* get_bounds) (EekElement *element, + EekBounds *bounds); +}; + +GType eek_element_get_type (void) G_GNUC_CONST; + +void eek_element_set_name (EekElement *element, + const gchar *name); + +G_CONST_RETURN gchar *eek_element_get_name (EekElement *element); + +void eek_element_set_bounds (EekElement *element, + EekBounds *bounds); + +void eek_element_get_bounds (EekElement *element, + EekBounds *bounds); + +G_END_DECLS +#endif /* EEK_ELEMENT_H */ diff --git a/eek/eek-gtk-key.c b/eek/eek-gtk-key.c deleted file mode 100644 index 4fc7f4a7..00000000 --- a/eek/eek-gtk-key.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -/** - * SECTION:eek-gtk-key - * @short_description: #EekKey implemented as a #GtkWidget - * - * The #EekClutterKey class implements the #EekKeyIface interface as a - * #GtkWidget. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ -#include "eek-gtk-key.h" -#include "eek-simple-key.h" -#include "eek-keysym.h" - -enum { - PROP_0, - PROP_KEYCODE, - PROP_KEYSYMS, - PROP_COLUMN, - PROP_ROW, - PROP_OUTLINE, - PROP_BOUNDS, - PROP_GROUP, - PROP_LEVEL, - PROP_LAST -}; - -static void eek_key_iface_init (EekKeyIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekGtkKey, eek_gtk_key, - GTK_TYPE_BUTTON, - G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY, - eek_key_iface_init)); - -#define EEK_GTK_KEY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEY, EekGtkKeyPrivate)) - -struct _EekGtkKeyPrivate -{ - EekSimpleKey *simple; -}; - -static guint -eek_gtk_key_real_get_keycode (EekKey *self) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_INVALID_KEYCODE); - return eek_key_get_keycode (EEK_KEY(priv->simple)); -} - -static void -eek_gtk_key_real_set_keysyms (EekKey *self, - guint *keysyms, - gint groups, - gint levels) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels); - if (groups > 0 && levels > 0) - eek_key_set_keysym_index (EEK_KEY(self), 0, 0); -} - -static void -eek_gtk_key_real_get_keysyms (EekKey *self, - guint **keysyms, - gint *groups, - gint *levels) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_get_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels); -} - -static gint -eek_gtk_key_real_get_groups (EekKey *self) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - return eek_key_get_groups (EEK_KEY(priv->simple)); -} - -static guint -eek_gtk_key_real_get_keysym (EekKey *self) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_INVALID_KEYSYM); - return eek_key_get_keysym (EEK_KEY(priv->simple)); -} - -static void -eek_gtk_key_real_set_index (EekKey *self, - gint column, - gint row) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_index (EEK_KEY(priv->simple), column, row); -} - -static void -eek_gtk_key_real_get_index (EekKey *self, - gint *column, - gint *row) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_get_index (EEK_KEY(priv->simple), column, row); -} - -static void -eek_gtk_key_real_set_outline (EekKey *self, EekOutline *outline) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_outline (EEK_KEY(priv->simple), outline); -} - -static EekOutline * -eek_gtk_key_real_get_outline (EekKey *self) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, NULL); - return eek_key_get_outline (EEK_KEY(priv->simple)); -} - -static void -eek_gtk_key_real_set_bounds (EekKey *self, EekBounds *bounds) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_key_set_bounds (EEK_KEY(priv->simple), bounds); -} - -static void -eek_gtk_key_real_get_bounds (EekKey *self, - EekBounds *bounds) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - return eek_key_get_bounds (EEK_KEY(priv->simple), bounds); -} - -static void -eek_gtk_key_real_set_keysym_index (EekKey *self, - gint group, - gint level) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - guint keysym; - - g_return_if_fail (priv); - eek_key_set_keysym_index (EEK_KEY(priv->simple), group, level); - keysym = eek_key_get_keysym (self); - if (keysym != EEK_INVALID_KEYSYM) { - const gchar *label; - - label = eek_keysym_to_string (keysym); - gtk_button_set_label (GTK_BUTTON(self), label ? label : ""); - } -} - -static void -eek_gtk_key_real_get_keysym_index (EekKey *self, gint *group, gint *level) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - return eek_key_get_keysym_index (EEK_KEY(priv->simple), group, level); -} - -static void -eek_key_iface_init (EekKeyIface *iface) -{ - iface->get_keycode = eek_gtk_key_real_get_keycode; - iface->set_keysyms = eek_gtk_key_real_set_keysyms; - iface->get_keysyms = eek_gtk_key_real_get_keysyms; - iface->get_groups = eek_gtk_key_real_get_groups; - iface->get_keysym = eek_gtk_key_real_get_keysym; - iface->set_index = eek_gtk_key_real_set_index; - iface->get_index = eek_gtk_key_real_get_index; - iface->set_outline = eek_gtk_key_real_set_outline; - iface->get_outline = eek_gtk_key_real_get_outline; - iface->set_bounds = eek_gtk_key_real_set_bounds; - iface->get_bounds = eek_gtk_key_real_get_bounds; - iface->set_keysym_index = eek_gtk_key_real_set_keysym_index; - iface->get_keysym_index = eek_gtk_key_real_get_keysym_index; -} - -static void -eek_gtk_key_dispose (GObject *object) -{ - G_OBJECT_CLASS (eek_gtk_key_parent_class)->dispose (object); -} - -static void -eek_gtk_key_finalize (GObject *object) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object); - - g_object_unref (priv->simple); - G_OBJECT_CLASS (eek_gtk_key_parent_class)->finalize (object); -} - -static void -eek_gtk_key_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object); - EekKeysymMatrix *matrix; - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_KEYSYMS: - matrix = g_value_get_boxed (value); - eek_key_set_keysyms (EEK_KEY(object), - matrix->data, - matrix->num_groups, - matrix->num_levels); - break; - case PROP_KEYCODE: - case PROP_BOUNDS: - case PROP_OUTLINE: - case PROP_COLUMN: - case PROP_GROUP: - case PROP_ROW: - case PROP_LEVEL: - g_object_set_property (G_OBJECT(priv->simple), - g_param_spec_get_name (pspec), - value); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_gtk_key_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_KEYCODE: - case PROP_BOUNDS: - case PROP_KEYSYMS: - case PROP_COLUMN: - case PROP_ROW: - case PROP_OUTLINE: - case PROP_GROUP: - case PROP_LEVEL: - g_object_get_property (G_OBJECT(priv->simple), - g_param_spec_get_name (pspec), - value); - break; - default: - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_gtk_key_class_init (EekGtkKeyClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, - sizeof (EekGtkKeyPrivate)); - - gobject_class->set_property = eek_gtk_key_set_property; - gobject_class->get_property = eek_gtk_key_get_property; - gobject_class->finalize = eek_gtk_key_finalize; - gobject_class->dispose = eek_gtk_key_dispose; - - g_object_class_override_property (gobject_class, - PROP_KEYCODE, - "keycode"); - g_object_class_override_property (gobject_class, - PROP_KEYSYMS, - "keysyms"); - g_object_class_override_property (gobject_class, - PROP_COLUMN, - "column"); - g_object_class_override_property (gobject_class, - PROP_ROW, - "row"); - g_object_class_override_property (gobject_class, - PROP_OUTLINE, - "outline"); - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); - g_object_class_override_property (gobject_class, - PROP_GROUP, - "group"); - g_object_class_override_property (gobject_class, - PROP_LEVEL, - "level"); -} - -static void -eek_gtk_key_init (EekGtkKey *self) -{ - EekGtkKeyPrivate *priv; - - priv = self->priv = EEK_GTK_KEY_GET_PRIVATE(self); - priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEY, NULL); -} diff --git a/eek/eek-gtk-key.h b/eek/eek-gtk-key.h deleted file mode 100644 index 71319723..00000000 --- a/eek/eek-gtk-key.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_GTK_KEY_H -#define EEK_GTK_KEY_H 1 - -#include -#include "eek-key.h" - -G_BEGIN_DECLS -#define EEK_TYPE_GTK_KEY (eek_gtk_key_get_type()) -#define EEK_GTK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEY, EekGtkKey)) -#define EEK_GTK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEY, EekGtkKeyClass)) -#define EEK_IS_GTK_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEY)) -#define EEK_IS_GTK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEY)) -#define EEK_GTK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEY, EekGtkKeyClass)) - -typedef struct _EekGtkKey EekGtkKey; -typedef struct _EekGtkKeyClass EekGtkKeyClass; -typedef struct _EekGtkKeyPrivate EekGtkKeyPrivate; - -struct _EekGtkKey -{ - /*< private >*/ - GtkButton parent; - - /*< private >*/ - EekGtkKeyPrivate *priv; -}; - -struct _EekGtkKeyClass -{ - /*< private >*/ - GtkButtonClass parent_class; -}; - -GType eek_gtk_key_get_type (void) G_GNUC_CONST; - -G_END_DECLS -#endif /* EEK_GTK_KEY_H */ diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c deleted file mode 100644 index 735697e6..00000000 --- a/eek/eek-gtk-keyboard.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -/** - * SECTION:eek-gtk-keyboard - * @short_description: #EekKeyboard implemented as a #GtkWidget - * - * The #EekGtkKeyboard class implements the #EekKeyboardIface - * interface as a #GtkWidget. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "eek-gtk-keyboard.h" -#include "eek-gtk-private.h" -#include "eek-simple-keyboard.h" - -enum { - PROP_0, - PROP_BOUNDS, - PROP_LAST -}; - -static void eek_keyboard_iface_init (EekKeyboardIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekGtkKeyboard, eek_gtk_keyboard, - GTK_TYPE_VBOX, - G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD, - eek_keyboard_iface_init)); - -#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate)) - - -struct _EekGtkKeyboardPrivate -{ - EekSimpleKeyboard *simple; - gint group; - gint level; -}; - -static void -eek_gtk_keyboard_real_set_bounds (EekKeyboard *self, - EekBounds *bounds) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_keyboard_set_bounds (EEK_KEYBOARD(priv->simple), bounds); -} - -static void -eek_gtk_keyboard_real_get_bounds (EekKeyboard *self, - EekBounds *bounds) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds); -} - -struct keysym_index { - gint group; - gint level; -}; - -static void -key_set_keysym_index (gpointer self, gpointer user_data) -{ - struct keysym_index *ki; - - g_return_if_fail (EEK_IS_KEY(self)); - eek_key_set_keysym_index (self, ki->group, ki->level); -} - -static void -section_set_keysym_index (gpointer self, gpointer user_data) -{ - EekGtkCallbackData data; - - data.func = key_set_keysym_index; - data.user_data = user_data; - - g_return_if_fail (EEK_IS_GTK_SECTION(self)); - gtk_container_foreach (GTK_CONTAINER(self), eek_gtk_callback, &data); -} - -static void -eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self, - gint group, - gint level) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); - EekGtkCallbackData data; - struct keysym_index ki; - - g_return_if_fail (priv); - priv->group = group; - priv->level = level; - - ki.group = group; - ki.level = level; - - data.func = section_set_keysym_index; - data.user_data = &ki; - - gtk_container_foreach (GTK_CONTAINER(self), eek_gtk_callback, &data); -} - -static void -eek_gtk_keyboard_real_get_keysym_index (EekKeyboard *self, - gint *group, - gint *level) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - *group = priv->group; - *level = priv->level; -} - -static EekSection * -eek_gtk_keyboard_real_create_section (EekKeyboard *self, - const gchar *name, - gint angle, - EekBounds *bounds) -{ - EekSection *section; - - g_return_if_fail (EEK_IS_GTK_KEYBOARD(self)); - - section = g_object_new (EEK_TYPE_GTK_SECTION, - "name", name, - "angle", angle, - "bounds", bounds, - NULL); - - gtk_box_pack_start (GTK_BOX(self), GTK_WIDGET(section), FALSE, FALSE, 0); - return section; -} - -static void -eek_gtk_keyboard_real_foreach_section (EekKeyboard *self, - GFunc func, - gpointer user_data) -{ - EekGtkCallbackData data; - - g_return_if_fail (EEK_IS_GTK_KEYBOARD(self)); - - data.func = func; - data.user_data = user_data; - - gtk_container_foreach (GTK_CONTAINER(self), - eek_gtk_callback, - &data); -} - -static void -eek_gtk_keyboard_real_set_layout (EekKeyboard *self, - EekLayout *layout) -{ - g_return_if_fail (EEK_IS_KEYBOARD(self)); - g_return_if_fail (EEK_IS_LAYOUT(layout)); - - EEK_LAYOUT_GET_CLASS(layout)->apply_to_keyboard (layout, self); - if (g_object_is_floating (layout)) - g_object_unref (layout); -} - -static void -eek_keyboard_iface_init (EekKeyboardIface *iface) -{ - iface->set_bounds = eek_gtk_keyboard_real_set_bounds; - iface->get_bounds = eek_gtk_keyboard_real_get_bounds; - iface->set_keysym_index = eek_gtk_keyboard_real_set_keysym_index; - iface->get_keysym_index = eek_gtk_keyboard_real_get_keysym_index; - iface->create_section = eek_gtk_keyboard_real_create_section; - iface->foreach_section = eek_gtk_keyboard_real_foreach_section; - iface->set_layout = eek_gtk_keyboard_real_set_layout; -} - -static void -eek_gtk_keyboard_dispose (GObject *object) -{ - G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object); -} - -static void -eek_gtk_keyboard_finalize (GObject *object) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); - - g_object_unref (priv->simple); - G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->finalize (object); -} - -static void -eek_gtk_keyboard_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_BOUNDS: - eek_keyboard_set_bounds (EEK_KEYBOARD(object), - g_value_get_boxed (value)); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_gtk_keyboard_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_BOUNDS: - eek_keyboard_set_bounds (EEK_KEYBOARD(object), - g_value_get_boxed (value)); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, - sizeof (EekGtkKeyboardPrivate)); - - gobject_class->set_property = eek_gtk_keyboard_set_property; - gobject_class->get_property = eek_gtk_keyboard_get_property; - gobject_class->finalize = eek_gtk_keyboard_finalize; - gobject_class->dispose = eek_gtk_keyboard_dispose; - - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); -} - -static void -eek_gtk_keyboard_init (EekGtkKeyboard *self) -{ - EekGtkKeyboardPrivate *priv; - - priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); - priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL); - priv->group = priv->level = 0; -} - -/** - * eek_gtk_keyboard_new: - * - * Create a new #EekGtkKeyboard. - */ -EekKeyboard* -eek_gtk_keyboard_new (void) -{ - return g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL); -} diff --git a/eek/eek-gtk-keyboard.h b/eek/eek-gtk-keyboard.h deleted file mode 100644 index 3fad2c3c..00000000 --- a/eek/eek-gtk-keyboard.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_GTK_KEYBOARD_H -#define EEK_GTK_KEYBOARD_H 1 - -#include "eek-gtk-section.h" -#include "eek-keyboard.h" - -G_BEGIN_DECLS -#define EEK_TYPE_GTK_KEYBOARD (eek_gtk_keyboard_get_type()) -#define EEK_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEYBOARD, EekKeyboard)) -#define EEK_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass)) -#define EEK_IS_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEYBOARD)) -#define EEK_IS_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEYBOARD)) -#define EEK_GTK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass)) - -typedef struct _EekGtkKeyboard EekGtkKeyboard; -typedef struct _EekGtkKeyboardClass EekGtkKeyboardClass; -typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate; - -struct _EekGtkKeyboard -{ - /*< private >*/ - GtkVBox parent; - - EekGtkKeyboardPrivate *priv; -}; - -struct _EekGtkKeyboardClass -{ - /*< private >*/ - GtkVBoxClass parent_class; -}; - -GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST; - -EekKeyboard *eek_gtk_keyboard_new (void); - -G_END_DECLS -#endif /* EEK_GTK_KEYBOARD_H */ diff --git a/eek/eek-gtk-private.c b/eek/eek-gtk-private.c deleted file mode 100644 index 0c23db9e..00000000 --- a/eek/eek-gtk-private.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "eek-gtk-private.h" - -void -eek_gtk_callback (GtkWidget *widget, gpointer user_data) -{ - EekGtkCallbackData *data = user_data; - data->func (widget, data->user_data); -} diff --git a/eek/eek-gtk-private.h b/eek/eek-gtk-private.h deleted file mode 100644 index 7266e58e..00000000 --- a/eek/eek-gtk-private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_GTK_PRIVATE_H -#define EEK_GTK_PRIVATE_H 1 - -#include -#include - -struct _EekGtkCallbackData { - GFunc func; - gpointer user_data; -}; -typedef struct _EekGtkCallbackData EekGtkCallbackData; - -void eek_gtk_callback (GtkWidget *actor, gpointer user_data); - -#endif /* EEK_GTK_PRIVATE_H */ diff --git a/eek/eek-gtk-section.c b/eek/eek-gtk-section.c deleted file mode 100644 index 5ee2cef0..00000000 --- a/eek/eek-gtk-section.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -/** - * SECTION:eek-gtk-section - * @short_description: #EekSection implemented as a #GtkWidget - * - * The #EekGtkSection class implements the #EekSectionIface - * interface as a #GtkWidget. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ -#include "eek-gtk-section.h" -#include "eek-gtk-private.h" -#include "eek-simple-section.h" -#include - -enum { - PROP_0, - PROP_COLUMNS, - PROP_ROWS, - PROP_ANGLE, - PROP_BOUNDS, - PROP_LAST -}; - -static void eek_section_iface_init (EekSectionIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekGtkSection, eek_gtk_section, - GTK_TYPE_VBOX, - G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION, - eek_section_iface_init)); - -#define EEK_GTK_SECTION_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_SECTION, EekGtkSectionPrivate)) - -struct _EekGtkSectionPrivate -{ - EekSimpleSection *simple; - GtkWidget **rows; /* GtkHBox * */ -}; - -static void -eek_gtk_section_real_set_rows (EekSection *self, - gint rows) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_rows (EEK_SECTION(priv->simple), rows); - priv->rows = g_slice_alloc0 (sizeof(GtkHBox *) * rows); -} - -static gint -eek_gtk_section_real_get_rows (EekSection *self) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - return eek_section_get_rows (EEK_SECTION(priv->simple)); -} - -static void -eek_gtk_section_real_set_columns (EekSection *self, - gint row, - gint columns) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_columns (EEK_SECTION(priv->simple), row, columns); -} - -static gint -eek_gtk_section_real_get_columns (EekSection *self, - gint row) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - return eek_section_get_columns (EEK_SECTION(priv->simple), row); -} - -static void -eek_gtk_section_real_set_orientation (EekSection *self, - gint row, - EekOrientation orientation) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_orientation (EEK_SECTION(priv->simple), row, orientation); -} - -static EekOrientation -eek_gtk_section_real_get_orientation (EekSection *self, - gint row) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_ORIENTATION_INVALID); - return eek_section_get_orientation (EEK_SECTION(priv->simple), row); -} - -static void -eek_gtk_section_real_set_angle (EekSection *self, - gint angle) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_angle (EEK_SECTION(priv->simple), angle); -} - -static gint -eek_gtk_section_real_get_angle (EekSection *self) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, 0); - eek_section_get_angle (EEK_SECTION(priv->simple)); -} - -static void -eek_gtk_section_real_set_bounds (EekSection *self, - EekBounds *bounds) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - eek_section_set_bounds (EEK_SECTION(priv->simple), bounds); -} - -static void -eek_gtk_section_real_get_bounds (EekSection *self, - EekBounds *bounds) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - return eek_section_get_bounds (EEK_SECTION(priv->simple), bounds); -} - -static EekKey * -eek_gtk_section_real_create_key (EekSection *self, - const gchar *name, - guint keycode, - guint *keysyms, - gint num_groups, - gint num_levels, - gint column, - gint row, - EekOutline *outline, - EekBounds *bounds) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - EekKey *key; - EekKeysymMatrix matrix; - gint columns, rows; - - g_return_val_if_fail (priv, NULL); - - rows = eek_section_get_rows (self); - g_return_val_if_fail (0 <= row && row < rows, NULL); - columns = eek_section_get_columns (self, row); - g_return_val_if_fail (column < columns, NULL); - - matrix.data = keysyms; - matrix.num_groups = num_groups; - matrix.num_levels = num_levels; - key = g_object_new (EEK_TYPE_GTK_KEY, - "name", name, - "keycode", keycode, - "keysyms", &matrix, - "column", column, - "row", row, - "outline", outline, - "bounds", bounds, - NULL); - g_return_val_if_fail (key, NULL); - - if (priv->rows[row] == NULL) { - priv->rows[row] = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX(self), priv->rows[row], - FALSE, FALSE, 0); - gtk_box_reorder_child (GTK_BOX(self), priv->rows[row], row); - } - gtk_box_pack_start (GTK_BOX(priv->rows[row]), GTK_WIDGET(key), - FALSE, FALSE, 0); - gtk_box_reorder_child (GTK_BOX(priv->rows[row]), GTK_WIDGET(key), column); - return key; -} - -static void -eek_gtk_section_real_foreach_key (EekSection *self, - GFunc func, - gpointer user_data) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self); - EekGtkCallbackData data; - gint i, num_rows; - - g_return_if_fail (priv); - - data.func = func; - data.user_data = user_data; - - num_rows = eek_section_get_rows (self); - for (i = 0; i < num_rows; i++) - gtk_container_foreach (GTK_CONTAINER(priv->rows[i]), - eek_gtk_callback, - &data); -} - -static void -eek_section_iface_init (EekSectionIface *iface) -{ - iface->set_rows = eek_gtk_section_real_set_rows; - iface->get_rows = eek_gtk_section_real_get_rows; - iface->set_columns = eek_gtk_section_real_set_columns; - iface->get_columns = eek_gtk_section_real_get_columns; - iface->set_orientation = eek_gtk_section_real_set_orientation; - iface->get_orientation = eek_gtk_section_real_get_orientation; - iface->set_angle = eek_gtk_section_real_set_angle; - iface->get_angle = eek_gtk_section_real_get_angle; - iface->set_bounds = eek_gtk_section_real_set_bounds; - iface->get_bounds = eek_gtk_section_real_get_bounds; - iface->create_key = eek_gtk_section_real_create_key; - iface->foreach_key = eek_gtk_section_real_foreach_key; -} - -static void -eek_gtk_section_dispose (GObject *object) -{ - G_OBJECT_CLASS (eek_gtk_section_parent_class)->dispose (object); -} - -static void -eek_gtk_section_finalize (GObject *object) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object); - - g_slice_free (GtkWidget *, priv->rows); - g_object_unref (priv->simple); - G_OBJECT_CLASS (eek_gtk_section_parent_class)->finalize (object); -} - -static void -eek_gtk_section_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object); - - switch (prop_id) { - case PROP_ANGLE: - eek_section_set_angle (EEK_SECTION(object), - g_value_get_int (value)); - break; - case PROP_BOUNDS: - eek_section_set_bounds (EEK_SECTION(object), - g_value_get_boxed (value)); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_gtk_section_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object); - EekBounds bounds; - - switch (prop_id) { - case PROP_ANGLE: - g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); - break; - case PROP_BOUNDS: - eek_section_get_bounds (EEK_SECTION(object), &bounds); - g_value_set_boxed (value, &bounds); - break; - default: - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_gtk_section_class_init (EekGtkSectionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, sizeof (EekGtkSectionPrivate)); - - gobject_class->set_property = eek_gtk_section_set_property; - gobject_class->get_property = eek_gtk_section_get_property; - gobject_class->finalize = eek_gtk_section_finalize; - gobject_class->dispose = eek_gtk_section_dispose; - - g_object_class_override_property (gobject_class, - PROP_ANGLE, - "angle"); - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); -} - -static void -eek_gtk_section_init (EekGtkSection *self) -{ - EekGtkSectionPrivate *priv; - - priv = self->priv = EEK_GTK_SECTION_GET_PRIVATE (self); - priv->simple = g_object_new (EEK_TYPE_SIMPLE_SECTION, NULL); - priv->rows = NULL; -} diff --git a/eek/eek-gtk-section.h b/eek/eek-gtk-section.h deleted file mode 100644 index 6f3d4cd9..00000000 --- a/eek/eek-gtk-section.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_GTK_SECTION_H -#define EEK_GTK_SECTION_H 1 - -#include "eek-gtk-key.h" -#include "eek-section.h" - -G_BEGIN_DECLS -#define EEK_TYPE_GTK_SECTION (eek_gtk_section_get_type()) -#define EEK_GTK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_SECTION, EekGtkSection)) -#define EEK_GTK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_SECTION, EekGtkSectionClass)) -#define EEK_IS_GTK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_SECTION)) -#define EEK_IS_GTK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_SECTION)) -#define EEK_GTK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_SECTION, EekGtkSectionClass)) - -typedef struct _EekGtkSection EekGtkSection; -typedef struct _EekGtkSectionClass EekGtkSectionClass; -typedef struct _EekGtkSectionPrivate EekGtkSectionPrivate; - -struct _EekGtkSection -{ - /*< private >*/ - GtkVBox parent; - - /*< private >*/ - EekGtkSectionPrivate *priv; -}; - -struct _EekGtkSectionClass -{ - /*< private >*/ - GtkVBoxClass parent_class; -}; - -GType eek_gtk_section_get_type (void) G_GNUC_CONST; - -G_END_DECLS -#endif /* EEK_GTK_SECTION_H */ diff --git a/eek/eek-gtk.h b/eek/eek-gtk.h deleted file mode 100644 index 327f2be2..00000000 --- a/eek/eek-gtk.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_GTK_H -#define EEK_GTK_H 1 - -#include "eek.h" -#include "eek-gtk-keyboard.h" - -#endif /* EEK_GTK_H */ diff --git a/eek/eek-gtk.pc.in b/eek/eek-gtk.pc.in deleted file mode 100644 index a7496fa1..00000000 --- a/eek/eek-gtk.pc.in +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (C) 2010 Daiki Ueno -# Copyright (C) 2010 Red Hat, Inc. - -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. - -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 USA - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: EEK-GTK -Description: A Library to Create Keyboard-like UI (GTK Support) -URL: http://github.com/ueno/eek -Version: @VERSION@ -Libs: -L${libdir} -leek -leek-gtk -Libs.private: @GTK2_LIBS@ -Cflags: -I${includedir}/eek-@EEK_API_VERSION@ diff --git a/eek/eek-key.c b/eek/eek-key.c index bd39de5b..d7d9a25e 100644 --- a/eek/eek-key.c +++ b/eek/eek-key.c @@ -20,408 +20,549 @@ /** * SECTION:eek-key - * @short_description: Base interface of a key - * @see_also: #EekSection + * @short_description: Base class of a key * - * The #EekKeyIface interface represents a key, which is parented to - * #EekSectionIface. + * The #EekKeyClass class represents a key. */ +#include +#define DEBUG 0 +#if DEBUG +#include +#endif + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ - #include "eek-key.h" #include "eek-keysym.h" +enum { + PROP_0, + PROP_KEYCODE, + PROP_KEYSYMS, + PROP_COLUMN, + PROP_ROW, + PROP_OUTLINE, + PROP_GROUP, + PROP_LEVEL, + PROP_LAST +}; + +enum { + PRESSED, + RELEASED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT); + +#define EEK_KEY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate)) + + +struct _EekKeyPrivate +{ + guint keycode; + EekKeysymMatrix keysyms; + gint column; + gint row; + EekOutline *outline; + gint group; + gint level; +}; + static void -eek_key_base_init (gpointer g_iface) +eek_key_real_set_keycode (EekKey *self, guint keycode) { - static gboolean is_initialized = FALSE; + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + priv->keycode = keycode; +} - if (!is_initialized) { - GParamSpec *pspec; +static guint +eek_key_real_get_keycode (EekKey *self) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + return priv->keycode; +} - /** - * EekKey:name: - * - * The name of #EekKey. - */ - pspec = g_param_spec_string ("name", - "Name", - "Name", - NULL, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); +static void +eek_key_real_set_keysyms (EekKey *self, + guint *keysyms, + gint num_groups, + gint num_levels) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + gint num_keysyms = num_groups * num_levels; + + if (num_keysyms > 0) { + priv->keysyms.data = + g_slice_alloc (num_keysyms * sizeof(guint)); + memcpy (priv->keysyms.data, keysyms, + num_keysyms * sizeof(guint)); + } + priv->keysyms.num_groups = num_groups; + priv->keysyms.num_levels = num_levels; - /** - * EekKey:keycode: - * - * The keycode of #EekKey. - */ - pspec = g_param_spec_uint ("keycode", - "Keycode", - "Keycode of the key", - 0, G_MAXUINT, 0, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); +#if DEBUG + { + const gchar *name; + gint i; - /** - * EekKey:keysyms: - * - * The symbol matrix of #EekKey. - */ - pspec = g_param_spec_boxed ("keysyms", - "Keysyms", - "Symbol matrix of the key", - EEK_TYPE_KEYSYM_MATRIX, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); + name = eek_element_get_name (EEK_ELEMENT(self)); + fprintf (stderr, "%s: ", name); + for (i = 0; i < priv->keysyms.num_groups * priv->keysyms.num_levels; i++) + fprintf (stderr, "\"%s\" ", eek_keysym_to_string (priv->keysyms.data[i])); + fprintf (stderr, "\n"); + } +#endif +} - /** - * EekKey:column: - * - * The column index of #EekKey in the parent #EekSection. - */ - pspec = g_param_spec_int ("column", - "Column", - "Column index of the key in section", - -1, G_MAXINT, -1, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); +static void +eek_key_real_get_keysyms (EekKey *self, + guint **keysyms, + gint *num_groups, + gint *num_levels) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels; - /** - * EekKey:row: - * - * The row index of #EekKey in the parent #EekSection. - */ - pspec = g_param_spec_int ("row", - "Row", - "Row index of the key in section", - -1, G_MAXINT, -1, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); - - /** - * EekKey:outline: - * - * The pointer to the outline shape of #EekKey. - */ - /* Use pointer instead of boxed to avoid copy, since we can - assume that only a few outline shapes are used in a whole - keyboard (unlike keysyms and bounds). */ - pspec = g_param_spec_pointer ("outline", - "Outline", - "Pointer to outline shape of the key", - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); - - /** - * EekKey:bounds: - * - * The bounding box of #EekKey. - */ - pspec = g_param_spec_boxed ("bounds", - "Bounds", - "Bounding box of the key", - EEK_TYPE_BOUNDS, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); - - /** - * EekKey:group: - * - * The column index of #EekKey in the symbol matrix #EekKey:keysyms. - */ - pspec = g_param_spec_int ("group", - "Group", - "Current group of the key", - 0, 64, 0, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); - - /** - * EekKey:level: - * - * The row index of #EekKey in the symbol matrix #EekKey:keysyms. - */ - pspec = g_param_spec_int ("level", - "Level", - "Current level of the key", - 0, 3, 0, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); - - is_initialized = TRUE; + if (num_groups) + *num_groups = priv->keysyms.num_groups; + if (num_levels) + *num_levels = priv->keysyms.num_levels; + if (keysyms && num_keysyms > 0) { + *keysyms = g_slice_alloc (num_keysyms * sizeof(guint)); + memcpy (*keysyms, priv->keysyms.data, num_keysyms * sizeof(guint)); } } -GType -eek_key_get_type (void) +static guint +eek_key_real_get_keysym (EekKey *self) { - static GType iface_type = 0; + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels; - if (iface_type == 0) { - static const GTypeInfo info = { - sizeof (EekKeyIface), - eek_key_base_init, /* iface_base_init */ - NULL /* iface_base_finalize */ - }; - - iface_type = g_type_register_static (G_TYPE_INTERFACE, - "EekKey", - &info, - 0); - } - return iface_type; + if (num_keysyms == 0) + return EEK_INVALID_KEYSYM; + return priv->keysyms.data[priv->group * priv->keysyms.num_levels + + priv->level]; +} + +static void +eek_key_real_set_index (EekKey *self, + gint column, + gint row) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + + g_return_if_fail (0 <= column); + g_return_if_fail (0 <= row); + priv->column = column; + priv->row = row; +} + +static void +eek_key_real_get_index (EekKey *self, + gint *column, + gint *row) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + + if (column) + *column = priv->column; + if (row) + *row = priv->row; +} + +static void +eek_key_real_set_outline (EekKey *self, EekOutline *outline) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + priv->outline = outline; +} + +static EekOutline * +eek_key_real_get_outline (EekKey *self) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + return priv->outline; +} + +static void +eek_key_real_set_keysym_index (EekKey *self, + gint group, + gint level) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + + g_return_if_fail (0 <= group); + if (group >= priv->keysyms.num_groups) + group = 0; + g_return_if_fail (0 <= level && level < priv->keysyms.num_levels); + priv->group = group; + priv->level = level; +} + +static void +eek_key_real_get_keysym_index (EekKey *self, + gint *group, + gint *level) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); + + g_return_if_fail (group); + g_return_if_fail (level); + if (group) + *group = priv->group; + if (level) + *level = priv->level; +} + +static void +eek_key_finalize (GObject *object) +{ + EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object); + gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels; + + g_slice_free1 (num_keysyms * sizeof (guint), priv->keysyms.data); + G_OBJECT_CLASS (eek_key_parent_class)->finalize (object); +} + +static void +eek_key_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekKeysymMatrix *matrix; + gint column, row; + gint group, level; + + g_return_if_fail (EEK_IS_KEY(object)); + switch (prop_id) { + case PROP_KEYCODE: + eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value)); + break; + case PROP_KEYSYMS: + matrix = g_value_get_boxed (value); + eek_key_set_keysyms (EEK_KEY(object), + matrix->data, + matrix->num_groups, + matrix->num_levels); + break; + case PROP_COLUMN: + eek_key_get_index (EEK_KEY(object), &column, &row); + eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row); + break; + case PROP_ROW: + eek_key_get_index (EEK_KEY(object), &column, &row); + eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value)); + break; + case PROP_OUTLINE: + eek_key_set_outline (EEK_KEY(object), g_value_get_pointer (value)); + break; + case PROP_GROUP: + eek_key_get_keysym_index (EEK_KEY(object), &group, &level); + eek_key_set_keysym_index (EEK_KEY(object), g_value_get_int (value), + level); + break; + case PROP_LEVEL: + eek_key_get_keysym_index (EEK_KEY(object), &group, &level); + eek_key_set_keysym_index (EEK_KEY(object), group, + g_value_get_int (value)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_key_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekKeysymMatrix matrix; + gint column, row; + gint group, level; + + g_return_if_fail (EEK_IS_KEY(object)); + switch (prop_id) { + case PROP_KEYCODE: + g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object))); + break; + case PROP_KEYSYMS: + eek_key_get_keysyms (EEK_KEY(object), &matrix.data, &matrix.num_groups, + &matrix.num_levels); + g_value_set_boxed (value, &matrix); + break; + case PROP_COLUMN: + eek_key_get_index (EEK_KEY(object), &column, &row); + g_value_set_int (value, column); + break; + case PROP_ROW: + eek_key_get_index (EEK_KEY(object), &column, &row); + g_value_set_int (value, row); + break; + case PROP_OUTLINE: + g_value_set_pointer (value, eek_key_get_outline (EEK_KEY(object))); + break; + case PROP_GROUP: + eek_key_get_keysym_index (EEK_KEY(object), &group, &level); + g_value_set_int (value, group); + break; + case PROP_LEVEL: + eek_key_get_keysym_index (EEK_KEY(object), &group, &level); + g_value_set_int (value, level); + break; + default: + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_key_class_init (EekKeyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, + sizeof (EekKeyPrivate)); + + klass->get_keycode = eek_key_real_get_keycode; + klass->set_keycode = eek_key_real_set_keycode; + klass->set_keysyms = eek_key_real_set_keysyms; + klass->get_keysyms = eek_key_real_get_keysyms; + klass->get_keysym = eek_key_real_get_keysym; + klass->set_index = eek_key_real_set_index; + klass->get_index = eek_key_real_get_index; + klass->set_outline = eek_key_real_set_outline; + klass->get_outline = eek_key_real_get_outline; + klass->set_keysym_index = eek_key_real_set_keysym_index; + klass->get_keysym_index = eek_key_real_get_keysym_index; + + gobject_class->set_property = eek_key_set_property; + gobject_class->get_property = eek_key_get_property; + gobject_class->finalize = eek_key_finalize; + + /** + * EekKey:keycode: + * + * The keycode of #EekKey. + */ + pspec = g_param_spec_uint ("keycode", + "Keycode", + "Keycode of the key", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec); + + /** + * EekKey:keysyms: + * + * The symbol matrix of #EekKey. + */ + pspec = g_param_spec_boxed ("keysyms", + "Keysyms", + "Symbol matrix of the key", + EEK_TYPE_KEYSYM_MATRIX, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_KEYSYMS, pspec); + + /** + * EekKey:column: + * + * The column index of #EekKey in the parent #EekSection. + */ + pspec = g_param_spec_int ("column", + "Column", + "Column index of the key in section", + -1, G_MAXINT, -1, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_COLUMN, pspec); + + /** + * EekKey:row: + * + * The row index of #EekKey in the parent #EekSection. + */ + pspec = g_param_spec_int ("row", + "Row", + "Row index of the key in section", + -1, G_MAXINT, -1, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_ROW, pspec); + + /** + * EekKey:outline: + * + * The pointer to the outline shape of #EekKey. + */ + /* Use pointer instead of boxed to avoid copy, since we can + assume that only a few outline shapes are used in a whole + keyboard (unlike keysyms and bounds). */ + pspec = g_param_spec_pointer ("outline", + "Outline", + "Pointer to outline shape of the key", + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_OUTLINE, pspec); + + /** + * EekKey:group: + * + * The column index of #EekKey in the symbol matrix #EekKey:keysyms. + */ + pspec = g_param_spec_int ("group", + "Group", + "Current group of the key", + 0, 64, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_GROUP, pspec); + + /** + * EekKey:level: + * + * The row index of #EekKey in the symbol matrix #EekKey:keysyms. + */ + pspec = g_param_spec_int ("level", + "Level", + "Current level of the key", + 0, 3, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_LEVEL, pspec); + + signals[PRESSED] = + g_signal_new ("pressed", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[RELEASED] = + g_signal_new ("released", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +eek_key_init (EekKey *self) +{ + EekKeyPrivate *priv; + + priv = self->priv = EEK_KEY_GET_PRIVATE(self); + priv->keycode = 0; + memset (&priv->keysyms, 0, sizeof priv->keysyms); + priv->column = priv->row = 0; + priv->outline = NULL; + priv->group = priv->level = 0; +} + +void +eek_key_set_keycode (EekKey *key, + guint keycode) +{ + g_return_if_fail (EEK_IS_KEY (key)); + EEK_KEY_GET_CLASS(key)->set_keycode (key, keycode); } -/** - * eek_key_get_keycode: - * @key: an #EekKey - * - * Get the keycode of @key. - */ guint eek_key_get_keycode (EekKey *key) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_val_if_fail (iface, EEK_INVALID_KEYCODE); - g_return_val_if_fail (iface->get_keycode, EEK_INVALID_KEYCODE); - return (*iface->get_keycode) (key); + g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE); + return EEK_KEY_GET_CLASS(key)->get_keycode (key); } -/** - * eek_key_set_keysyms: - * @key: an #EekKey - * @keysyms: symbol matrix of @key - * @num_groups: the number of groups (rows) of @keysyms - * @num_levels: the number of levels (columns) of @keysyms - * - * Set the symbol matrix of @key to @keysyms. @keysyms is an array of - * symbols (unsigned int) and the length must match with @num_groups * - * @num_levels. - */ void eek_key_set_keysyms (EekKey *key, guint *keysyms, gint num_groups, gint num_levels) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_keysyms); - (*iface->set_keysyms) (key, keysyms, num_groups, num_levels); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->set_keysyms (key, keysyms, num_groups, num_levels); } -/** - * eek_key_get_keysyms: - * @key: an #EekKey - * @keysyms: pointer where symbol matrix of @key will be stored - * @num_groups: pointer where the number of groups (rows) of @keysyms - * will be stored - * @num_levels: pointer where the number of levels (columns) of - * @keysyms will be stored - * - * Get the symbol matrix of @key to @keysyms. @keysyms is an array of - * symbols (unsigned int) and the length must match with @num_groups * - * @num_levels. - */ void eek_key_get_keysyms (EekKey *key, guint **keysyms, gint *num_groups, gint *num_levels) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->get_keysyms); - (*iface->get_keysyms) (key, keysyms, num_groups, num_levels); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->get_keysyms (key, keysyms, num_groups, num_levels); } -/** - * eek_key_get_groups: - * @key: an #EekKey - * - * Get the number of groups (rows) of the symbol matrix of @key. - */ -gint -eek_key_get_groups (EekKey *key) -{ - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_val_if_fail (iface, -1); - g_return_val_if_fail (iface->get_groups, -1); - return (*iface->get_groups) (key); -} - -/** - * eek_key_get_keysym: - * @key: an #EekKey - * - * Get the current symbol of @key. It is depend on the current group - * and level, and the symbol matrix of @key. They are set through - * eek_key_set_keysym_index() and eek_key_set_keysyms(), respectively. - */ guint eek_key_get_keysym (EekKey *key) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_val_if_fail (iface, EEK_INVALID_KEYSYM); - g_return_val_if_fail (iface->get_keysym, EEK_INVALID_KEYSYM); - return (*iface->get_keysym) (key); + g_return_val_if_fail (EEK_IS_KEY(key), EEK_INVALID_KEYSYM); + return EEK_KEY_GET_CLASS(key)->get_keysym (key); } -/** - * eek_key_set_index: - * @key: an #EekKey - * @column: column index in the section - * @row: row index in the section - * - * Set column and row index of @key in the parent section. - */ void -eek_key_set_index (EekKey *key, - gint column, - gint row) +eek_key_set_index (EekKey *key, + gint column, + gint row) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_index); - (*iface->set_index) (key, column, row); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->set_index (key, column, row); } -/** - * eek_key_get_index: - * @key: an #EekKey - * @column: a pointer to where column index in the section is stored - * @row: a pointer to where row index in the section is stored - * - * Get column and row index of @key in the parent section. - */ void -eek_key_get_index (EekKey *key, - gint *column, - gint *row) +eek_key_get_index (EekKey *key, + gint *column, + gint *row) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->get_index); - return (*iface->get_index) (key, column, row); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->get_index (key, column, row); } -/** - * eek_key_set_outline: - * @key: an #EekKey - * @outline: a pointer to the outline shape of @key - * - * Set outline shape of @key. - */ void eek_key_set_outline (EekKey *key, EekOutline *outline) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_outline); - (*iface->set_outline) (key, outline); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->set_outline (key, outline); } -/** - * eek_key_get_outline: - * @key: an #EekKey - * - * Get outline shape of @key as a pointer. - */ EekOutline * eek_key_get_outline (EekKey *key) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_val_if_fail (iface, NULL); - g_return_val_if_fail (iface->get_outline, NULL); - return (*iface->get_outline) (key); + g_return_val_if_fail (EEK_IS_KEY (key), NULL); + return EEK_KEY_GET_CLASS(key)->get_outline (key); } -/** - * eek_key_set_bounds: - * @key: an #EekKey - * @bounds: bounding box of @key - * - * Set the bounding box of @key to @bounds. - */ -void -eek_key_set_bounds (EekKey *key, - EekBounds *bounds) -{ - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_bounds); - (*iface->set_bounds) (key, bounds); -} - -/** - * eek_key_get_bounds: - * @key: an #EekKey - * @bounds: the bounding box of @key - * - * Get the bounding box of @key. - */ -void -eek_key_get_bounds (EekKey *key, - EekBounds *bounds) -{ - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->get_bounds); - return (*iface->get_bounds) (key, bounds); -} - -/** - * eek_key_set_keysym_index: - * @key: an #EekKey - * @group: row index of the symbol matrix #EekKey:keysyms - * @level: column index of the symbol matrix #EekKey:keysyms - * - * Select a cell of the symbol matrix of @key. - */ void eek_key_set_keysym_index (EekKey *key, - gint group, - gint level) + gint group, + gint level) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_keysym_index); - (*iface->set_keysym_index) (key, group, level); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->set_keysym_index (key, group, level); } -/** - * eek_key_get_keysym_index: - * @key: an #EekKey - * @group: a pointer where row index of the symbol matrix #EekKey:keysyms - * will be stored - * @level: a pointer where column index of the symbol matrix - * #EekKey:keysyms will be stored - * - * Get the current cell position of the symbol matrix of @key. - */ void -eek_key_get_keysym_index (EekKey *key, gint *column, gint *row) +eek_key_get_keysym_index (EekKey *key, + gint *group, + gint *level) { - EekKeyIface *iface = EEK_KEY_GET_IFACE(key); - - g_return_if_fail (iface); - g_return_if_fail (iface->get_keysym_index); - return (*iface->get_keysym_index) (key, column, row); + g_return_if_fail (EEK_IS_KEY(key)); + EEK_KEY_GET_CLASS(key)->get_keysym_index (key, group, level); } diff --git a/eek/eek-key.h b/eek/eek-key.h index 7268a4ad..fac2412d 100644 --- a/eek/eek-key.h +++ b/eek/eek-key.h @@ -21,24 +21,37 @@ #define EEK_KEY_H 1 #include +#include "eek-element.h" #include "eek-types.h" G_BEGIN_DECLS #define EEK_TYPE_KEY (eek_key_get_type()) #define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey)) +#define EEK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEY, EekKeyClass)) #define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY)) -#define EEK_KEY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_KEY, EekKeyIface)) +#define EEK_IS_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEY)) +#define EEK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEY, EekKeyClass)) -typedef struct _EekKeyIface EekKeyIface; -typedef struct _EekKey EekKey; +typedef struct _EekKeyClass EekKeyClass; +typedef struct _EekKeyPrivate EekKeyPrivate; -struct _EekKeyIface +struct _EekKey { /*< private >*/ - GTypeInterface g_iface; + EekElement parent; + + EekKeyPrivate *priv; +}; + +struct _EekKeyClass +{ + /*< private >*/ + EekElementClass parent_class; /*< public >*/ + void (* set_keycode) (EekKey *self, + guint keycode); guint (* get_keycode) (EekKey *self); void (* set_keysyms) (EekKey *self, guint *keysyms, @@ -48,7 +61,6 @@ struct _EekKeyIface guint **keysyms, gint *num_groups, gint *num_levels); - gint (* get_groups) (EekKey *self); guint (* get_keysym) (EekKey *self); void (* set_index) (EekKey *self, @@ -61,10 +73,6 @@ struct _EekKeyIface void (* set_outline) (EekKey *self, EekOutline *outline); EekOutline *(* get_outline) (EekKey *self); - void (* set_bounds) (EekKey *self, - EekBounds *bounds); - void (* get_bounds) (EekKey *self, - EekBounds *bounds); void (* set_keysym_index) (EekKey *self, gint group, @@ -76,6 +84,8 @@ struct _EekKeyIface GType eek_key_get_type (void) G_GNUC_CONST; +void eek_key_set_keycode (EekKey *key, + guint keycode); guint eek_key_get_keycode (EekKey *key); void eek_key_set_keysyms (EekKey *key, guint *keysyms, @@ -85,7 +95,6 @@ void eek_key_get_keysyms (EekKey *key, guint **keysyms, gint *num_groups, gint *num_levels); -gint eek_key_get_groups (EekKey *key); guint eek_key_get_keysym (EekKey *key); void eek_key_set_index (EekKey *key, @@ -98,10 +107,6 @@ void eek_key_get_index (EekKey *key, void eek_key_set_outline (EekKey *key, EekOutline *outline); EekOutline *eek_key_get_outline (EekKey *key); -void eek_key_set_bounds (EekKey *key, - EekBounds *bounds); -void eek_key_get_bounds (EekKey *key, - EekBounds *bounds); void eek_key_set_keysym_index (EekKey *key, gint group, diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index cd30c899..c49c96fe 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -20,14 +20,11 @@ /** * SECTION:eek-keyboard - * @short_description: Base interface of a keyboard + * @short_description: Base class of a keyboard * @see_also: #EekSection * - * The #EekKeyboardIface interface represents a keyboard, which - * consists of one or more sections of the #EekSectionIface interface. - * - * #EekKeyboardIface follows the Builder pattern and is responsible - * for creation of sections. + * The #EekKeyboardClass class represents a keyboard, which consists + * of one or more sections of the #EekSectionClass class. */ #ifdef HAVE_CONFIG_H @@ -35,85 +32,270 @@ #endif /* HAVE_CONFIG_H */ #include "eek-keyboard.h" +#include "eek-section.h" +#include "eek-key.h" + +enum { + PROP_0, + PROP_GROUP, + PROP_LEVEL, + PROP_LAST +}; + +enum { + KEY_PRESSED, + KEY_RELEASED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER); + +#define EEK_KEYBOARD_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate)) + + +struct _EekKeyboardPrivate +{ + gint group; + gint level; +}; + +struct keysym_index { + gint group; + gint level; +}; static void -eek_keyboard_base_init (gpointer g_iface) +set_keysym_index_for_key (EekElement *element, + gpointer user_data) { - static gboolean is_initialized = FALSE; + struct keysym_index *ki; - if (!is_initialized) { - GParamSpec *pspec; + g_return_if_fail (EEK_IS_KEY(element)); - /** - * EekKeyboard:bounds: - * - * The bounding box of #EekKeyboard. - */ - pspec = g_param_spec_boxed ("bounds", - "Bounds", - "Bounding box of the keyboard", - EEK_TYPE_BOUNDS, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); + ki = user_data; + eek_key_set_keysym_index (EEK_KEY(element), ki->group, ki->level); +} - is_initialized = TRUE; +static void +set_keysym_index_for_section (EekElement *element, + gpointer user_data) +{ + eek_container_foreach_child (EEK_CONTAINER(element), + set_keysym_index_for_key, + user_data); +} + +static void +eek_keyboard_real_set_keysym_index (EekKeyboard *self, + gint group, + gint level) +{ + EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); + struct keysym_index ki; + + ki.group = priv->group = group; + ki.level = priv->level = level; + + eek_container_foreach_child (EEK_CONTAINER(self), + set_keysym_index_for_section, + &ki); +} + +void +eek_keyboard_real_get_keysym_index (EekKeyboard *self, + gint *group, + gint *level) +{ + EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); + + g_return_if_fail (group || level); + if (group) + *group = priv->group; + if (level) + *level = priv->level; +} + +static void +key_pressed_event (EekSection *section, + EekKey *key, + EekKeyboard *keyboard) +{ + g_signal_emit_by_name (keyboard, "key-pressed", key); +} + +static void +key_released_event (EekSection *section, + EekKey *key, + EekKeyboard *keyboard) +{ + g_signal_emit_by_name (keyboard, "key-released", key); +} + +static EekSection * +eek_keyboard_real_create_section (EekKeyboard *self) +{ + EekSection *section; + + section = g_object_new (EEK_TYPE_SECTION, NULL); + g_return_val_if_fail (section, NULL); + g_object_ref_sink (section); + + g_signal_connect (section, "key-pressed", G_CALLBACK(key_pressed_event), self); + g_signal_connect (section, "key-released", G_CALLBACK(key_released_event), self); + + EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), + EEK_ELEMENT(section)); + return section; +} + +static void +eek_keyboard_real_set_layout (EekKeyboard *keyboard, + EekLayout *layout) +{ + g_return_if_fail (EEK_IS_LAYOUT(layout)); + + EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard); + + if (g_object_is_floating (layout)) + g_object_unref (layout); +} + +static void +eek_keyboard_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + gint group, level; + + g_return_if_fail (EEK_IS_KEYBOARD(object)); + switch (prop_id) { + case PROP_GROUP: + eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level); + eek_keyboard_set_keysym_index (EEK_KEYBOARD(object), + g_value_get_int (value), + level); + break; + case PROP_LEVEL: + eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level); + eek_keyboard_set_keysym_index (EEK_KEYBOARD(object), + group, + g_value_get_int (value)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; } } -GType -eek_keyboard_get_type (void) +static void +eek_keyboard_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - static GType iface_type = 0; + gint group, level; - if (iface_type == 0) { - static const GTypeInfo info = { - sizeof (EekKeyboardIface), - eek_keyboard_base_init, - NULL - }; - - iface_type = g_type_register_static (G_TYPE_INTERFACE, - "EekKeyboard", - &info, - 0); + g_return_if_fail (EEK_IS_KEYBOARD(object)); + switch (prop_id) { + case PROP_GROUP: + eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level); + g_value_set_int (value, group); + break; + case PROP_LEVEL: + eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &level, &level); + g_value_set_int (value, level); + break; + default: + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; } - return iface_type; } -/** - * eek_keyboard_set_bounds: - * @keyboard: an #EekKeyboard - * @bounds: bounding box of the keyboard - * - * Set the bounding box of @keyboard to @bounds. - */ -void -eek_keyboard_set_bounds (EekKeyboard *keyboard, - EekBounds *bounds) +static void +eek_keyboard_class_init (EekKeyboardClass *klass) { - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; - g_return_if_fail (iface); - g_return_if_fail (iface->set_bounds); - (*iface->set_bounds) (keyboard, bounds); + g_type_class_add_private (gobject_class, + sizeof (EekKeyboardPrivate)); + + klass->set_keysym_index = eek_keyboard_real_set_keysym_index; + klass->get_keysym_index = eek_keyboard_real_get_keysym_index; + klass->create_section = eek_keyboard_real_create_section; + klass->set_layout = eek_keyboard_real_set_layout; + + gobject_class->get_property = eek_keyboard_get_property; + gobject_class->set_property = eek_keyboard_set_property; + + /** + * EekKeyboard:group: + * + * The group (row) index of symbol matrix of #EekKeyboard. + */ + pspec = g_param_spec_int ("group", + "Group", + "Group index of symbol matrix of the keyboard", + 0, G_MAXINT, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_GROUP, + pspec); + + /** + * EekKeyboard:level: + * + * The level (row) index of symbol matrix of #EekKeyboard. + */ + pspec = g_param_spec_int ("level", + "Level", + "Level index of symbol matrix of the keyboard", + 0, G_MAXINT, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_LEVEL, + pspec); + + signals[KEY_PRESSED] = + g_signal_new ("key-pressed", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + EEK_TYPE_KEY); + + signals[KEY_RELEASED] = + g_signal_new ("key-released", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + EEK_TYPE_KEY); } -/** - * eek_keyboard_get_bounds: - * @keyboard: an #EekKeyboard - * @bounds: the bounding box of @keyboard - * - * Get the bounding box of @keyboard. - */ -void -eek_keyboard_get_bounds (EekKeyboard *keyboard, - EekBounds *bounds) +static void +eek_keyboard_init (EekKeyboard *self) { - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + EekKeyboardPrivate *priv; - g_return_if_fail (iface); - g_return_if_fail (iface->get_bounds); - return (*iface->get_bounds) (keyboard, bounds); + priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self); + priv->group = priv->level = 0; } /** @@ -125,19 +307,16 @@ eek_keyboard_get_bounds (EekKeyboard *keyboard, * Select a cell of the symbol matrix of each key on @keyboard. */ void -eek_keyboard_set_keysym_index (EekKeyboard *self, +eek_keyboard_set_keysym_index (EekKeyboard *keyboard, gint group, gint level) { - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(self); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_keysym_index); - (*iface->set_keysym_index) (self, group, level); + g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); + EEK_KEYBOARD_GET_CLASS(keyboard)->set_keysym_index (keyboard, group, level); } /** - * eek_keyboard_set_keysym_index: + * eek_keyboard_get_keysym_index: * @keyboard: an #EekKeyboard * @group: a pointer where row index of the symbol matrix of keys on * @keyboard will be stored @@ -147,57 +326,29 @@ eek_keyboard_set_keysym_index (EekKeyboard *self, * Get the current cell position of the symbol matrix of each key on @keyboard. */ void -eek_keyboard_get_keysym_index (EekKeyboard *self, +eek_keyboard_get_keysym_index (EekKeyboard *keyboard, gint *group, gint *level) { - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(self); - - g_return_if_fail (iface); - g_return_if_fail (iface->get_keysym_index); - return (*iface->get_keysym_index) (self, group, level); + g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); + EEK_KEYBOARD_GET_CLASS(keyboard)->get_keysym_index (keyboard, group, level); } /** * eek_keyboard_create_section: * @keyboard: an #EekKeyboard * @name: name of the section - * @angle: rotation angle of the section * @bounds: bounding box of the section * * Create an #EekSection instance and attach it to @keyboard. */ EekSection * -eek_keyboard_create_section (EekKeyboard *keyboard, - const gchar *name, - gint angle, - EekBounds *bounds) +eek_keyboard_create_section (EekKeyboard *keyboard) { - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); - - g_return_val_if_fail (iface, NULL); - g_return_val_if_fail (iface->create_section, NULL); - return (*iface->create_section) (keyboard, name, angle, bounds); -} - -/** - * eek_keyboard_foreach_section: - * @keyboard: an #EekKeyboard - * @func: a callback of #GFunc - * @user_data: a pointer to an object passed to @func - * - * Iterate over @keyboard's children list. - */ -void -eek_keyboard_foreach_section (EekKeyboard *keyboard, - GFunc func, - gpointer user_data) -{ - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); - - g_return_if_fail (iface); - g_return_if_fail (iface->foreach_section); - (*iface->foreach_section) (keyboard, func, user_data); + EekSection *section; + g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL); + section = EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard); + return section; } /** @@ -212,10 +363,6 @@ void eek_keyboard_set_layout (EekKeyboard *keyboard, EekLayout *layout) { - EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); - - g_return_if_fail (iface); - g_return_if_fail (iface->set_layout); - g_return_if_fail (EEK_IS_LAYOUT(layout)); - (*iface->set_layout) (keyboard, layout); + g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); + EEK_KEYBOARD_GET_CLASS(keyboard)->set_layout (keyboard, layout); } diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index fb066803..b3b63401 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -20,42 +20,45 @@ #ifndef EEK_KEYBOARD_H #define EEK_KEYBOARD_H 1 -#include "eek-section.h" +#include +#include "eek-container.h" +#include "eek-types.h" #include "eek-layout.h" G_BEGIN_DECLS #define EEK_TYPE_KEYBOARD (eek_keyboard_get_type()) #define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard)) +#define EEK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYBOARD, EekKeyboardClass)) #define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD)) -#define EEK_KEYBOARD_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardIface)) +#define EEK_IS_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYBOARD)) +#define EEK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYBOARD, EekKeyboardClass)) -typedef struct _EekKeyboardIface EekKeyboardIface; +typedef struct _EekKeyboardClass EekKeyboardClass; +typedef struct _EekKeyboardPrivate EekKeyboardPrivate; -struct _EekKeyboardIface +struct _EekKeyboard { /*< private >*/ - GTypeInterface g_iface; + EekContainer parent; + + EekKeyboardPrivate *priv; +}; + +struct _EekKeyboardClass +{ + /*< private >*/ + EekContainerClass parent_class; /*< public >*/ - void (* set_bounds) (EekKeyboard *self, - EekBounds *bounds); - void (* get_bounds) (EekKeyboard *self, - EekBounds *bounds); void (* set_keysym_index) (EekKeyboard *self, gint group, gint level); void (* get_keysym_index) (EekKeyboard *self, gint *group, gint *level); - EekSection *(* create_section) (EekKeyboard *self, - const gchar *name, - gint angle, - EekBounds *bounds); - - void (* foreach_section) (EekKeyboard *self, - GFunc func, - gpointer user_data); + + EekSection *(* create_section) (EekKeyboard *self); void (* set_layout) (EekKeyboard *self, EekLayout *layout); @@ -63,10 +66,6 @@ struct _EekKeyboardIface GType eek_keyboard_get_type (void) G_GNUC_CONST; -void eek_keyboard_set_bounds (EekKeyboard *keyboard, - EekBounds *bounds); -void eek_keyboard_get_bounds (EekKeyboard *keyboard, - EekBounds *bounds); void eek_keyboard_set_keysym_index (EekKeyboard *self, gint group, gint level); @@ -74,14 +73,7 @@ void eek_keyboard_get_keysym_index (EekKeyboard *self, gint *group, gint *level); -EekSection *eek_keyboard_create_section (EekKeyboard *keyboard, - const gchar *name, - gint angle, - EekBounds *bounds); - -void eek_keyboard_foreach_section (EekKeyboard *keyboard, - GFunc func, - gpointer user_data); +EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); void eek_keyboard_set_layout (EekKeyboard *keyboard, EekLayout *layout); diff --git a/eek/eek-layout.c b/eek/eek-layout.c index b480ab8c..f09f08f9 100644 --- a/eek/eek-layout.c +++ b/eek/eek-layout.c @@ -20,10 +20,10 @@ /** * SECTION:eek-layout - * @short_description: Base class of a layout engine + * @short_description: Base interface of a layout engine * - * The #EekLayout class is a base abstract class of layout engine - * which arranges keyboard elements. + * The #EekLayout class is a base interface of layout engine which + * arranges keyboard elements. */ #ifdef HAVE_CONFIG_H @@ -33,31 +33,39 @@ #include "eek-layout.h" #include "eek-keyboard.h" -G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_INITIALLY_UNOWNED); - static void -eek_layout_finalize (GObject *object) +eek_layout_base_init (gpointer gobject_class) { - G_OBJECT_CLASS (eek_layout_parent_class)->finalize (object); + static gboolean is_initialized = FALSE; + + if (!is_initialized) { + /* TODO: signals */ + is_initialized = TRUE; + } } -static void -eek_layout_dispose (GObject *object) +GType +eek_layout_get_type (void) { - G_OBJECT_CLASS (eek_layout_parent_class)->dispose (object); + static GType iface_type = 0; + if (iface_type == 0) { + static const GTypeInfo info = { + sizeof (EekLayoutIface), + eek_layout_base_init, + NULL, + }; + iface_type = g_type_register_static (G_TYPE_INTERFACE, + "EekLayout", + &info, 0); + } + return iface_type; } -static void -eek_layout_class_init (EekLayoutClass *klass) +void +eek_layout_apply (EekLayout *layout, + EekKeyboard *keyboard) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->finalize = eek_layout_finalize; - gobject_class->dispose = eek_layout_dispose; + g_return_if_fail (EEK_IS_LAYOUT(layout)); + EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard); } -static void -eek_layout_init (EekLayout *self) -{ -} diff --git a/eek/eek-layout.h b/eek/eek-layout.h index 08333d68..11f645dd 100644 --- a/eek/eek-layout.h +++ b/eek/eek-layout.h @@ -28,31 +28,24 @@ G_BEGIN_DECLS #define EEK_TYPE_LAYOUT (eek_layout_get_type()) #define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout)) -#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass)) #define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT)) -#define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT)) -#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass)) +#define EEK_LAYOUT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_LAYOUT, EekLayoutIface)) -typedef struct _EekLayoutClass EekLayoutClass; +typedef struct _EekLayoutIface EekLayoutIface; typedef struct _EekLayout EekLayout; -struct _EekLayout +struct _EekLayoutIface { /*< private >*/ - GInitiallyUnowned parent; + GTypeInterface parent_iface; + + void (*apply) (EekLayout *self, + EekKeyboard *keyboard); }; -struct _EekLayoutClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; - - /*< public >*/ - void (*apply_to_keyboard) (EekLayout *self, - EekKeyboard *keyboard); -}; - -GType eek_layout_get_type (void) G_GNUC_CONST; +GType eek_layout_get_type (void) G_GNUC_CONST; +void eek_layout_apply (EekLayout *layout, + EekKeyboard *keyboard); G_END_DECLS #endif /* EEK_LAYOUT_H */ diff --git a/eek/eek-private.c b/eek/eek-private.c deleted file mode 100644 index 5191628a..00000000 --- a/eek/eek-private.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2006 Sergey V. Udaltsov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "eek-private.h" -#include - -#define noKBDRAW_DEBUG - -static gdouble -length (gdouble x, gdouble y) -{ - return sqrt (x * x + y * y); -} - -static gdouble -point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny) -{ - return ax * nx + ay * ny; -} - -static void -normal_form (gdouble ax, gdouble ay, - gdouble bx, gdouble by, - gdouble * nx, gdouble * ny, gdouble * d) -{ - gdouble l; - - *nx = by - ay; - *ny = ax - bx; - - l = length (*nx, *ny); - - *nx /= l; - *ny /= l; - - *d = point_line_distance (ax, ay, *nx, *ny); -} - -static void -inverse (gdouble a, gdouble b, gdouble c, gdouble d, - gdouble * e, gdouble * f, gdouble * g, gdouble * h) -{ - gdouble det; - - det = a * d - b * c; - - *e = d / det; - *f = -b / det; - *g = -c / det; - *h = a / det; -} - -static void -multiply (gdouble a, gdouble b, gdouble c, gdouble d, - gdouble e, gdouble f, gdouble * x, gdouble * y) -{ - *x = a * e + b * f; - *y = c * e + d * f; -} - -static void -intersect (gdouble n1x, gdouble n1y, gdouble d1, - gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y) -{ - gdouble e, f, g, h; - - inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h); - multiply (e, f, g, h, d1, d2, x, y); -} - - -/* draw an angle from the current point to b and then to c, - * with a rounded corner of the given radius. - */ -static void -rounded_corner (cairo_t * cr, - gdouble bx, gdouble by, - gdouble cx, gdouble cy, gdouble radius) -{ - gdouble ax, ay; - gdouble n1x, n1y, d1; - gdouble n2x, n2y, d2; - gdouble pd1, pd2; - gdouble ix, iy; - gdouble dist1, dist2; - gdouble nx, ny, d; - gdouble a1x, a1y, c1x, c1y; - gdouble phi1, phi2; - - cairo_get_current_point (cr, &ax, &ay); -#ifdef KBDRAW_DEBUG - printf (" current point: (%f, %f), radius %f:\n", ax, ay, - radius); -#endif - - /* make sure radius is not too large */ - dist1 = length (bx - ax, by - ay); - dist2 = length (cx - bx, cy - by); - - radius = MIN (radius, MIN (dist1, dist2)); - - /* construct normal forms of the lines */ - normal_form (ax, ay, bx, by, &n1x, &n1y, &d1); - normal_form (bx, by, cx, cy, &n2x, &n2y, &d2); - - /* find which side of the line a,b the point c is on */ - if (point_line_distance (cx, cy, n1x, n1y) < d1) - pd1 = d1 - radius; - else - pd1 = d1 + radius; - - /* find which side of the line b,c the point a is on */ - if (point_line_distance (ax, ay, n2x, n2y) < d2) - pd2 = d2 - radius; - else - pd2 = d2 + radius; - - /* intersect the parallels to find the center of the arc */ - intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy); - - nx = (bx - ax) / dist1; - ny = (by - ay) / dist1; - d = point_line_distance (ix, iy, nx, ny); - - /* a1 is the point on the line a-b where the arc starts */ - intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y); - - nx = (cx - bx) / dist2; - ny = (cy - by) / dist2; - d = point_line_distance (ix, iy, nx, ny); - - /* c1 is the point on the line b-c where the arc ends */ - intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y); - - /* determine the first angle */ - if (a1x - ix == 0) - phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2; - else if (a1x - ix > 0) - phi1 = atan ((a1y - iy) / (a1x - ix)); - else - phi1 = M_PI + atan ((a1y - iy) / (a1x - ix)); - - /* determine the second angle */ - if (c1x - ix == 0) - phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2; - else if (c1x - ix > 0) - phi2 = atan ((c1y - iy) / (c1x - ix)); - else - phi2 = M_PI + atan ((c1y - iy) / (c1x - ix)); - - /* compute the difference between phi2 and phi1 mod 2pi */ - d = phi2 - phi1; - while (d < 0) - d += 2 * M_PI; - while (d > 2 * M_PI) - d -= 2 * M_PI; - -#ifdef KBDRAW_DEBUG - printf (" line 1 to: (%f, %f):\n", a1x, a1y); -#endif - if (!(isnan (a1x) || isnan (a1y))) - cairo_line_to (cr, a1x, a1y); - - /* pick the short arc from phi1 to phi2 */ - if (d < M_PI) - cairo_arc (cr, ix, iy, radius, phi1, phi2); - else - cairo_arc_negative (cr, ix, iy, radius, phi1, phi2); - -#ifdef KBDRAW_DEBUG - printf (" line 2 to: (%f, %f):\n", cx, cy); -#endif - cairo_line_to (cr, cx, cy); -} - -void -eek_cairo_draw_rounded_polygon (cairo_t * cr, - gboolean filled, - gdouble radius, - EekPoint * points, - gint num_points) -{ - gint i, j; - - cairo_move_to (cr, - (gdouble) (points[num_points - 1].x + - points[0].x) / 2, - (gdouble) (points[num_points - 1].y + - points[0].y) / 2); - - -#ifdef KBDRAW_DEBUG - printf (" rounded polygon of radius %f:\n", radius); -#endif - for (i = 0; i < num_points; i++) { - j = (i + 1) % num_points; - rounded_corner (cr, (gdouble) points[i].x, - (gdouble) points[i].y, - (gdouble) (points[i].x + points[j].x) / 2, - (gdouble) (points[i].y + points[j].y) / 2, - radius); -#ifdef KBDRAW_DEBUG - printf (" corner (%d, %d) -> (%d, %d):\n", - points[i].x, points[i].y, points[j].x, - points[j].y); -#endif - }; - cairo_close_path (cr); - - if (filled) - cairo_fill (cr); - else - cairo_stroke (cr); -} - diff --git a/eek/eek-private.h b/eek/eek-private.h deleted file mode 100644 index 61fcdddc..00000000 --- a/eek/eek-private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_PRIVATE_H -#define EEK_PRIVATE_H 1 - -#include -#include -#include "eek-types.h" - -G_BEGIN_DECLS - -void eek_cairo_draw_rounded_polygon (cairo_t * cr, - gboolean filled, - gdouble radius, - EekPoint * points, - gint num_points); - -G_END_DECLS -#endif /* EEK_PRIVATE_H */ diff --git a/eek/eek-section.c b/eek/eek-section.c index afa55eaa..1396adc0 100644 --- a/eek/eek-section.c +++ b/eek/eek-section.c @@ -20,350 +20,329 @@ /** * SECTION:eek-section - * @short_description: Base interface of a keyboard section - * @see_also: #EekKeyboard, #EekKey + * @short_description: Base class of a section + * @see_also: #EekKey * - * The #EekSectionIface interface represents a keyboard section, which - * is parented to #EekKeyboardIface and can have one or more keys of - * the #EekKeyIface interface. - * - * #EekSectionIface follows the Builder pattern and is responsible for - * creation of keys. + * The #EekSectionClass class represents a section, which consists + * of one or more keys of the #EekKeyClass class. */ +#include + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ - #include "eek-section.h" +#include "eek-key.h" + +enum { + PROP_0, + PROP_ANGLE, + PROP_LAST +}; + +enum { + KEY_PRESSED, + KEY_RELEASED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE (EekSection, eek_section, EEK_TYPE_CONTAINER); + +#define EEK_SECTION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SECTION, EekSectionPrivate)) + +struct _EekRow +{ + gint num_columns; + EekOrientation orientation; +}; + +typedef struct _EekRow EekRow; + +struct _EekSectionPrivate +{ + gint angle; + GSList *rows; + GSList *keys; +}; static void -eek_section_base_init (gpointer g_iface) +eek_section_real_set_angle (EekSection *self, + gint angle) { - static gboolean is_initialized = FALSE; + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); - if (!is_initialized) { - GParamSpec *pspec; + priv->angle = angle; - /** - * EekSection:name: - * - * The name of #EekSection. - */ - pspec = g_param_spec_string ("name", - "Name", - "Name", - NULL, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); + g_object_notify (G_OBJECT(self), "angle"); +} - /** - * EekSection:columns: - * - * The number of columns in #EekSection. - */ - pspec = g_param_spec_int ("columns", - "Columns", - "The number of columns in the section", - 0, G_MAXINT, 0, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); +static gint +eek_section_real_get_angle (EekSection *self) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); - /** - * EekSection:rows: - * - * The number of rows in #EekSection. - */ - pspec = g_param_spec_int ("rows", - "Rows", - "The number of rows of the section", - 0, G_MAXINT, 0, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); + return priv->angle; +} - /** - * EekSection:angle: - * - * The rotation angle of #EekSection. - */ - pspec = g_param_spec_int ("angle", - "Angle", - "Rotation angle of the section", - -360, 360, 0, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); +static gint +eek_section_real_get_n_rows (EekSection *self) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); - /** - * EekSection:bounds: - * - * The bounding box of #EekSection. - */ - pspec = g_param_spec_boxed ("bounds", - "Bounds", - "Bounding box of the section", - EEK_TYPE_BOUNDS, - G_PARAM_READWRITE); - g_object_interface_install_property (g_iface, pspec); + return g_slist_length (priv->rows); +} - is_initialized = TRUE; +static void +eek_section_real_add_row (EekSection *self, + gint num_columns, + EekOrientation orientation) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); + EekRow *row; + + row = g_slice_new (EekRow); + row->num_columns = num_columns; + row->orientation = orientation; + priv->rows = g_slist_append (priv->rows, row); +} + +static void +eek_section_real_get_row (EekSection *self, + gint index, + gint *num_columns, + EekOrientation *orientation) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); + EekRow *row; + + row = g_slist_nth_data (priv->rows, index); + g_return_if_fail (row); + if (num_columns) + *num_columns = row->num_columns; + if (orientation) + *orientation = row->orientation; +} + +static void +pressed_event (EekKey *key, EekSection *section) +{ + g_signal_emit_by_name (section, "key-pressed", key); +} + +static void +released_event (EekKey *key, EekSection *section) +{ + g_signal_emit_by_name (section, "key-released", key); +} + +static EekKey * +eek_section_real_create_key (EekSection *self, + gint column, + gint row) +{ + EekKey *key; + gint num_columns, num_rows; + EekOrientation orientation; + + num_rows = eek_section_get_n_rows (self); + g_return_val_if_fail (0 <= row && row < num_rows, NULL); + eek_section_get_row (self, row, &num_columns, &orientation); + g_return_val_if_fail (column < num_columns, NULL); + + key = g_object_new (EEK_TYPE_KEY, + "column", column, + "row", row, + NULL); + g_return_val_if_fail (key, NULL); + g_object_ref_sink (key); + + g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self); + g_signal_connect (key, "released", G_CALLBACK(released_event), self); + + EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), + EEK_ELEMENT(key)); + + return key; +} + +static void +eek_section_finalize (GObject *object) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(object); + GSList *head; + + for (head = priv->rows; head; head = g_slist_next (head)) + g_slice_free (EekRow, head->data); + g_slist_free (priv->rows); + + for (head = priv->keys; head; head = g_slist_next (head)) + g_object_unref (head->data); + g_slist_free (priv->keys); + + G_OBJECT_CLASS (eek_section_parent_class)->finalize (object); +} + +static void +eek_section_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_ANGLE: + eek_section_set_angle (EEK_SECTION(object), + g_value_get_int (value)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; } } -GType -eek_section_get_type (void) +static void +eek_section_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - static GType iface_type = 0; - - if (iface_type == 0) { - static const GTypeInfo info = { - sizeof (EekSectionIface), - eek_section_base_init, - NULL - }; - - iface_type = g_type_register_static (G_TYPE_INTERFACE, - "EekSection", - &info, - 0); + switch (prop_id) { + case PROP_ANGLE: + g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); + break; + default: + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; } - return iface_type; } -/** - * eek_section_set_rows: - * @section: an #EekSection - * @rows: the number of rows in @section - * - * Set the number of rows in @section to @rows. - */ +static void +eek_section_class_init (EekSectionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, sizeof (EekSectionPrivate)); + + klass->set_angle = eek_section_real_set_angle; + klass->get_angle = eek_section_real_get_angle; + klass->get_n_rows = eek_section_real_get_n_rows; + klass->add_row = eek_section_real_add_row; + klass->get_row = eek_section_real_get_row; + klass->create_key = eek_section_real_create_key; + + gobject_class->set_property = eek_section_set_property; + gobject_class->get_property = eek_section_get_property; + gobject_class->finalize = eek_section_finalize; + + /** + * EekSection:angle: + * + * The rotation angle of #EekSection. + */ + pspec = g_param_spec_int ("angle", + "Angle", + "Rotation angle of the section", + -360, 360, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_ANGLE, + pspec); + + signals[KEY_PRESSED] = + g_signal_new ("key-pressed", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + EEK_TYPE_KEY); + + signals[KEY_RELEASED] = + g_signal_new ("key-released", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + EEK_TYPE_KEY); +} + +static void +eek_section_init (EekSection *self) +{ + EekSectionPrivate *priv; + + priv = self->priv = EEK_SECTION_GET_PRIVATE (self); + priv->angle = 0; + priv->rows = NULL; + priv->keys = NULL; +} + void -eek_section_set_rows (EekSection *section, - gint rows) +eek_section_set_angle (EekSection *section, + gint angle) { - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->set_rows); - (*iface->set_rows) (section, rows); + g_return_if_fail (EEK_IS_SECTION(section)); + EEK_SECTION_GET_CLASS(section)->set_angle (section, angle); } -/** - * eek_section_get_rows: - * @section: an #EekSection - * - * Get the number of rows in @section. - */ -gint -eek_section_get_rows (EekSection *section) -{ - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_val_if_fail (iface->get_rows, -1); - return (*iface->get_rows) (section); -} - -/** - * eek_section_set_columns: - * @section: an #EekSection - * @row: row index in @section - * @columns: the number of keys on @row - * - * Set the number of keys on the @row-th row in @section. - */ -void -eek_section_set_columns (EekSection *section, - gint row, - gint columns) -{ - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->set_columns); - (*iface->set_columns) (section, row, columns); -} - -/** - * eek_section_get_columns: - * @section: an #EekSection - * @row: row index in @section - * - * Get the number of keys on the @row-th row in @section. - */ -gint -eek_section_get_columns (EekSection *section, - gint row) -{ - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->get_columns); - return (*iface->get_columns) (section, row); -} - -/** - * eek_section_set_orientation: - * @section: an #EekSection - * @row: row index in @section - * @orientation: either %EEK_ORIENTATION_HORIZONTAL or %EEK_ORIENTATION_VERTICAL - * - * Set the orientation of the @row-th row in @section to @orientation. - */ -void -eek_section_set_orientation (EekSection *section, - gint row, - EekOrientation orientation) -{ - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->set_orientation); - (*iface->set_orientation) (section, row, orientation); -} - -/** - * eek_section_get_orientation: - * @section: an #EekSection - * @row: row index in @section - * - * Get the orientation of the @row-th row in @section. - * Returns: either %EEK_ORIENTATION_HORIZONTAL or %EEK_ORIENTATION_VERTICAL - */ -EekOrientation -eek_section_get_orientation (EekSection *section, - gint row) -{ - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_val_if_fail (iface->get_orientation, EEK_ORIENTATION_INVALID); - return (*iface->get_orientation) (section, row); -} - -/** - * eek_section_set_angle: - * @section: an #EekSection - * @angle: rotation angle of @section - * - * Set the rotation angle of @section to @angle. - */ -void -eek_section_set_angle (EekSection *section, - gint angle) -{ - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->set_angle); - (*iface->set_angle) (section, angle); -} - -/** - * eek_section_get_angle: - * @section: an #EekSection - * - * Get the rotation angle of @section. - */ gint eek_section_get_angle (EekSection *section) { - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_val_if_fail (iface->get_angle, 0); - return (*iface->get_angle) (section); + g_return_val_if_fail (EEK_IS_SECTION(section), -1); + return EEK_SECTION_GET_CLASS(section)->get_angle (section); } -/** - * eek_section_set_bounds: - * @section: an #EekSection - * @bounds: bounding box of @section - * - * Set the bounding box of @section to @bounds. - */ -void -eek_section_set_bounds (EekSection *section, - EekBounds *bounds) +gint +eek_section_get_n_rows (EekSection *section) { - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->set_bounds); - (*iface->set_bounds) (section, bounds); + g_return_val_if_fail (EEK_IS_SECTION(section), -1); + return EEK_SECTION_GET_CLASS(section)->get_n_rows (section); } -/** - * eek_section_get_bounds: - * @section: an #EekSection - * @bounds: the bounding box of @section - * - * Get the bounding box of @section. - */ void -eek_section_get_bounds (EekSection *section, - EekBounds *bounds) +eek_section_add_row (EekSection *section, + gint num_columns, + EekOrientation orientation) { - EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); - - g_return_if_fail (iface->get_bounds); - return (*iface->get_bounds) (section, bounds); + g_return_if_fail (EEK_IS_SECTION(section)); + EEK_SECTION_GET_CLASS(section)->add_row (section, + num_columns, + orientation); +} + +void +eek_section_get_row (EekSection *section, + gint index, + gint *num_columns, + EekOrientation *orientation) +{ + g_return_if_fail (EEK_IS_SECTION(section)); + EEK_SECTION_GET_CLASS(section)->get_row (section, + index, + num_columns, + orientation); } -/** - * eek_section_create_key: - * @section: an #EekSection - * @name: name of the key - * @keysyms: symbol matrix of the key - * @num_groups: number of rows in the @keysyms - * @num_levels: number of columns in the @keysyms - * @column: column index in the @section - * @row: row index in the section - * @outline: outline shape of the key - * @bounds: bounding box of the key - * - * Create an #EekKey instance and attach it to @section. - */ EekKey * eek_section_create_key (EekSection *section, - const gchar *name, - guint keycode, - guint *keysyms, - gint num_groups, - gint num_levels, gint column, - gint row, - EekOutline *outline, - EekBounds *bounds) + gint row) { - EekSectionIface *iface; - - g_return_if_fail (EEK_IS_SECTION(section)); - - iface = EEK_SECTION_GET_IFACE(section); - g_return_if_fail (iface->create_key); - - return (*iface->create_key) (section, - name, - keycode, - keysyms, - num_groups, - num_levels, - column, - row, - outline, - bounds); -} - -/** - * eek_section_foreach_key: - * @section: an #EekSection - * @func: a callback of #GFunc - * @user_data: a pointer to an object passed to @func - * - * Iterate over @section's children list. - */ -void -eek_section_foreach_key (EekSection *section, - GFunc func, - gpointer user_data) -{ - EekSectionIface *iface; - - g_return_if_fail (EEK_IS_SECTION(section)); - - iface = EEK_SECTION_GET_IFACE(section); - g_return_if_fail (iface->foreach_key); - - return (*iface->foreach_key) (section, func, user_data); + g_return_val_if_fail (EEK_IS_SECTION(section), NULL); + return EEK_SECTION_GET_CLASS(section)->create_key (section, column, row); } diff --git a/eek/eek-section.h b/eek/eek-section.h index d9f5e7ae..85daab13 100644 --- a/eek/eek-section.h +++ b/eek/eek-section.h @@ -20,102 +20,72 @@ #ifndef EEK_SECTION_H #define EEK_SECTION_H 1 -#include "eek-key.h" +#include +#include "eek-container.h" +#include "eek-types.h" G_BEGIN_DECLS #define EEK_TYPE_SECTION (eek_section_get_type()) #define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection)) +#define EEK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SECTION, EekSectionClass)) #define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION)) -#define EEK_SECTION_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SECTION, EekSectionIface)) +#define EEK_IS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SECTION)) +#define EEK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SECTION, EekSectionClass)) -typedef struct _EekSectionIface EekSectionIface; -typedef struct _EekSection EekSection; +typedef struct _EekSectionClass EekSectionClass; +typedef struct _EekSectionPrivate EekSectionPrivate; -struct _EekSectionIface +struct _EekSection { /*< private >*/ - GTypeInterface g_iface; + EekContainer parent; - /*< public >*/ - void (* set_rows) (EekSection *self, - gint rows); - gint (* get_rows) (EekSection *self); - void (* set_columns) (EekSection *self, - gint row, - gint columns); - gint (* get_columns) (EekSection *self, - gint row); - void (* set_orientation) (EekSection *self, - gint row, - EekOrientation orientation); - EekOrientation (* get_orientation) (EekSection *self, - gint row); - - void (* set_angle) (EekSection *self, - gint angle); - gint (* get_angle) (EekSection *self); - - void (* set_bounds) (EekSection *self, - EekBounds *bounds); - void (* get_bounds) (EekSection *self, - EekBounds *bounds); - - EekKey *(* create_key) (EekSection *self, - const gchar *name, - guint keycode, - guint *keysyms, - gint num_groups, - gint num_levels, - gint column, - gint row, - EekOutline *outline, - EekBounds *bounds); - - void (* foreach_key) (EekSection *self, - GFunc func, - gpointer user_data); + EekSectionPrivate *priv; }; -GType eek_section_get_type (void) G_GNUC_CONST; +struct _EekSectionClass +{ + /*< private >*/ + EekContainerClass parent_class; -void eek_section_set_rows (EekSection *section, - gint rows); -gint eek_section_get_rows (EekSection *section); -void eek_section_set_columns (EekSection *section, - gint row, - gint columns); -gint eek_section_get_columns (EekSection *section, - gint row); -void eek_section_set_orientation (EekSection *section, - gint row, - EekOrientation orientation); -EekOrientation eek_section_get_orientation (EekSection *section, - gint row); + /*< public >*/ + void (* set_angle) (EekSection *self, + gint angle); + gint (* get_angle) (EekSection *self); -void eek_section_set_angle (EekSection *section, - gint angle); -gint eek_section_get_angle (EekSection *section); + gint (* get_n_rows) (EekSection *self); + void (* add_row) (EekSection *self, + gint num_columns, + EekOrientation orientation); + void (* get_row) (EekSection *self, + gint index, + gint *num_columns, + EekOrientation *orientation); -void eek_section_set_bounds (EekSection *section, - EekBounds *bounds); -void eek_section_get_bounds (EekSection *section, - EekBounds *bounds); + EekKey *(* create_key) (EekSection *self, + gint row, + gint column); +}; -EekKey *eek_section_create_key (EekSection *section, - const gchar *name, - guint keycode, - guint *keysyms, - gint num_groups, - gint num_levels, - gint column, - gint row, - EekOutline *outline, - EekBounds *bounds); +GType eek_section_get_type (void) G_GNUC_CONST; -void eek_section_foreach_key (EekSection *section, - GFunc func, - gpointer user_data); +void eek_section_set_angle (EekSection *section, + gint angle); +gint eek_section_get_angle (EekSection *section); + +gint eek_section_get_n_rows (EekSection *section); +void eek_section_add_row (EekSection *section, + gint num_columns, + EekOrientation orientation); +void eek_section_get_row (EekSection *section, + gint index, + gint *num_columns, + EekOrientation *orientation); + +EekKey *eek_section_create_key (EekSection *section, + gint column, + gint row); G_END_DECLS #endif /* EEK_SECTION_H */ diff --git a/eek/eek-simple-key.c b/eek/eek-simple-key.c deleted file mode 100644 index d19aacca..00000000 --- a/eek/eek-simple-key.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ -#include "eek-simple-key.h" -#include "eek-keysym.h" -#include - -#define DEBUG 0 -#if DEBUG -#include -#endif - -enum { - PROP_0, - PROP_NAME, - PROP_KEYCODE, - PROP_KEYSYMS, - PROP_COLUMN, - PROP_ROW, - PROP_OUTLINE, - PROP_BOUNDS, - PROP_GROUP, - PROP_LEVEL, - PROP_LAST -}; - -static void eek_key_iface_init (EekKeyIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekSimpleKey, eek_simple_key, - G_TYPE_INITIALLY_UNOWNED, - G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY, - eek_key_iface_init)); - -#define EEK_SIMPLE_KEY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyPrivate)) - -struct _EekSimpleKeyPrivate -{ - gchar *name; - guint keycode; - guint *keysyms; - gint num_levels; - gint num_groups; - gint column; - gint row; - EekOutline *outline; - EekBounds bounds; - gint group; - gint level; -}; - -static guint -eek_simple_key_real_get_keycode (EekKey *self) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_INVALID_KEYCODE); - return priv->keycode; -} - -static void -eek_simple_key_real_set_keysyms (EekKey *self, - guint *keysyms, - gint groups, - gint levels) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - if (priv->keysyms) - g_slice_free (guint, priv->keysyms); - priv->keysyms = g_slice_alloc (groups * levels * sizeof(guint)); - memcpy (priv->keysyms, keysyms, groups * levels * sizeof(guint)); - priv->num_groups = groups; - priv->num_levels = levels; - -#if DEBUG - { - gint i; - - fprintf (stderr, "%s: ", priv->name); - for (i = 0; i < groups * levels; i++) - fprintf (stderr, "\"%s\" ", eek_keysym_to_string (keysyms[i])); - fprintf (stderr, "\n"); - } -#endif -} - -static void -eek_simple_key_real_get_keysyms (EekKey *self, - guint **keysyms, - gint *groups, - gint *levels) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (groups); - g_return_if_fail (levels); - g_return_if_fail (keysyms); - - *groups = priv->num_groups; - *levels = priv->num_levels; - if (priv->keysyms) { - *keysyms = g_slice_alloc (*groups * *levels * sizeof(guint)); - memcpy (*keysyms, priv->keysyms, *groups * *levels * sizeof(guint)); - } else - *keysyms = NULL; -} - -static gint -eek_simple_key_real_get_groups (EekKey *self) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - return priv->num_groups; -} - -static guint -eek_simple_key_real_get_keysym (EekKey *self) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_INVALID_KEYSYM); - if (priv->num_groups * priv->num_levels == 0) - return EEK_INVALID_KEYSYM; - return priv->keysyms[priv->group * priv->num_levels + priv->level]; -} - -static void -eek_simple_key_real_set_index (EekKey *self, - gint column, - gint row) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (column < 0); - g_return_if_fail (row < 0); - priv->column = column; - priv->row = row; -} - -static void -eek_simple_key_real_get_index (EekKey *self, - gint *column, - gint *row) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (column); - g_return_if_fail (row); - *column = priv->column; - *row = priv->row; -} - -static void -eek_simple_key_real_set_outline (EekKey *self, EekOutline *outline) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - priv->outline = outline; -} - -static EekOutline * -eek_simple_key_real_get_outline (EekKey *self) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_val_if_fail (priv, NULL); - return priv->outline; -} - -static void -eek_simple_key_real_set_bounds (EekKey *self, - EekBounds *bounds) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - priv->bounds = *bounds; -} - -static void -eek_simple_key_real_get_bounds (EekKey *self, - EekBounds *bounds) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (bounds); - *bounds = priv->bounds; -} - -static void -eek_simple_key_real_set_keysym_index (EekKey *self, - gint group, - gint level) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (0 <= group); - if (group >= priv->num_groups) - group = 0; - g_return_if_fail (0 <= level && level < priv->num_levels); - priv->group = group; - priv->level = level; -} - -static void -eek_simple_key_real_get_keysym_index (EekKey *self, - gint *group, - gint *level) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (group); - g_return_if_fail (level); - *group = priv->group; - *level = priv->level; -} - -static void -eek_key_iface_init (EekKeyIface *iface) -{ - iface->get_keycode = eek_simple_key_real_get_keycode; - iface->set_keysyms = eek_simple_key_real_set_keysyms; - iface->get_keysyms = eek_simple_key_real_get_keysyms; - iface->get_groups = eek_simple_key_real_get_groups; - iface->get_keysym = eek_simple_key_real_get_keysym; - iface->set_index = eek_simple_key_real_set_index; - iface->get_index = eek_simple_key_real_get_index; - iface->set_outline = eek_simple_key_real_set_outline; - iface->get_outline = eek_simple_key_real_get_outline; - iface->set_bounds = eek_simple_key_real_set_bounds; - iface->get_bounds = eek_simple_key_real_get_bounds; - iface->set_keysym_index = eek_simple_key_real_set_keysym_index; - iface->get_keysym_index = eek_simple_key_real_get_keysym_index; -} - -static void -eek_simple_key_dispose (GObject *object) -{ - G_OBJECT_CLASS (eek_simple_key_parent_class)->dispose (object); -} - -static void -eek_simple_key_finalize (GObject *object) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); - - g_free (priv->name); - g_slice_free (guint, priv->keysyms); - G_OBJECT_CLASS (eek_simple_key_parent_class)->finalize (object); -} - -static void -eek_simple_key_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); - EekKeysymMatrix *matrix; - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_NAME: - g_free (priv->name); - priv->name = g_strdup (g_value_get_string (value)); - break; - case PROP_KEYCODE: - priv->keycode = g_value_get_uint (value); - break; - case PROP_KEYSYMS: - matrix = g_value_get_boxed (value); - eek_key_set_keysyms (EEK_KEY(object), - matrix->data, - matrix->num_groups, - matrix->num_levels); - break; - case PROP_COLUMN: - priv->column = g_value_get_int (value); - break; - case PROP_ROW: - priv->row = g_value_get_int (value); - break; - case PROP_OUTLINE: - priv->outline = g_value_get_pointer (value); - break; - case PROP_BOUNDS: - priv->bounds = *(EekBounds *)g_value_get_boxed (value); - break; - case PROP_GROUP: - priv->group = g_value_get_int (value); - break; - case PROP_LEVEL: - priv->level = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_simple_key_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); - EekKeysymMatrix matrix; - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_KEYCODE: - g_value_set_uint (value, priv->keycode); - break; - case PROP_KEYSYMS: - matrix.data = priv->keysyms; - matrix.num_groups = priv->num_groups; - matrix.num_levels = priv->num_levels; - g_value_set_boxed (value, &matrix); - break; - case PROP_COLUMN: - g_value_set_int (value, priv->column); - break; - case PROP_ROW: - g_value_set_int (value, priv->row); - break; - case PROP_OUTLINE: - g_value_set_pointer (value, priv->outline); - break; - case PROP_BOUNDS: - g_value_set_boxed (value, &priv->bounds); - break; - case PROP_GROUP: - g_value_set_int (value, priv->group); - break; - case PROP_LEVEL: - g_value_set_int (value, priv->level); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_simple_key_class_init (EekSimpleKeyClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, - sizeof (EekSimpleKeyPrivate)); - - gobject_class->set_property = eek_simple_key_set_property; - gobject_class->get_property = eek_simple_key_get_property; - gobject_class->finalize = eek_simple_key_finalize; - gobject_class->dispose = eek_simple_key_dispose; - - g_object_class_override_property (gobject_class, - PROP_NAME, - "name"); - g_object_class_override_property (gobject_class, - PROP_KEYCODE, - "keycode"); - g_object_class_override_property (gobject_class, - PROP_KEYSYMS, - "keysyms"); - g_object_class_override_property (gobject_class, - PROP_COLUMN, - "column"); - g_object_class_override_property (gobject_class, - PROP_ROW, - "row"); - g_object_class_override_property (gobject_class, - PROP_OUTLINE, - "outline"); - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); - g_object_class_override_property (gobject_class, - PROP_GROUP, - "group"); - g_object_class_override_property (gobject_class, - PROP_LEVEL, - "level"); -} - -static void -eek_simple_key_init (EekSimpleKey *self) -{ - EekSimpleKeyPrivate *priv; - - priv = self->priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); - priv->keysyms = NULL; - priv->keycode = 0; - priv->num_groups = 0; - priv->num_levels = 0; - priv->column = 0; - priv->row = 0; - priv->outline = NULL; - memset (&priv->bounds, 0, sizeof priv->bounds); -} diff --git a/eek/eek-simple-key.h b/eek/eek-simple-key.h deleted file mode 100644 index 3beb1866..00000000 --- a/eek/eek-simple-key.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_SIMPLE_KEY_H -#define EEK_SIMPLE_KEY_H 1 - -#include "eek-key.h" - -G_BEGIN_DECLS -#define EEK_TYPE_SIMPLE_KEY (eek_simple_key_get_type()) -#define EEK_SIMPLE_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKey)) -#define EEK_SIMPLE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyClass)) -#define EEK_IS_SIMPLE_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_KEY)) -#define EEK_IS_SIMPLE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_KEY)) -#define EEK_SIMPLE_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyClass)) - -typedef struct _EekSimpleKey EekSimpleKey; -typedef struct _EekSimpleKeyClass EekSimpleKeyClass; -typedef struct _EekSimpleKeyPrivate EekSimpleKeyPrivate; - -struct _EekSimpleKey -{ - /*< private >*/ - GInitiallyUnowned parent; - - /*< private >*/ - EekSimpleKeyPrivate *priv; -}; - -struct _EekSimpleKeyClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; -}; - -GType eek_simple_key_get_type (void) G_GNUC_CONST; - -G_END_DECLS -#endif /* EEK_SIMPLE_KEY_H */ diff --git a/eek/eek-simple-keyboard.c b/eek/eek-simple-keyboard.c deleted file mode 100644 index bf42467c..00000000 --- a/eek/eek-simple-keyboard.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "eek-simple-keyboard.h" - -enum { - PROP_0, - PROP_BOUNDS, - PROP_LAST -}; - -static void eek_keyboard_iface_init (EekKeyboardIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekSimpleKeyboard, eek_simple_keyboard, - G_TYPE_INITIALLY_UNOWNED, - G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD, - eek_keyboard_iface_init)); - -#define EEK_SIMPLE_KEYBOARD_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardPrivate)) - - -struct _EekSimpleKeyboardPrivate -{ - EekBounds bounds; - GSList *sections; -}; - -static void -eek_simple_keyboard_real_set_bounds (EekKeyboard *self, - EekBounds *bounds) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - priv->bounds = *bounds; -} - -static void -eek_simple_keyboard_real_get_bounds (EekKeyboard *self, - EekBounds *bounds) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (bounds); - *bounds = priv->bounds; -} - -static EekSection * -eek_simple_keyboard_real_create_section (EekKeyboard *self, - const gchar *name, - gint angle, - EekBounds *bounds) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); - EekSection *section; - - g_return_val_if_fail (priv, NULL); - section = g_object_new (EEK_TYPE_SIMPLE_SECTION, - "name", name, - "angle", angle, - "bounds", bounds, - NULL); - g_return_val_if_fail (section, NULL); - priv->sections = g_slist_prepend (priv->sections, section); - return section; -} - -static void -eek_simple_keyboard_real_foreach_section (EekKeyboard *self, - GFunc func, - gpointer user_data) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_slist_foreach (priv->sections, func, user_data); -} - -static void -eek_simple_keyboard_real_set_layout (EekKeyboard *self, - EekLayout *layout) -{ - g_return_if_fail (EEK_IS_KEYBOARD(self)); - g_return_if_fail (EEK_IS_LAYOUT(layout)); - - EEK_LAYOUT_GET_CLASS(layout)->apply_to_keyboard (layout, self); - if (g_object_is_floating (layout)) - g_object_unref (layout); -} - -static void -eek_keyboard_iface_init (EekKeyboardIface *iface) -{ - iface->set_bounds = eek_simple_keyboard_real_set_bounds; - iface->get_bounds = eek_simple_keyboard_real_get_bounds; - iface->create_section = eek_simple_keyboard_real_create_section; - iface->foreach_section = eek_simple_keyboard_real_foreach_section; - iface->set_layout = eek_simple_keyboard_real_set_layout; -} - -static void -eek_simple_keyboard_dispose (GObject *object) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object); - GSList *head; - - for (head = priv->sections; head; head = g_slist_next (head)) - g_object_unref (head->data); - G_OBJECT_CLASS (eek_simple_keyboard_parent_class)->dispose (object); -} - -static void -eek_simple_keyboard_finalize (GObject *object) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object); - - g_slist_free (priv->sections); - G_OBJECT_CLASS (eek_simple_keyboard_parent_class)->finalize (object); -} - -static void -eek_simple_keyboard_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_BOUNDS: - eek_keyboard_set_bounds (EEK_KEYBOARD(object), - g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_simple_keyboard_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object); - - g_return_if_fail (priv); - switch (prop_id) { - case PROP_BOUNDS: - g_value_set_boxed (value, &priv->bounds); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_simple_keyboard_class_init (EekSimpleKeyboardClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, - sizeof (EekSimpleKeyboardPrivate)); - - gobject_class->set_property = eek_simple_keyboard_set_property; - gobject_class->get_property = eek_simple_keyboard_get_property; - gobject_class->finalize = eek_simple_keyboard_finalize; - gobject_class->dispose = eek_simple_keyboard_dispose; - - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); -} - -static void -eek_simple_keyboard_init (EekSimpleKeyboard *self) -{ - EekSimpleKeyboardPrivate *priv; - - priv = self->priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); - priv->sections = NULL; -} - -EekKeyboard* -eek_simple_keyboard_new (void) -{ - return g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL); -} diff --git a/eek/eek-simple-keyboard.h b/eek/eek-simple-keyboard.h deleted file mode 100644 index 658dbc72..00000000 --- a/eek/eek-simple-keyboard.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_SIMPLE_KEYBOARD_H -#define EEK_SIMPLE_KEYBOARD_H 1 - -#include "eek-simple-section.h" -#include "eek-keyboard.h" - -G_BEGIN_DECLS -#define EEK_TYPE_SIMPLE_KEYBOARD (eek_simple_keyboard_get_type()) -#define EEK_SIMPLE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekKeyboard)) -#define EEK_SIMPLE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardClass)) -#define EEK_IS_SIMPLE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_KEYBOARD)) -#define EEK_IS_SIMPLE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_KEYBOARD)) -#define EEK_SIMPLE_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardClass)) - -typedef struct _EekSimpleKeyboard EekSimpleKeyboard; -typedef struct _EekSimpleKeyboardClass EekSimpleKeyboardClass; -typedef struct _EekSimpleKeyboardPrivate EekSimpleKeyboardPrivate; - -struct _EekSimpleKeyboard -{ - /*< private >*/ - GInitiallyUnowned parent; - - EekSimpleKeyboardPrivate *priv; -}; - -struct _EekSimpleKeyboardClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; -}; - -GType eek_simple_keyboard_get_type (void) G_GNUC_CONST; - -EekKeyboard *eek_simple_keyboard_new (void); - -G_END_DECLS -#endif /* EEK_SIMPLE_KEYBOARD_H */ diff --git a/eek/eek-simple-section.c b/eek/eek-simple-section.c deleted file mode 100644 index a5645df1..00000000 --- a/eek/eek-simple-section.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ -#include "eek-simple-section.h" -#include - -enum { - PROP_0, - PROP_NAME, - PROP_COLUMNS, - PROP_ROWS, - PROP_ANGLE, - PROP_BOUNDS, - PROP_LAST -}; - -static void eek_section_iface_init (EekSectionIface *iface); - -G_DEFINE_TYPE_WITH_CODE (EekSimpleSection, eek_simple_section, - G_TYPE_INITIALLY_UNOWNED, - G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION, - eek_section_iface_init)); - -#define EEK_SIMPLE_SECTION_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionPrivate)) - -struct _EekSimpleSectionPrivate -{ - gchar *name; - gint num_rows; - gint *num_columns; - EekOrientation *orientations; - gint angle; - EekBounds bounds; - GSList *keys; -}; - -static void -eek_simple_section_real_set_rows (EekSection *self, - gint rows) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (rows >= 0); - priv->num_rows = rows; - if (rows > 0) { - g_free (priv->num_columns); - priv->num_columns = g_slice_alloc (sizeof(gint) * priv->num_rows); - g_free (priv->orientations); - priv->orientations = - g_slice_alloc (sizeof(EekOrientation) * priv->num_rows); - } -} - -static gint -eek_simple_section_real_get_rows (EekSection *self) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - return priv->num_rows; -} - -static void -eek_simple_section_real_set_columns (EekSection *self, - gint row, - gint columns) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (0 <= row && row < priv->num_rows); - priv->num_columns[row] = columns; -} - -static gint -eek_simple_section_real_get_columns (EekSection *self, - gint row) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, -1); - g_return_val_if_fail (0 <= row && row < priv->num_rows, -1); - return priv->num_columns[row]; -} - -static void -eek_simple_section_real_set_orientation (EekSection *self, - gint row, - EekOrientation orientation) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (0 <= row && row < priv->num_rows); - priv->orientations[row] = orientation; -} - -static EekOrientation -eek_simple_section_real_get_orientation (EekSection *self, - gint row) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, EEK_ORIENTATION_INVALID); - g_return_if_fail (0 <= row && row < priv->num_rows); - return priv->orientations[row]; -} - -static void -eek_simple_section_real_set_angle (EekSection *self, - gint angle) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - priv->angle = angle; -} - -static gint -eek_simple_section_real_get_angle (EekSection *self) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_val_if_fail (priv, 0); - return priv->angle; -} - -static void -eek_simple_section_real_set_bounds (EekSection *self, - EekBounds *bounds) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (bounds); - priv->bounds = *bounds; -} - -static void -eek_simple_section_real_get_bounds (EekSection *self, EekBounds *bounds) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_return_if_fail (bounds); - priv->bounds = *bounds; -} - -static EekKey * -eek_simple_section_real_create_key (EekSection *self, - const gchar *name, - guint keycode, - guint *keysyms, - gint num_groups, - gint num_levels, - gint column, - gint row, - EekOutline *outline, - EekBounds *bounds) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - EekKey *key; - EekKeysymMatrix matrix; - - g_return_val_if_fail (priv, NULL); - g_return_val_if_fail (0 <= row && row < priv->num_rows, NULL); - g_return_val_if_fail (column < priv->num_columns[row], NULL); - - matrix.data = keysyms; - matrix.num_groups = num_groups; - matrix.num_levels = num_levels; - key = g_object_new (EEK_TYPE_SIMPLE_KEY, - "name", name, - "keycode", keycode, - "keysyms", &matrix, - "column", column, - "row", row, - "outline", outline, - "bounds", bounds, - NULL); - g_return_val_if_fail (key, NULL); - priv->keys = g_slist_prepend (priv->keys, key); - return key; -} - -static void -eek_simple_section_real_foreach_key (EekSection *self, - GFunc func, - gpointer user_data) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); - - g_return_if_fail (priv); - g_slist_foreach (priv->keys, func, user_data); -} - -static void -eek_section_iface_init (EekSectionIface *iface) -{ - iface->set_rows = eek_simple_section_real_set_rows; - iface->get_rows = eek_simple_section_real_get_rows; - iface->set_columns = eek_simple_section_real_set_columns; - iface->get_columns = eek_simple_section_real_get_columns; - iface->set_orientation = eek_simple_section_real_set_orientation; - iface->get_orientation = eek_simple_section_real_get_orientation; - iface->set_angle = eek_simple_section_real_set_angle; - iface->get_angle = eek_simple_section_real_get_angle; - iface->set_bounds = eek_simple_section_real_set_bounds; - iface->get_bounds = eek_simple_section_real_get_bounds; - iface->create_key = eek_simple_section_real_create_key; - iface->foreach_key = eek_simple_section_real_foreach_key; -} - -static void -eek_simple_section_dispose (GObject *object) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); - GSList *head; - - for (head = priv->keys; head; head = g_slist_next (head)) - g_object_unref (head->data); - - G_OBJECT_CLASS (eek_simple_section_parent_class)->dispose (object); -} - -static void -eek_simple_section_finalize (GObject *object) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); - - g_free (priv->name); - g_slist_free (priv->keys); - g_slice_free (gint, priv->num_columns); - g_slice_free (EekOrientation, priv->orientations); - G_OBJECT_CLASS (eek_simple_section_parent_class)->finalize (object); -} - -static void -eek_simple_section_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); - - switch (prop_id) { - case PROP_NAME: - g_free (priv->name); - priv->name = g_strdup (g_value_get_string (value)); - break; - case PROP_ANGLE: - eek_section_set_angle (EEK_SECTION(object), - g_value_get_int (value)); - break; - case PROP_BOUNDS: - eek_section_set_bounds (EEK_SECTION(object), - g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_simple_section_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); - - switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_ANGLE: - g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); - break; - case PROP_BOUNDS: - g_value_set_boxed (value, &priv->bounds); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } -} - -static void -eek_simple_section_class_init (EekSimpleSectionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (gobject_class, sizeof (EekSimpleSectionPrivate)); - - gobject_class->set_property = eek_simple_section_set_property; - gobject_class->get_property = eek_simple_section_get_property; - gobject_class->finalize = eek_simple_section_finalize; - gobject_class->dispose = eek_simple_section_dispose; - - g_object_class_override_property (gobject_class, - PROP_NAME, - "name"); - g_object_class_override_property (gobject_class, - PROP_ANGLE, - "angle"); - g_object_class_override_property (gobject_class, - PROP_BOUNDS, - "bounds"); -} - -static void -eek_simple_section_init (EekSimpleSection *self) -{ - EekSimpleSectionPrivate *priv; - - priv = self->priv = EEK_SIMPLE_SECTION_GET_PRIVATE (self); - priv->angle = 0; - memset (&priv->bounds, 0, sizeof priv->bounds); - priv->keys = NULL; - priv->num_rows = 0; - priv->num_columns = NULL; - priv->orientations = NULL; -} diff --git a/eek/eek-simple-section.h b/eek/eek-simple-section.h deleted file mode 100644 index c6f7eb72..00000000 --- a/eek/eek-simple-section.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_SIMPLE_SECTION_H -#define EEK_SIMPLE_SECTION_H 1 - -#include "eek-simple-key.h" -#include "eek-section.h" - -G_BEGIN_DECLS -#define EEK_TYPE_SIMPLE_SECTION (eek_simple_section_get_type()) -#define EEK_SIMPLE_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSection)) -#define EEK_SIMPLE_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionClass)) -#define EEK_IS_SIMPLE_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_SECTION)) -#define EEK_IS_SIMPLE_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_SECTION)) -#define EEK_SIMPLE_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionClass)) - -typedef struct _EekSimpleSection EekSimpleSection; -typedef struct _EekSimpleSectionClass EekSimpleSectionClass; -typedef struct _EekSimpleSectionPrivate EekSimpleSectionPrivate; - -struct _EekSimpleSection -{ - /*< private >*/ - GInitiallyUnowned parent; - - /*< private >*/ - EekSimpleSectionPrivate *priv; -}; - -struct _EekSimpleSectionClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; -}; - -GType eek_simple_section_get_type (void) G_GNUC_CONST; - -G_END_DECLS -#endif /* EEK_SIMPLE_SECTION_H */ diff --git a/eek/eek-types.c b/eek/eek-types.c index b313bd35..790987e7 100644 --- a/eek/eek-types.c +++ b/eek/eek-types.c @@ -17,6 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ + +/** + * SECTION:eek-types + * @short_description: Miscellaneous types + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ diff --git a/eek/eek-types.h b/eek/eek-types.h index c0f213af..fb30bcfd 100644 --- a/eek/eek-types.h +++ b/eek/eek-types.h @@ -30,6 +30,8 @@ typedef enum { EEK_ORIENTATION_INVALID = -1 } EekOrientation; +typedef struct _EekKey EekKey; +typedef struct _EekSection EekSection; typedef struct _EekKeyboard EekKeyboard; /** diff --git a/eek/eek-xkb-layout.c b/eek/eek-xkb-layout.c index 1c325f58..186d58f9 100644 --- a/eek/eek-xkb-layout.c +++ b/eek/eek-xkb-layout.c @@ -37,10 +37,17 @@ #include #include "eek-xkb-layout.h" #include "eek-keyboard.h" +#include "eek-section.h" +#include "eek-key.h" +#include "eek-keysym.h" #define noKBDRAW_DEBUG -G_DEFINE_TYPE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT); +static void eek_layout_iface_init (EekLayoutIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekXkbLayout, eek_xkb_layout, G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (EEK_TYPE_LAYOUT, + eek_layout_iface_init)); #define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate)) @@ -72,8 +79,6 @@ struct _EekXkbLayoutPrivate gint scale_denominator; }; -#define INVALID_KEYCODE ((guint)(-1)) - static guint find_keycode (EekXkbLayout *layout, gchar *key_name); @@ -104,7 +109,7 @@ xkb_to_pixmap_double (EekXkbLayout *layout, return d * priv->scale_numerator / priv->scale_denominator; } -static EekKey * +static void create_key (EekXkbLayout *layout, EekSection *section, gint column, @@ -120,11 +125,11 @@ create_key (EekXkbLayout *layout, EekXkbLayoutPrivate *priv = layout->priv; EekKey *key; EekBounds bounds; - guint *keysyms; + guint *keysyms = NULL; gchar name[XkbKeyNameLength + 1]; EekOutline *outline; KeyCode keycode; - gint num_groups, num_levels; + gint num_groups, num_levels, num_keysyms; xkbgeometry = priv->xkb->geom; xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx]; @@ -133,7 +138,7 @@ create_key (EekXkbLayout *layout, xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] : xkbshape->primary; - outline = g_new0 (EekOutline, 1); + outline = g_slice_new (EekOutline); outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius); if (xkboutline->num_points <= 2) { /* rectangular */ @@ -179,16 +184,16 @@ create_key (EekXkbLayout *layout, bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1); keycode = find_keycode (layout, name); - if (keycode == INVALID_KEYCODE) + if (keycode == EEK_INVALID_KEYCODE) num_groups = num_levels = 0; else { KeySym keysym; - gint num_keysyms, i, j; + gint i, j; num_groups = XkbKeyNumGroups (priv->xkb, keycode); num_levels = XkbKeyGroupsWidth (priv->xkb, keycode); num_keysyms = num_groups * num_levels; - keysyms = g_malloc0 ((num_keysyms) * sizeof(guint)); + keysyms = g_slice_alloc0 (num_keysyms * sizeof(guint)); for (i = 0; i < num_groups; i++) for (j = 0; j < num_levels; j++) { keysym = XkbKeySymEntry (priv->xkb, keycode, j, i); @@ -196,16 +201,15 @@ create_key (EekXkbLayout *layout, } } - eek_section_create_key (section, - name, - keycode, - keysyms, - num_groups, - num_levels, - column, - row, - outline, - &bounds); + key = eek_section_create_key (section, column, row); + eek_element_set_name (EEK_ELEMENT(key), name); + eek_element_set_bounds (EEK_ELEMENT(key), &bounds); + eek_key_set_keycode (key, keycode); + eek_key_set_keysyms (key, keysyms, num_groups, num_levels); + if (keysyms) + g_slice_free1 (num_keysyms * sizeof(guint), keysyms); + eek_key_set_keysym_index (key, 0, 0); + eek_key_set_outline (key, outline); } static void @@ -229,25 +233,24 @@ create_section (EekXkbLayout *layout, priv = layout->priv; xkbgeometry = priv->xkb->geom; name = XGetAtomName (priv->display, xkbsection->name); - section = eek_keyboard_create_section (keyboard, - name, - /* angle is in tenth of degree */ - xkbsection->angle / 10, - &bounds); + section = eek_keyboard_create_section (keyboard); + eek_element_set_name (EEK_ELEMENT(section), name); + eek_element_set_bounds (EEK_ELEMENT(section), &bounds); + eek_section_set_angle (section, + /* angle is in tenth of degree */ + xkbsection->angle / 10); - eek_section_set_rows (section, xkbsection->num_rows); for (i = 0; i < xkbsection->num_rows; i++) { XkbRowRec *xkbrow; xkbrow = &xkbsection->rows[i]; left = xkbrow->left; top = xkbrow->top; - eek_section_set_columns (section, i, xkbrow->num_keys); - eek_section_set_orientation (section, - i, - xkbrow->vertical ? - EEK_ORIENTATION_VERTICAL : - EEK_ORIENTATION_HORIZONTAL); + eek_section_add_row (section, + xkbrow->num_keys, + xkbrow->vertical ? + EEK_ORIENTATION_VERTICAL : + EEK_ORIENTATION_HORIZONTAL); for (j = 0; j < xkbrow->num_keys; j++) { XkbKeyRec *xkbkey; XkbBoundsRec *xkbbounds; @@ -280,39 +283,33 @@ create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard) xkbgeometry = priv->xkb->geom; - eek_keyboard_get_bounds (keyboard, &bounds); + eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height); bounds.x = bounds.y = 0; bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm); bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm); - eek_keyboard_set_bounds (keyboard, &bounds); for (i = 0; i < xkbgeometry->num_sections; i++) { XkbSectionRec *xkbsection; - EekSection *section; xkbsection = &xkbgeometry->sections[i]; create_section (layout, keyboard, xkbsection); } + eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds); } static void -eek_xkb_layout_apply_to_keyboard (EekLayout *layout, EekKeyboard *keyboard) +eek_xkb_layout_real_apply (EekLayout *layout, EekKeyboard *keyboard) { - g_return_if_fail (EEK_IS_XKB_LAYOUT(layout)); g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); + create_keyboard (EEK_XKB_LAYOUT(layout), keyboard); + if (g_object_is_floating (keyboard)) g_object_unref (keyboard); } -static void -eek_xkb_layout_dispose (GObject *object) -{ - G_OBJECT_CLASS (eek_xkb_layout_parent_class)->dispose (object); -} - static void eek_xkb_layout_finalize (GObject *object) { @@ -321,7 +318,8 @@ eek_xkb_layout_finalize (GObject *object) g_free (priv->names.keycodes); g_free (priv->names.geometry); g_free (priv->names.symbols); - g_hash_table_unref (priv->outline_hash); + /* XXX */ + //g_hash_table_unref (priv->outline_hash); XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */ G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object); } @@ -349,7 +347,9 @@ eek_xkb_layout_set_property (GObject *object, eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); break; } } @@ -377,27 +377,31 @@ eek_xkb_layout_get_property (GObject *object, g_value_set_string (value, name); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); break; } } +static void +eek_layout_iface_init (EekLayoutIface *iface) +{ + iface->apply = eek_xkb_layout_real_apply; +} + static void eek_xkb_layout_class_init (EekXkbLayoutClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate)); gobject_class->finalize = eek_xkb_layout_finalize; - gobject_class->dispose = eek_xkb_layout_dispose; gobject_class->set_property = eek_xkb_layout_set_property; gobject_class->get_property = eek_xkb_layout_get_property; - layout_class->apply_to_keyboard = eek_xkb_layout_apply_to_keyboard; - pspec = g_param_spec_string ("keycodes", "Keycodes", "XKB keycodes component name", @@ -420,6 +424,12 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass) g_object_class_install_property (gobject_class, PROP_SYMBOLS, pspec); } +static void +outline_free (gpointer data) +{ + g_slice_free (EekOutline, data); +} + static void eek_xkb_layout_init (EekXkbLayout *self) { @@ -443,7 +453,7 @@ eek_xkb_layout_init (EekXkbLayout *self) priv->outline_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - g_free); + outline_free); if (priv->xkb == NULL) { g_critical ("XkbGetKeyboard failed to get keyboard from the server!"); return; @@ -515,10 +525,12 @@ eek_xkb_layout_new (const gchar *keycodes, const gchar *geometry, const gchar *symbols) { - EekXkbLayout *layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL); - EekXkbLayoutPrivate *priv = layout->priv; + EekXkbLayout *layout; + EekXkbLayoutPrivate *priv; + layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL); g_return_val_if_fail (layout, NULL); + priv = layout->priv; if (keycodes) priv->names.keycodes = g_strdup (keycodes); if (geometry) @@ -609,8 +621,6 @@ G_CONST_RETURN gchar * eek_xkb_layout_get_geometry (EekXkbLayout *layout) { EekXkbLayoutPrivate *priv = layout->priv; - char *name; - return priv->names.geometry; } @@ -682,7 +692,7 @@ find_keycode (EekXkbLayout *layout, gchar *key_name) EekXkbLayoutPrivate *priv = layout->priv; if (!priv->xkb) - return INVALID_KEYCODE; + return EEK_INVALID_KEYCODE; #ifdef KBDRAW_DEBUG printf (" looking for keycode for (%c%c%c%c)\n", @@ -736,7 +746,7 @@ find_keycode (EekXkbLayout *layout, gchar *key_name) palias++; } - return INVALID_KEYCODE; + return EEK_INVALID_KEYCODE; } static void diff --git a/eek/eek-xkb-layout.h b/eek/eek-xkb-layout.h index 9c1662c5..b39b1cac 100644 --- a/eek/eek-xkb-layout.h +++ b/eek/eek-xkb-layout.h @@ -40,7 +40,7 @@ typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate; struct _EekXkbLayout { /*< private >*/ - EekLayout parent; + GInitiallyUnowned parent; EekXkbLayoutPrivate *priv; }; @@ -48,7 +48,7 @@ struct _EekXkbLayout struct _EekXkbLayoutClass { /*< private >*/ - EekLayoutClass parent_class; + GInitiallyUnownedClass parent_class; void (* set_keycodes) (EekXkbLayout *self, const gchar *keycodes); diff --git a/examples/Makefile.am b/examples/Makefile.am index d4e7bb68..48a27d09 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -16,9 +16,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA -noinst_PROGRAMS = eek-clutter-xkb-test eek-gtk-xkb-test +noinst_PROGRAMS = eek-clutter-xkb-test eek_clutter_xkb_test_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(CLUTTER_CFLAGS) $(XKB_CFLAGS) eek_clutter_xkb_test_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la $(top_builddir)/eek/libeek-clutter.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(XKB_LIBS) - -eek_gtk_xkb_test_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS) -eek_gtk_xkb_test_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la $(top_builddir)/eek/libeek-gtk.la $(GOBJECT2_LIBS) $(GTK2_LIBS) $(XKB_LIBS) diff --git a/examples/eek-clutter-xkb-test.c b/examples/eek-clutter-xkb-test.c index d12a76b7..cc95d658 100644 --- a/examples/eek-clutter-xkb-test.c +++ b/examples/eek-clutter-xkb-test.c @@ -4,8 +4,8 @@ #include #include -#define CSW 1280 -#define CSH 1024 +#define CSW 640 +#define CSH 480 static gchar *symbols = NULL; static gchar *keycodes = NULL; @@ -83,12 +83,21 @@ on_resize (GObject *object, &value); } +static void +key_pressed_event (EekKeyboard *keyboard, + EekKey *key) +{ + guint keysym = eek_key_get_keysym (key); + g_return_if_fail (keysym != EEK_INVALID_KEYSYM); + g_debug ("%s", eek_keysym_to_string (keysym)); +} + int main (int argc, char *argv[]) { EekKeyboard *keyboard; EekLayout *layout; - ClutterActor *stage; + ClutterActor *stage, *actor; ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff }; GOptionContext *context; @@ -116,16 +125,17 @@ main (int argc, char *argv[]) } g_object_ref_sink (keyboard); + g_signal_connect (keyboard, "key-pressed", G_CALLBACK(key_pressed_event), NULL); eek_keyboard_set_layout (keyboard, layout); - + actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard)); stage = clutter_stage_get_default (); clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - clutter_actor_get_size (CLUTTER_ACTOR(keyboard), &stage_width, &stage_height); + clutter_actor_get_size (actor, &stage_width, &stage_height); clutter_actor_set_size (stage, stage_width, stage_height); - clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard)); + clutter_group_add (CLUTTER_GROUP(stage), actor); clutter_actor_show_all (stage); @@ -139,11 +149,6 @@ main (int argc, char *argv[]) G_CALLBACK (on_resize), NULL); - g_signal_connect (stage, - "event", - G_CALLBACK (on_event), - NULL); - clutter_main (); return 0; diff --git a/tests/Makefile.am b/tests/Makefile.am index 714e6eb1..e1f91f6f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,13 +16,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA -INCLUDES = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(SIMPLE_CFLAGS) $(XKB_CFLAGS) +INCLUDES = -I$(top_srcdir) $(CLUTTER_CFLAGS) $(GOBJECT2_CFLAGS) $(SIMPLE_CFLAGS) $(XKB_CFLAGS) TESTS = eek-simple-test eek-xkb-test noinst_PROGRAMS = $(TESTS) eek_simple_test_SOURCES = eek-simple-test.c -eek_simple_test_LDADD = $(top_builddir)/eek/libeek.la +eek_simple_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-clutter.la eek_xkb_test_SOURCES = eek-xkb-test.c -eek_xkb_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la \ No newline at end of file +eek_xkb_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la diff --git a/tests/eek-simple-test.c b/tests/eek-simple-test.c index 4123bcd8..084ca1a4 100644 --- a/tests/eek-simple-test.c +++ b/tests/eek-simple-test.c @@ -17,74 +17,44 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ -#include "eek-simple-keyboard.h" +#include "eek.h" +#include "eek-clutter.h" static void test_create (void) { EekKeyboard *keyboard; EekSection *section; - EekKey *key; + EekKey *key0, *key1; - EekOutline outline = {45.0, NULL, 0}; - EekBounds bounds = {0.1, 0.2, 3.0, 4.0}; - EekKeysymMatrix *matrix; - GValue value = {0}; - gint iv; - const gchar *sv; - gpointer bv; - guint keysyms[] = {'a', 'b', 'c', 'd', 'e', 'f'}; + keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL); + section = eek_keyboard_create_section (keyboard); + g_assert (EEK_IS_SECTION(section)); + eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL); + key0 = eek_section_create_key (section, 0, 0); + g_assert (EEK_IS_KEY(key0)); + key1 = eek_section_create_key (section, 1, 0); + g_assert (EEK_IS_KEY(key1)); +} - keyboard = eek_simple_keyboard_new (); - g_assert (keyboard); - g_assert (g_object_is_floating (keyboard)); +static void +test_create_clutter (void) +{ + EekKeyboard *keyboard; + EekSection *section; + EekKey *key0, *key1; + ClutterActor *actor; - section = eek_keyboard_create_section (keyboard, - "test-section", - 45, - &bounds); - g_assert (section); - g_value_init (&value, G_TYPE_STRING); - g_object_get_property (G_OBJECT(section), "name", &value); - sv = g_value_get_string (&value); - g_assert_cmpstr (sv, ==, "test-section"); - g_value_unset (&value); - - g_value_init (&value, G_TYPE_INT); - g_object_get_property (G_OBJECT(section), "angle", &value); - iv = g_value_get_int (&value); - g_assert_cmpint (iv, ==, 45); - g_value_unset (&value); - - g_value_init (&value, EEK_TYPE_BOUNDS); - g_object_get_property (G_OBJECT(section), "bounds", &value); - bv = g_value_get_boxed (&value); - g_assert (bv); - g_assert_cmpfloat (((EekBounds *)bv)->x, ==, 0.1); - g_value_unset (&value); - - key = eek_section_create_key (section, - "test-key", - 0, - keysyms, - 3, - 2, - 1, - 2, - &outline, - &bounds); - g_assert (key); - g_value_init (&value, EEK_TYPE_KEYSYM_MATRIX); - g_object_get_property (G_OBJECT(key), "keysyms", &value); - matrix = g_value_get_boxed (&value); - g_assert_cmpint (matrix->data[0], ==, 'a'); - g_value_unset (&value); - - g_value_init (&value, G_TYPE_POINTER); - g_object_get_property (G_OBJECT(key), "outline", &value); - bv = g_value_get_pointer (&value); - g_assert (bv == &outline); - g_value_unset (&value); + keyboard = eek_clutter_keyboard_new (640.0, 480.0); + section = eek_keyboard_create_section (keyboard); + g_assert (EEK_IS_SECTION(section)); + eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL); + key0 = eek_section_create_key (section, 0, 0); + g_assert (EEK_IS_KEY(key0)); + key1 = eek_section_create_key (section, 1, 0); + g_assert (EEK_IS_KEY(key1)); + actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard)); + g_assert (CLUTTER_IS_ACTOR(actor)); g_object_unref (keyboard); } @@ -94,5 +64,7 @@ main (int argc, char **argv) g_type_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/eek-simple-test/create", test_create); + clutter_init (&argc, &argv); + g_test_add_func ("/eek-simple-test/create-clutter", test_create_clutter); return g_test_run (); }