Rewrite.
This commit is contained in:
9
README
9
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) \
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
|
||||
<chapter>
|
||||
<title>Base classes and interfaces</title>
|
||||
<xi:include href="xml/eek-element.xml"/>
|
||||
<xi:include href="xml/eek-container.xml"/>
|
||||
<xi:include href="xml/eek-keyboard.xml"/>
|
||||
<xi:include href="xml/eek-section.xml"/>
|
||||
<xi:include href="xml/eek-key.xml"/>
|
||||
@ -30,12 +32,6 @@
|
||||
<title>XKB layout engine</title>
|
||||
<xi:include href="xml/eek-xkb-layout.xml"/>
|
||||
</chapter>
|
||||
<chapter>
|
||||
<title>GTK keyboard elements</title>
|
||||
<xi:include href="xml/eek-gtk-keyboard.xml"/>
|
||||
<xi:include href="xml/eek-gtk-section.xml"/>
|
||||
<xi:include href="xml/eek-gtk-key.xml"/>
|
||||
</chapter>
|
||||
<chapter id="object-tree">
|
||||
<title>Object Hierarchy</title>
|
||||
<xi:include href="xml/tree_index.sgml"/>
|
||||
|
||||
@ -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 \
|
||||
|
||||
561
eek/eek-clutter-key-actor.c
Normal file
561
eek/eek-clutter-key-actor.c
Normal file
@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include "eek-clutter-key-actor.h"
|
||||
#include "eek-keysym.h"
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-pango.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
60
eek/eek-clutter-key-actor.h
Normal file
60
eek/eek-clutter-key-actor.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <clutter/clutter.h>
|
||||
#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 */
|
||||
@ -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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
ClutterActor *eek_clutter_key_get_actor (EekClutterKey *key);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_CLUTTER_KEY_H */
|
||||
|
||||
@ -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 <string.h>
|
||||
|
||||
#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,
|
||||
eek_clutter_keyboard_real_set_name (EekElement *self,
|
||||
const gchar *name)
|
||||
{
|
||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
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_set_bounds (EekElement *self,
|
||||
EekBounds *bounds)
|
||||
{
|
||||
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_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_get_bounds (EekKeyboard *self,
|
||||
EekBounds *bounds)
|
||||
key_pressed_event (EekSection *section,
|
||||
EekKey *key,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds);
|
||||
g_signal_emit_by_name (keyboard, "key-pressed", key);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_keyboard_real_set_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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_keyboard_real_get_keysym_index (EekKeyboard *self,
|
||||
gint *group,
|
||||
gint *level)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
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))
|
||||
@ -38,7 +38,7 @@ 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);
|
||||
ClutterActor *eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_CLUTTER_KEYBOARD_H */
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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);
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <glib/gtypes.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
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 */
|
||||
@ -20,103 +20,51 @@
|
||||
|
||||
/**
|
||||
* 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 <stdio.h>
|
||||
|
||||
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
|
||||
@ -125,245 +73,106 @@ eek_clutter_section_real_set_angle (EekSection *self,
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
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));
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
ClutterActor *eek_clutter_section_get_actor (EekClutterSection *section);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_CLUTTER_SECTION_H */
|
||||
|
||||
157
eek/eek-container.c
Normal file
157
eek/eek-container.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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);
|
||||
}
|
||||
79
eek/eek-container.h
Normal file
79
eek/eek-container.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
235
eek/eek-element.c
Normal file
235
eek/eek-element.c
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
77
eek/eek-element.h
Normal file
77
eek/eek-element.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <glib-object.h>
|
||||
#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 */
|
||||
@ -1,350 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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);
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <gtk/gtk.h>
|
||||
#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 */
|
||||
@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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);
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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);
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <glib/gtypes.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
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 */
|
||||
@ -1,345 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
@ -1,30 +0,0 @@
|
||||
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
# 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@
|
||||
633
eek/eek-key.c
633
eek/eek-key.c
@ -20,39 +20,339 @@
|
||||
|
||||
/**
|
||||
* 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 <string.h>
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-key.h"
|
||||
#include "eek-keysym.h"
|
||||
|
||||
static void
|
||||
eek_key_base_init (gpointer g_iface)
|
||||
{
|
||||
static gboolean is_initialized = FALSE;
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_KEYCODE,
|
||||
PROP_KEYSYMS,
|
||||
PROP_COLUMN,
|
||||
PROP_ROW,
|
||||
PROP_OUTLINE,
|
||||
PROP_GROUP,
|
||||
PROP_LEVEL,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
if (!is_initialized) {
|
||||
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_real_set_keycode (EekKey *self, guint keycode)
|
||||
{
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
priv->keycode = keycode;
|
||||
}
|
||||
|
||||
static guint
|
||||
eek_key_real_get_keycode (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
return priv->keycode;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
const gchar *name;
|
||||
gint i;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
eek_key_real_get_keysym (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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:
|
||||
@ -64,7 +364,7 @@ eek_key_base_init (gpointer g_iface)
|
||||
"Keycode of the key",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:keysyms:
|
||||
@ -76,7 +376,7 @@ eek_key_base_init (gpointer g_iface)
|
||||
"Symbol matrix of the key",
|
||||
EEK_TYPE_KEYSYM_MATRIX,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class, PROP_KEYSYMS, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:column:
|
||||
@ -88,7 +388,7 @@ eek_key_base_init (gpointer g_iface)
|
||||
"Column index of the key in section",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:row:
|
||||
@ -100,7 +400,7 @@ eek_key_base_init (gpointer g_iface)
|
||||
"Row index of the key in section",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class, PROP_ROW, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:outline:
|
||||
@ -114,19 +414,7 @@ eek_key_base_init (gpointer g_iface)
|
||||
"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);
|
||||
g_object_class_install_property (gobject_class, PROP_OUTLINE, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:group:
|
||||
@ -138,7 +426,7 @@ eek_key_base_init (gpointer g_iface)
|
||||
"Current group of the key",
|
||||
0, 64, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class, PROP_GROUP, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:level:
|
||||
@ -150,278 +438,131 @@ eek_key_base_init (gpointer g_iface)
|
||||
"Current level of the key",
|
||||
0, 3, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class, PROP_LEVEL, pspec);
|
||||
|
||||
is_initialized = TRUE;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
GType
|
||||
eek_key_get_type (void)
|
||||
static void
|
||||
eek_key_init (EekKey *self)
|
||||
{
|
||||
static GType iface_type = 0;
|
||||
EekKeyPrivate *priv;
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -21,24 +21,37 @@
|
||||
#define EEK_KEY_H 1
|
||||
|
||||
#include <glib-object.h>
|
||||
#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,
|
||||
|
||||
@ -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) {
|
||||
g_return_if_fail (EEK_IS_KEY(element));
|
||||
|
||||
ki = user_data;
|
||||
eek_key_set_keysym_index (EEK_KEY(element), ki->group, ki->level);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
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:bounds:
|
||||
* EekKeyboard:group:
|
||||
*
|
||||
* The bounding box of #EekKeyboard.
|
||||
* The group (row) index of symbol matrix of #EekKeyboard.
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("bounds",
|
||||
"Bounds",
|
||||
"Bounding box of the keyboard",
|
||||
EEK_TYPE_BOUNDS,
|
||||
pspec = g_param_spec_int ("group",
|
||||
"Group",
|
||||
"Group index of symbol matrix of the keyboard",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_GROUP,
|
||||
pspec);
|
||||
|
||||
is_initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
eek_keyboard_get_type (void)
|
||||
{
|
||||
static GType iface_type = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
return iface_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_set_bounds:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @bounds: bounding box of the keyboard
|
||||
/**
|
||||
* EekKeyboard:level:
|
||||
*
|
||||
* Set the bounding box of @keyboard to @bounds.
|
||||
* The level (row) index of symbol matrix of #EekKeyboard.
|
||||
*/
|
||||
void
|
||||
eek_keyboard_set_bounds (EekKeyboard *keyboard,
|
||||
EekBounds *bounds)
|
||||
{
|
||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard);
|
||||
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);
|
||||
|
||||
g_return_if_fail (iface);
|
||||
g_return_if_fail (iface->set_bounds);
|
||||
(*iface->set_bounds) (keyboard, bounds);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -20,42 +20,45 @@
|
||||
#ifndef EEK_KEYBOARD_H
|
||||
#define EEK_KEYBOARD_H 1
|
||||
|
||||
#include "eek-section.h"
|
||||
#include <glib-object.h>
|
||||
#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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
struct _EekLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (*apply_to_keyboard) (EekLayout *self,
|
||||
void (*apply) (EekLayout *self,
|
||||
EekKeyboard *keyboard);
|
||||
};
|
||||
|
||||
GType eek_layout_get_type (void) G_GNUC_CONST;
|
||||
void eek_layout_apply (EekLayout *layout,
|
||||
EekKeyboard *keyboard);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_LAYOUT_H */
|
||||
|
||||
@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
|
||||
*
|
||||
* 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 <math.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <glib/gtypes.h>
|
||||
#include <cairo/cairo.h>
|
||||
#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 */
|
||||
@ -20,66 +20,227 @@
|
||||
|
||||
/**
|
||||
* 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 <string.h>
|
||||
|
||||
#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) {
|
||||
priv->angle = angle;
|
||||
|
||||
g_object_notify (G_OBJECT(self), "angle");
|
||||
}
|
||||
|
||||
static gint
|
||||
eek_section_real_get_angle (EekSection *self)
|
||||
{
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
|
||||
return priv->angle;
|
||||
}
|
||||
|
||||
static gint
|
||||
eek_section_real_get_n_rows (EekSection *self)
|
||||
{
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
|
||||
return g_slist_length (priv->rows);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_class_init (EekSectionClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
/**
|
||||
* 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_type_class_add_private (gobject_class, sizeof (EekSectionPrivate));
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
gobject_class->set_property = eek_section_set_property;
|
||||
gobject_class->get_property = eek_section_get_property;
|
||||
gobject_class->finalize = eek_section_finalize;
|
||||
|
||||
/**
|
||||
* EekSection:angle:
|
||||
@ -91,279 +252,97 @@ eek_section_base_init (gpointer g_iface)
|
||||
"Rotation angle of the section",
|
||||
-360, 360, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_interface_install_property (g_iface, pspec);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ANGLE,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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);
|
||||
|
||||
is_initialized = TRUE;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
GType
|
||||
eek_section_get_type (void)
|
||||
static void
|
||||
eek_section_init (EekSection *self)
|
||||
{
|
||||
static GType iface_type = 0;
|
||||
EekSectionPrivate *priv;
|
||||
|
||||
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);
|
||||
}
|
||||
return iface_type;
|
||||
priv = self->priv = EEK_SECTION_GET_PRIVATE (self);
|
||||
priv->angle = 0;
|
||||
priv->rows = NULL;
|
||||
priv->keys = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_set_rows:
|
||||
* @section: an #EekSection
|
||||
* @rows: the number of rows in @section
|
||||
*
|
||||
* Set the number of rows in @section to @rows.
|
||||
*/
|
||||
void
|
||||
eek_section_set_rows (EekSection *section,
|
||||
gint rows)
|
||||
{
|
||||
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
|
||||
|
||||
g_return_if_fail (iface->set_rows);
|
||||
(*iface->set_rows) (section, rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
g_return_if_fail (EEK_IS_SECTION(section));
|
||||
EEK_SECTION_GET_CLASS(section)->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);
|
||||
}
|
||||
|
||||
@ -20,102 +20,72 @@
|
||||
#ifndef EEK_SECTION_H
|
||||
#define EEK_SECTION_H 1
|
||||
|
||||
#include "eek-key.h"
|
||||
#include <glib-object.h>
|
||||
#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;
|
||||
|
||||
EekSectionPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekSectionClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekContainerClass parent_class;
|
||||
|
||||
/*< 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);
|
||||
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);
|
||||
|
||||
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);
|
||||
gint column);
|
||||
};
|
||||
|
||||
GType eek_section_get_type (void) G_GNUC_CONST;
|
||||
|
||||
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);
|
||||
|
||||
void eek_section_set_angle (EekSection *section,
|
||||
gint angle);
|
||||
gint eek_section_get_angle (EekSection *section);
|
||||
|
||||
void eek_section_set_bounds (EekSection *section,
|
||||
EekBounds *bounds);
|
||||
void eek_section_get_bounds (EekSection *section,
|
||||
EekBounds *bounds);
|
||||
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,
|
||||
const gchar *name,
|
||||
guint keycode,
|
||||
guint *keysyms,
|
||||
gint num_groups,
|
||||
gint num_levels,
|
||||
gint column,
|
||||
gint row,
|
||||
EekOutline *outline,
|
||||
EekBounds *bounds);
|
||||
|
||||
void eek_section_foreach_key (EekSection *section,
|
||||
GFunc func,
|
||||
gpointer user_data);
|
||||
gint row);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_SECTION_H */
|
||||
|
||||
@ -1,439 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <string.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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);
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
@ -1,352 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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 */
|
||||
@ -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 */
|
||||
|
||||
@ -30,6 +30,8 @@ typedef enum {
|
||||
EEK_ORIENTATION_INVALID = -1
|
||||
} EekOrientation;
|
||||
|
||||
typedef struct _EekKey EekKey;
|
||||
typedef struct _EekSection EekSection;
|
||||
typedef struct _EekKeyboard EekKeyboard;
|
||||
|
||||
/**
|
||||
|
||||
@ -37,10 +37,17 @@
|
||||
#include <string.h>
|
||||
#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,22 +233,21 @@ create_section (EekXkbLayout *layout,
|
||||
priv = layout->priv;
|
||||
xkbgeometry = priv->xkb->geom;
|
||||
name = XGetAtomName (priv->display, xkbsection->name);
|
||||
section = eek_keyboard_create_section (keyboard,
|
||||
name,
|
||||
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,
|
||||
&bounds);
|
||||
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,
|
||||
eek_section_add_row (section,
|
||||
xkbrow->num_keys,
|
||||
xkbrow->vertical ?
|
||||
EEK_ORIENTATION_VERTICAL :
|
||||
EEK_ORIENTATION_HORIZONTAL);
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
|
||||
@ -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
|
||||
@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user