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. */
|
10: /* Apply the layout to the keyboard. */
|
||||||
11: eek_keyboard_set_layout (keyboard, layout);
|
11: eek_keyboard_set_layout (keyboard, layout);
|
||||||
12:
|
12:
|
||||||
13: clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard));
|
13: clutter_group_add (CLUTTER_GROUP(stage),
|
||||||
|
14: eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(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));
|
|
||||||
|
|
||||||
Footnotes:
|
Footnotes:
|
||||||
[1] http://en.wikipedia.org/wiki/Builder_pattern
|
[1] http://en.wikipedia.org/wiki/Builder_pattern
|
||||||
|
|||||||
@ -56,6 +56,5 @@ docs/reference/Makefile
|
|||||||
docs/reference/eek/Makefile
|
docs/reference/eek/Makefile
|
||||||
eek/eek.pc
|
eek/eek.pc
|
||||||
eek/eek-clutter.pc
|
eek/eek-clutter.pc
|
||||||
eek/eek-xkb.pc
|
eek/eek-xkb.pc])
|
||||||
eek/eek-gtk.pc])
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|||||||
@ -77,8 +77,7 @@ EXTRA_HFILES=
|
|||||||
# Header files to ignore when scanning. Use base file name, no paths
|
# Header files to ignore when scanning. Use base file name, no paths
|
||||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
|
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
|
||||||
IGNORE_HFILES= eek-private.h \
|
IGNORE_HFILES= eek-private.h \
|
||||||
eek-clutter-private.h \
|
eek-keysym.h \
|
||||||
eek-keysyms.h \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# Images to copy into HTML directory.
|
# Images to copy into HTML directory.
|
||||||
@ -103,7 +102,6 @@ GTKDOC_CFLAGS = $(GOBJECT2_CFLAGS)
|
|||||||
GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \
|
GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \
|
||||||
$(top_srcdir)/eek/libeek-clutter.la \
|
$(top_srcdir)/eek/libeek-clutter.la \
|
||||||
$(top_srcdir)/eek/libeek-xkb.la \
|
$(top_srcdir)/eek/libeek-xkb.la \
|
||||||
$(top_srcdir)/eek/libeek-gtk.la \
|
|
||||||
$(GOBJECT2_LIBS) \
|
$(GOBJECT2_LIBS) \
|
||||||
$(CLUTTER_LIBS) \
|
$(CLUTTER_LIBS) \
|
||||||
$(XKB_LIBS) \
|
$(XKB_LIBS) \
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
<chapter>
|
<chapter>
|
||||||
<title>Base classes and interfaces</title>
|
<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-keyboard.xml"/>
|
||||||
<xi:include href="xml/eek-section.xml"/>
|
<xi:include href="xml/eek-section.xml"/>
|
||||||
<xi:include href="xml/eek-key.xml"/>
|
<xi:include href="xml/eek-key.xml"/>
|
||||||
@ -30,12 +32,6 @@
|
|||||||
<title>XKB layout engine</title>
|
<title>XKB layout engine</title>
|
||||||
<xi:include href="xml/eek-xkb-layout.xml"/>
|
<xi:include href="xml/eek-xkb-layout.xml"/>
|
||||||
</chapter>
|
</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">
|
<chapter id="object-tree">
|
||||||
<title>Object Hierarchy</title>
|
<title>Object Hierarchy</title>
|
||||||
<xi:include href="xml/tree_index.sgml"/>
|
<xi:include href="xml/tree_index.sgml"/>
|
||||||
|
|||||||
@ -16,25 +16,21 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
# 02110-1301 USA
|
# 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 = \
|
libeek_la_SOURCES = \
|
||||||
eek-layout.c \
|
eek-layout.c \
|
||||||
eek-layout.h \
|
eek-layout.h \
|
||||||
|
eek-element.c \
|
||||||
|
eek-element.h \
|
||||||
|
eek-container.c \
|
||||||
|
eek-container.h \
|
||||||
eek-keyboard.c \
|
eek-keyboard.c \
|
||||||
eek-keyboard.h \
|
eek-keyboard.h \
|
||||||
eek-section.c \
|
eek-section.c \
|
||||||
eek-section.h \
|
eek-section.h \
|
||||||
eek-key.c \
|
eek-key.c \
|
||||||
eek-key.h \
|
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.h \
|
||||||
eek-types.c \
|
eek-types.c \
|
||||||
eek-keysym.h \
|
eek-keysym.h \
|
||||||
@ -54,8 +50,8 @@ libeek_clutter_la_SOURCES = \
|
|||||||
eek-clutter-section.h \
|
eek-clutter-section.h \
|
||||||
eek-clutter-key.c \
|
eek-clutter-key.c \
|
||||||
eek-clutter-key.h \
|
eek-clutter-key.h \
|
||||||
eek-clutter-private.c \
|
eek-clutter-key-actor.c \
|
||||||
eek-clutter-private.h \
|
eek-clutter-key-actor.h \
|
||||||
eek-clutter.h \
|
eek-clutter.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
@ -70,23 +66,10 @@ libeek_xkb_la_SOURCES = \
|
|||||||
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS)
|
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS)
|
||||||
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS)
|
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
|
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
|
||||||
eek_HEADERS = \
|
eek_HEADERS = \
|
||||||
|
$(top_srcdir)/eek/eek-element.h \
|
||||||
|
$(top_srcdir)/eek/eek-container.h \
|
||||||
$(top_srcdir)/eek/eek-keyboard.h \
|
$(top_srcdir)/eek/eek-keyboard.h \
|
||||||
$(top_srcdir)/eek/eek-section.h \
|
$(top_srcdir)/eek/eek-section.h \
|
||||||
$(top_srcdir)/eek/eek-key.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 < $< > $@
|
$(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
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 = \
|
DISTCLEANFILES = \
|
||||||
eek-special-keysym-labels.h \
|
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
|
* SECTION:eek-clutter-key
|
||||||
* @short_description: #EekKey implemented as a #ClutterActor
|
* @short_description: #EekKey embedding a #ClutterActor
|
||||||
*
|
|
||||||
* The #EekClutterKey class implements the #EekKeyIface interface as a
|
|
||||||
* #ClutterActor.
|
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-clutter-key.h"
|
#include "eek-clutter-key.h"
|
||||||
#include "eek-simple-key.h"
|
#include "eek-clutter-key-actor.h"
|
||||||
#include "eek-keysym.h"
|
|
||||||
|
|
||||||
enum {
|
G_DEFINE_TYPE (EekClutterKey, eek_clutter_key, EEK_TYPE_KEY);
|
||||||
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));
|
|
||||||
|
|
||||||
#define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \
|
#define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate))
|
||||||
|
|
||||||
struct _EekClutterKeyPrivate
|
struct _EekClutterKeyPrivate
|
||||||
{
|
{
|
||||||
EekSimpleKey *simple;
|
ClutterActor *actor;
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint
|
static void
|
||||||
eek_clutter_key_real_get_keycode (EekKey *self)
|
eek_clutter_key_real_set_name (EekElement *self,
|
||||||
|
const gchar *name)
|
||||||
{
|
{
|
||||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
|
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_val_if_fail (priv, EEK_INVALID_KEYCODE);
|
EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)->
|
||||||
return eek_key_get_keycode (EEK_KEY(priv->simple));
|
set_name (self, name);
|
||||||
|
|
||||||
|
g_return_if_fail (priv->actor);
|
||||||
|
|
||||||
|
clutter_actor_set_name (CLUTTER_ACTOR(priv->actor), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_key_real_set_keysyms (EekKey *self,
|
eek_clutter_key_real_set_bounds (EekElement *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,
|
|
||||||
EekBounds *bounds)
|
EekBounds *bounds)
|
||||||
{
|
{
|
||||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
|
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)->
|
||||||
return eek_key_get_bounds (EEK_KEY(priv->simple), bounds);
|
set_bounds (self, bounds);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
g_return_if_fail (priv->actor);
|
||||||
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);
|
clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
|
||||||
eek_key_set_keysym_index (EEK_KEY(priv->simple), group, level);
|
clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -226,358 +73,40 @@ eek_clutter_key_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(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);
|
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
|
static void
|
||||||
eek_clutter_key_class_init (EekClutterKeyClass *klass)
|
eek_clutter_key_class_init (EekClutterKeyClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class,
|
g_type_class_add_private (gobject_class,
|
||||||
sizeof (EekClutterKeyPrivate));
|
sizeof (EekClutterKeyPrivate));
|
||||||
|
|
||||||
actor_class->paint = eek_clutter_key_paint;
|
element_class->set_name = eek_clutter_key_real_set_name;
|
||||||
/* FIXME: This is a workaround for the bug
|
element_class->set_bounds = eek_clutter_key_real_set_bounds;
|
||||||
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
|
gobject_class->finalize = eek_clutter_key_finalize;
|
||||||
* says this is not a right way to solve the original problem.
|
|
||||||
*/
|
|
||||||
actor_class->get_preferred_width = eek_clutter_key_get_preferred_width;
|
|
||||||
|
|
||||||
gobject_class->set_property = eek_clutter_key_set_property;
|
|
||||||
gobject_class->get_property = eek_clutter_key_get_property;
|
|
||||||
gobject_class->finalize = eek_clutter_key_finalize;
|
|
||||||
gobject_class->dispose = eek_clutter_key_dispose;
|
|
||||||
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_KEYCODE,
|
|
||||||
"keycode");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_KEYSYMS,
|
|
||||||
"keysyms");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_COLUMN,
|
|
||||||
"column");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_ROW,
|
|
||||||
"row");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_OUTLINE,
|
|
||||||
"outline");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_BOUNDS,
|
|
||||||
"bounds");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_GROUP,
|
|
||||||
"group");
|
|
||||||
g_object_class_override_property (gobject_class,
|
|
||||||
PROP_LEVEL,
|
|
||||||
"level");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_key_animate_complete (ClutterAnimation *animation,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterActor *actor = (ClutterActor*)user_data;
|
|
||||||
|
|
||||||
/* reset after effect */
|
|
||||||
clutter_actor_set_opacity (actor, 0xff);
|
|
||||||
clutter_actor_set_scale (actor, 1.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
key_enlarge (ClutterActor *actor)
|
|
||||||
{
|
|
||||||
clutter_actor_set_scale (actor, 1.0, 1.0);
|
|
||||||
clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150,
|
|
||||||
"scale-x", 1.5,
|
|
||||||
"scale-y", 1.5,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
key_shrink (ClutterActor *actor)
|
|
||||||
{
|
|
||||||
clutter_actor_set_scale (actor, 1.5, 1.5);
|
|
||||||
clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150,
|
|
||||||
"scale-x", 1.0,
|
|
||||||
"scale-y", 1.0,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
on_event (ClutterActor *actor,
|
|
||||||
ClutterEvent *event,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEY(actor), FALSE);
|
|
||||||
if (clutter_event_get_source (event) == actor) {
|
|
||||||
ClutterActor *section;
|
|
||||||
|
|
||||||
/* Make sure the enlarged key show up on the keys which belong
|
|
||||||
to other sections. */
|
|
||||||
section = clutter_actor_get_parent (actor);
|
|
||||||
clutter_actor_raise_top (section);
|
|
||||||
clutter_actor_raise_top (actor);
|
|
||||||
if (event->type == CLUTTER_BUTTON_PRESS)
|
|
||||||
key_enlarge (actor);
|
|
||||||
else if (event->type == CLUTTER_BUTTON_RELEASE)
|
|
||||||
key_shrink (actor);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_key_init (EekClutterKey *self)
|
eek_clutter_key_init (EekClutterKey *self)
|
||||||
{
|
{
|
||||||
EekClutterKeyPrivate *priv;
|
EekClutterKeyPrivate *priv;
|
||||||
|
priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE (self);
|
||||||
priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
|
priv->actor = NULL;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
eek_clutter_key_create_texture (EekClutterKey *key)
|
eek_clutter_key_get_actor (EekClutterKey *key)
|
||||||
{
|
{
|
||||||
EekOutline *outline;
|
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
|
||||||
EekBounds bounds;
|
if (!priv->actor)
|
||||||
ClutterActor *texture;
|
priv->actor = eek_clutter_key_actor_new (EEK_KEY(key));
|
||||||
cairo_t *cr;
|
return priv->actor;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ typedef struct _EekClutterKeyPrivate EekClutterKeyPrivate;
|
|||||||
struct _EekClutterKey
|
struct _EekClutterKey
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
ClutterGroup parent;
|
EekKey parent;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
EekClutterKeyPrivate *priv;
|
EekClutterKeyPrivate *priv;
|
||||||
@ -47,14 +47,11 @@ struct _EekClutterKey
|
|||||||
struct _EekClutterKeyClass
|
struct _EekClutterKeyClass
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
ClutterGroupClass parent_class;
|
EekKeyClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_clutter_key_get_type (void) G_GNUC_CONST;
|
GType eek_clutter_key_get_type (void) G_GNUC_CONST;
|
||||||
|
ClutterActor *eek_clutter_key_get_actor (EekClutterKey *key);
|
||||||
ClutterActor *eek_clutter_key_create_texture (EekClutterKey *key);
|
|
||||||
void eek_clutter_key_set_texture (EekClutterKey *key,
|
|
||||||
ClutterActor *texture);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_CLUTTER_KEY_H */
|
#endif /* EEK_CLUTTER_KEY_H */
|
||||||
|
|||||||
@ -20,31 +20,18 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:eek-clutter-keyboard
|
* SECTION:eek-clutter-keyboard
|
||||||
* @short_description: #EekKeyboard implemented as a #ClutterActor
|
* @short_description: #EekKeyboard embedding a #ClutterActor
|
||||||
*
|
|
||||||
* The #EekClutterKeyboard class implements the #EekKeyboardIface
|
|
||||||
* interface as a #ClutterActor.
|
|
||||||
*/
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-clutter-keyboard.h"
|
#include "eek-clutter-keyboard.h"
|
||||||
#include "eek-clutter-private.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-simple-keyboard.h"
|
|
||||||
|
|
||||||
enum {
|
G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, EEK_TYPE_KEYBOARD);
|
||||||
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));
|
|
||||||
|
|
||||||
#define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \
|
#define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate))
|
(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
|
struct _EekClutterKeyboardPrivate
|
||||||
{
|
{
|
||||||
EekSimpleKeyboard *simple;
|
ClutterActor *actor;
|
||||||
gint group;
|
|
||||||
gint level;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_keyboard_real_set_bounds (EekKeyboard *self,
|
eek_clutter_keyboard_real_set_name (EekElement *self,
|
||||||
EekBounds *bounds)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
|
||||||
eek_keyboard_set_bounds (EEK_KEYBOARD(priv->simple), bounds);
|
set_name (self, name);
|
||||||
clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y);
|
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->width, bounds->height);
|
g_return_if_fail (priv->actor);
|
||||||
|
|
||||||
|
clutter_actor_set_name (priv->actor, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_keyboard_real_get_bounds (EekKeyboard *self,
|
eek_clutter_keyboard_real_set_bounds (EekElement *self,
|
||||||
EekBounds *bounds)
|
EekBounds *bounds)
|
||||||
{
|
{
|
||||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
|
||||||
return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds);
|
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
|
static void
|
||||||
eek_clutter_keyboard_real_set_keysym_index (EekKeyboard *self,
|
key_pressed_event (EekSection *section,
|
||||||
gint group,
|
EekKey *key,
|
||||||
gint level)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
g_signal_emit_by_name (keyboard, "key-pressed", key);
|
||||||
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
|
static void
|
||||||
eek_clutter_keyboard_real_get_keysym_index (EekKeyboard *self,
|
key_released_event (EekSection *section,
|
||||||
gint *group,
|
EekKey *key,
|
||||||
gint *level)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
g_signal_emit_by_name (keyboard, "key-released", key);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
|
||||||
*group = priv->group;
|
|
||||||
*level = priv->level;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static EekSection *
|
static EekSection *
|
||||||
eek_clutter_keyboard_real_create_section (EekKeyboard *self,
|
eek_clutter_keyboard_real_create_section (EekKeyboard *self)
|
||||||
const gchar *name,
|
|
||||||
gint angle,
|
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekSection *section;
|
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,
|
g_signal_connect (section, "key-pressed", G_CALLBACK(key_pressed_event), self);
|
||||||
"name", name,
|
g_signal_connect (section, "key-released", G_CALLBACK(key_released_event), self);
|
||||||
"angle", angle,
|
|
||||||
"bounds", bounds,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER(self),
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
CLUTTER_ACTOR(section));
|
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;
|
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
|
static void
|
||||||
eek_clutter_keyboard_finalize (GObject *object)
|
eek_clutter_keyboard_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(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);
|
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
|
static void
|
||||||
eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass)
|
eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
EekKeyboardClass *keyboard_class = EEK_KEYBOARD_CLASS (klass);
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class,
|
g_type_class_add_private (gobject_class,
|
||||||
sizeof (EekClutterKeyboardPrivate));
|
sizeof (EekClutterKeyboardPrivate));
|
||||||
|
|
||||||
gobject_class->set_property = eek_clutter_keyboard_set_property;
|
keyboard_class->create_section = eek_clutter_keyboard_real_create_section;
|
||||||
gobject_class->get_property = eek_clutter_keyboard_get_property;
|
element_class->set_name = eek_clutter_keyboard_real_set_name;
|
||||||
gobject_class->finalize = eek_clutter_keyboard_finalize;
|
element_class->set_bounds = eek_clutter_keyboard_real_set_bounds;
|
||||||
gobject_class->dispose = eek_clutter_keyboard_dispose;
|
gobject_class->finalize = eek_clutter_keyboard_finalize;
|
||||||
|
|
||||||
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
|
static void
|
||||||
@ -308,11 +145,7 @@ eek_clutter_keyboard_init (EekClutterKeyboard *self)
|
|||||||
EekClutterKeyboardPrivate *priv;
|
EekClutterKeyboardPrivate *priv;
|
||||||
|
|
||||||
priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||||
priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL);
|
priv->actor = NULL;
|
||||||
priv->group = priv->level = 0;
|
|
||||||
|
|
||||||
clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE);
|
|
||||||
g_signal_connect (self, "event", G_CALLBACK(on_event), self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -326,10 +159,28 @@ EekKeyboard*
|
|||||||
eek_clutter_keyboard_new (gfloat width,
|
eek_clutter_keyboard_new (gfloat width,
|
||||||
gfloat height)
|
gfloat height)
|
||||||
{
|
{
|
||||||
|
EekKeyboard *keyboard;
|
||||||
EekBounds bounds;
|
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.width = width;
|
||||||
bounds.height = height;
|
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,20 +25,20 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
#define EEK_TYPE_CLUTTER_KEYBOARD (eek_clutter_keyboard_get_type())
|
#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_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(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEYBOARD))
|
||||||
#define EEK_IS_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEYBOARD))
|
#define EEK_IS_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEYBOARD))
|
||||||
#define EEK_CLUTTER_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass))
|
#define EEK_CLUTTER_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass))
|
||||||
|
|
||||||
typedef struct _EekClutterKeyboard EekClutterKeyboard;
|
typedef struct _EekClutterKeyboard EekClutterKeyboard;
|
||||||
typedef struct _EekClutterKeyboardClass EekClutterKeyboardClass;
|
typedef struct _EekClutterKeyboardClass EekClutterKeyboardClass;
|
||||||
typedef struct _EekClutterKeyboardPrivate EekClutterKeyboardPrivate;
|
typedef struct _EekClutterKeyboardPrivate EekClutterKeyboardPrivate;
|
||||||
|
|
||||||
struct _EekClutterKeyboard
|
struct _EekClutterKeyboard
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
ClutterGroup parent;
|
EekKeyboard parent;
|
||||||
|
|
||||||
EekClutterKeyboardPrivate *priv;
|
EekClutterKeyboardPrivate *priv;
|
||||||
};
|
};
|
||||||
@ -46,13 +46,13 @@ struct _EekClutterKeyboard
|
|||||||
struct _EekClutterKeyboardClass
|
struct _EekClutterKeyboardClass
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
ClutterGroupClass parent_class;
|
EekKeyboardClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST;
|
GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST;
|
||||||
|
EekKeyboard *eek_clutter_keyboard_new (gfloat width,
|
||||||
EekKeyboard *eek_clutter_keyboard_new (gfloat width,
|
gfloat height);
|
||||||
gfloat height);
|
ClutterActor *eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_CLUTTER_KEYBOARD_H */
|
#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,350 +20,159 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:eek-clutter-section
|
* SECTION:eek-clutter-section
|
||||||
* @short_description: #EekSection implemented as a #ClutterActor
|
* @short_description: #EekSection embedding a #ClutterActor
|
||||||
*
|
|
||||||
* The #EekClutterSection class implements the #EekSectionIface
|
|
||||||
* interface as a #ClutterActor.
|
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-clutter-section.h"
|
#include "eek-clutter-section.h"
|
||||||
#include "eek-clutter-private.h"
|
|
||||||
#include "eek-simple-section.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
enum {
|
G_DEFINE_TYPE (EekClutterSection, eek_clutter_section, EEK_TYPE_SECTION);
|
||||||
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));
|
|
||||||
|
|
||||||
#define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \
|
#define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate))
|
||||||
|
|
||||||
struct _EekClutterSectionPrivate
|
struct _EekClutterSectionPrivate
|
||||||
{
|
{
|
||||||
EekSimpleSection *simple;
|
ClutterActor *actor;
|
||||||
GHashTable *key_outline_texture_hash; /* outline pointer -> texture */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_section_real_set_rows (EekSection *self,
|
eek_clutter_section_real_set_name (EekElement *self,
|
||||||
gint rows)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)->
|
||||||
eek_section_set_rows (EEK_SECTION(priv->simple), rows);
|
set_name (self, name);
|
||||||
}
|
|
||||||
|
|
||||||
static gint
|
g_return_if_fail (priv->actor);
|
||||||
eek_clutter_section_real_get_rows (EekSection *self)
|
|
||||||
{
|
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
|
||||||
|
|
||||||
g_return_val_if_fail (priv, -1);
|
clutter_actor_set_name (priv->actor, name);
|
||||||
return eek_section_get_rows (EEK_SECTION(priv->simple));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_section_real_set_columns (EekSection *self,
|
eek_clutter_section_real_set_bounds (EekElement *self,
|
||||||
gint row,
|
EekBounds *bounds)
|
||||||
gint columns)
|
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)->
|
||||||
eek_section_set_columns (EEK_SECTION(priv->simple), row, columns);
|
set_bounds (self, bounds);
|
||||||
}
|
|
||||||
|
|
||||||
static gint
|
g_return_if_fail (priv->actor);
|
||||||
eek_clutter_section_real_get_columns (EekSection *self,
|
|
||||||
gint row)
|
|
||||||
{
|
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
|
||||||
|
|
||||||
g_return_val_if_fail (priv, -1);
|
clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
|
||||||
return eek_section_get_columns (EEK_SECTION(priv->simple), row);
|
clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_section_real_set_angle (EekSection *self,
|
eek_clutter_section_real_set_angle (EekSection *self,
|
||||||
gint angle)
|
gint angle)
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
EEK_SECTION_CLASS (eek_clutter_section_parent_class)->
|
||||||
eek_section_set_angle (EEK_SECTION(priv->simple), angle);
|
set_angle (self, angle);
|
||||||
clutter_actor_set_rotation (CLUTTER_ACTOR(self),
|
|
||||||
|
g_return_if_fail (priv->actor);
|
||||||
|
|
||||||
|
clutter_actor_set_rotation (priv->actor,
|
||||||
CLUTTER_Z_AXIS,
|
CLUTTER_Z_AXIS,
|
||||||
angle,
|
eek_section_get_angle (self),
|
||||||
0,
|
0, 0, 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_section_real_set_bounds (EekSection *self,
|
pressed_event (EekKey *key, gpointer user_data)
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
g_signal_emit_by_name (user_data, "key-pressed", key);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_clutter_section_real_get_bounds (EekSection *self,
|
released_event (EekKey *key, gpointer user_data)
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
g_signal_emit_by_name (user_data, "key-released", key);
|
||||||
|
|
||||||
g_return_if_fail (priv);
|
|
||||||
return eek_section_get_bounds (EEK_SECTION(priv->simple), bounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static EekKey *
|
static EekKey *
|
||||||
eek_clutter_section_real_create_key (EekSection *self,
|
eek_clutter_section_real_create_key (EekSection *self,
|
||||||
const gchar *name,
|
|
||||||
guint keycode,
|
|
||||||
guint *keysyms,
|
|
||||||
gint num_groups,
|
|
||||||
gint num_levels,
|
|
||||||
gint column,
|
gint column,
|
||||||
gint row,
|
gint row)
|
||||||
EekOutline *outline,
|
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
|
|
||||||
EekKey *key;
|
EekKey *key;
|
||||||
EekKeysymMatrix matrix;
|
gint num_columns, num_rows;
|
||||||
gint columns, rows;
|
EekOrientation orientation;
|
||||||
ClutterActor *texture;
|
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,
|
key = g_object_new (EEK_TYPE_CLUTTER_KEY,
|
||||||
"name", name,
|
|
||||||
"keycode", keycode,
|
|
||||||
"keysyms", &matrix,
|
|
||||||
"column", column,
|
"column", column,
|
||||||
"row", row,
|
"row", row,
|
||||||
"outline", outline,
|
|
||||||
"bounds", bounds,
|
|
||||||
NULL);
|
NULL);
|
||||||
g_return_val_if_fail (key, NULL);
|
g_return_val_if_fail (key, NULL);
|
||||||
|
g_object_ref_sink (key);
|
||||||
|
|
||||||
texture = g_hash_table_lookup (priv->key_outline_texture_hash, outline);
|
g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self);
|
||||||
if (texture == NULL) {
|
g_signal_connect (key, "released", G_CALLBACK(released_event), self);
|
||||||
texture = eek_clutter_key_create_texture (EEK_CLUTTER_KEY(key));
|
|
||||||
g_hash_table_insert (priv->key_outline_texture_hash, outline, texture);
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
} else
|
EEK_ELEMENT(key));
|
||||||
texture = clutter_clone_new (texture);
|
|
||||||
|
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;
|
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
|
static void
|
||||||
eek_clutter_section_finalize (GObject *object)
|
eek_clutter_section_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(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);
|
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
|
static void
|
||||||
eek_clutter_section_class_init (EekClutterSectionClass *klass)
|
eek_clutter_section_class_init (EekClutterSectionClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
EekSectionClass *section_class = EEK_SECTION_CLASS (klass);
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate));
|
g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate));
|
||||||
|
|
||||||
gobject_class->set_property = eek_clutter_section_set_property;
|
section_class->set_angle = eek_clutter_section_real_set_angle;
|
||||||
gobject_class->get_property = eek_clutter_section_get_property;
|
section_class->create_key = eek_clutter_section_real_create_key;
|
||||||
gobject_class->finalize = eek_clutter_section_finalize;
|
element_class->set_name = eek_clutter_section_real_set_name;
|
||||||
gobject_class->dispose = eek_clutter_section_dispose;
|
element_class->set_bounds = eek_clutter_section_real_set_bounds;
|
||||||
|
gobject_class->finalize = eek_clutter_section_finalize;
|
||||||
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
|
static void
|
||||||
eek_clutter_section_init (EekClutterSection *self)
|
eek_clutter_section_init (EekClutterSection *self)
|
||||||
{
|
{
|
||||||
EekClutterSectionPrivate *priv;
|
EekClutterSectionPrivate *priv;
|
||||||
|
|
||||||
priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self);
|
priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self);
|
||||||
priv->simple = g_object_new (EEK_TYPE_SIMPLE_SECTION, NULL);
|
priv->actor = NULL;
|
||||||
priv->key_outline_texture_hash =
|
}
|
||||||
g_hash_table_new_full (g_direct_hash,
|
|
||||||
g_direct_equal,
|
ClutterActor *
|
||||||
NULL,
|
eek_clutter_section_get_actor (EekClutterSection *section)
|
||||||
g_free);
|
{
|
||||||
|
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
|
struct _EekClutterSection
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
ClutterGroup parent;
|
EekSection parent;
|
||||||
|
|
||||||
/*< private >*/
|
|
||||||
EekClutterSectionPrivate *priv;
|
EekClutterSectionPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EekClutterSectionClass
|
struct _EekClutterSectionClass
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
ClutterGroupClass parent_class;
|
EekSectionClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_clutter_section_get_type (void) G_GNUC_CONST;
|
GType eek_clutter_section_get_type (void) G_GNUC_CONST;
|
||||||
|
ClutterActor *eek_clutter_section_get_actor (EekClutterSection *section);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_CLUTTER_SECTION_H */
|
#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@
|
|
||||||
795
eek/eek-key.c
795
eek/eek-key.c
@ -20,408 +20,549 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:eek-key
|
* SECTION:eek-key
|
||||||
* @short_description: Base interface of a key
|
* @short_description: Base class of a key
|
||||||
* @see_also: #EekSection
|
|
||||||
*
|
*
|
||||||
* The #EekKeyIface interface represents a key, which is parented to
|
* The #EekKeyClass class represents a key.
|
||||||
* #EekSectionIface.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#define DEBUG 0
|
||||||
|
#if DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_KEYCODE,
|
||||||
|
PROP_KEYSYMS,
|
||||||
|
PROP_COLUMN,
|
||||||
|
PROP_ROW,
|
||||||
|
PROP_OUTLINE,
|
||||||
|
PROP_GROUP,
|
||||||
|
PROP_LEVEL,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PRESSED,
|
||||||
|
RELEASED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
#define EEK_KEY_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate))
|
||||||
|
|
||||||
|
|
||||||
|
struct _EekKeyPrivate
|
||||||
|
{
|
||||||
|
guint keycode;
|
||||||
|
EekKeysymMatrix keysyms;
|
||||||
|
gint column;
|
||||||
|
gint row;
|
||||||
|
EekOutline *outline;
|
||||||
|
gint group;
|
||||||
|
gint level;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_key_base_init (gpointer g_iface)
|
eek_key_real_set_keycode (EekKey *self, guint keycode)
|
||||||
{
|
{
|
||||||
static gboolean is_initialized = FALSE;
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
priv->keycode = keycode;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_initialized) {
|
static guint
|
||||||
GParamSpec *pspec;
|
eek_key_real_get_keycode (EekKey *self)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
return priv->keycode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* EekKey:name:
|
eek_key_real_set_keysyms (EekKey *self,
|
||||||
*
|
guint *keysyms,
|
||||||
* The name of #EekKey.
|
gint num_groups,
|
||||||
*/
|
gint num_levels)
|
||||||
pspec = g_param_spec_string ("name",
|
{
|
||||||
"Name",
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
"Name",
|
gint num_keysyms = num_groups * num_levels;
|
||||||
NULL,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
if (num_keysyms > 0) {
|
||||||
* EekKey:keycode:
|
priv->keysyms.data =
|
||||||
*
|
g_slice_alloc (num_keysyms * sizeof(guint));
|
||||||
* The keycode of #EekKey.
|
memcpy (priv->keysyms.data, keysyms,
|
||||||
*/
|
num_keysyms * sizeof(guint));
|
||||||
pspec = g_param_spec_uint ("keycode",
|
}
|
||||||
"Keycode",
|
priv->keysyms.num_groups = num_groups;
|
||||||
"Keycode of the key",
|
priv->keysyms.num_levels = num_levels;
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
#if DEBUG
|
||||||
* EekKey:keysyms:
|
{
|
||||||
*
|
const gchar *name;
|
||||||
* The symbol matrix of #EekKey.
|
gint i;
|
||||||
*/
|
|
||||||
pspec = g_param_spec_boxed ("keysyms",
|
|
||||||
"Keysyms",
|
|
||||||
"Symbol matrix of the key",
|
|
||||||
EEK_TYPE_KEYSYM_MATRIX,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
name = eek_element_get_name (EEK_ELEMENT(self));
|
||||||
* EekKey:column:
|
fprintf (stderr, "%s: ", name);
|
||||||
*
|
for (i = 0; i < priv->keysyms.num_groups * priv->keysyms.num_levels; i++)
|
||||||
* The column index of #EekKey in the parent #EekSection.
|
fprintf (stderr, "\"%s\" ", eek_keysym_to_string (priv->keysyms.data[i]));
|
||||||
*/
|
fprintf (stderr, "\n");
|
||||||
pspec = g_param_spec_int ("column",
|
}
|
||||||
"Column",
|
#endif
|
||||||
"Column index of the key in section",
|
}
|
||||||
-1, G_MAXINT, -1,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* EekKey:row:
|
eek_key_real_get_keysyms (EekKey *self,
|
||||||
*
|
guint **keysyms,
|
||||||
* The row index of #EekKey in the parent #EekSection.
|
gint *num_groups,
|
||||||
*/
|
gint *num_levels)
|
||||||
pspec = g_param_spec_int ("row",
|
{
|
||||||
"Row",
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
"Row index of the key in section",
|
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
|
||||||
-1, G_MAXINT, -1,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
if (num_groups)
|
||||||
* EekKey:outline:
|
*num_groups = priv->keysyms.num_groups;
|
||||||
*
|
if (num_levels)
|
||||||
* The pointer to the outline shape of #EekKey.
|
*num_levels = priv->keysyms.num_levels;
|
||||||
*/
|
if (keysyms && num_keysyms > 0) {
|
||||||
/* Use pointer instead of boxed to avoid copy, since we can
|
*keysyms = g_slice_alloc (num_keysyms * sizeof(guint));
|
||||||
assume that only a few outline shapes are used in a whole
|
memcpy (*keysyms, priv->keysyms.data, num_keysyms * sizeof(guint));
|
||||||
keyboard (unlike keysyms and bounds). */
|
|
||||||
pspec = g_param_spec_pointer ("outline",
|
|
||||||
"Outline",
|
|
||||||
"Pointer to outline shape of the key",
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EekKey:bounds:
|
|
||||||
*
|
|
||||||
* The bounding box of #EekKey.
|
|
||||||
*/
|
|
||||||
pspec = g_param_spec_boxed ("bounds",
|
|
||||||
"Bounds",
|
|
||||||
"Bounding box of the key",
|
|
||||||
EEK_TYPE_BOUNDS,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EekKey:group:
|
|
||||||
*
|
|
||||||
* The column index of #EekKey in the symbol matrix #EekKey:keysyms.
|
|
||||||
*/
|
|
||||||
pspec = g_param_spec_int ("group",
|
|
||||||
"Group",
|
|
||||||
"Current group of the key",
|
|
||||||
0, 64, 0,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EekKey:level:
|
|
||||||
*
|
|
||||||
* The row index of #EekKey in the symbol matrix #EekKey:keysyms.
|
|
||||||
*/
|
|
||||||
pspec = g_param_spec_int ("level",
|
|
||||||
"Level",
|
|
||||||
"Current level of the key",
|
|
||||||
0, 3, 0,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
is_initialized = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
static guint
|
||||||
eek_key_get_type (void)
|
eek_key_real_get_keysym (EekKey *self)
|
||||||
{
|
{
|
||||||
static GType iface_type = 0;
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
|
||||||
|
|
||||||
if (iface_type == 0) {
|
if (num_keysyms == 0)
|
||||||
static const GTypeInfo info = {
|
return EEK_INVALID_KEYSYM;
|
||||||
sizeof (EekKeyIface),
|
return priv->keysyms.data[priv->group * priv->keysyms.num_levels +
|
||||||
eek_key_base_init, /* iface_base_init */
|
priv->level];
|
||||||
NULL /* iface_base_finalize */
|
}
|
||||||
};
|
|
||||||
|
static void
|
||||||
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
eek_key_real_set_index (EekKey *self,
|
||||||
"EekKey",
|
gint column,
|
||||||
&info,
|
gint row)
|
||||||
0);
|
{
|
||||||
}
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
return iface_type;
|
|
||||||
|
g_return_if_fail (0 <= column);
|
||||||
|
g_return_if_fail (0 <= row);
|
||||||
|
priv->column = column;
|
||||||
|
priv->row = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_real_get_index (EekKey *self,
|
||||||
|
gint *column,
|
||||||
|
gint *row)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
|
||||||
|
if (column)
|
||||||
|
*column = priv->column;
|
||||||
|
if (row)
|
||||||
|
*row = priv->row;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_real_set_outline (EekKey *self, EekOutline *outline)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
priv->outline = outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EekOutline *
|
||||||
|
eek_key_real_get_outline (EekKey *self)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
return priv->outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_real_set_keysym_index (EekKey *self,
|
||||||
|
gint group,
|
||||||
|
gint level)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
|
||||||
|
g_return_if_fail (0 <= group);
|
||||||
|
if (group >= priv->keysyms.num_groups)
|
||||||
|
group = 0;
|
||||||
|
g_return_if_fail (0 <= level && level < priv->keysyms.num_levels);
|
||||||
|
priv->group = group;
|
||||||
|
priv->level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_real_get_keysym_index (EekKey *self,
|
||||||
|
gint *group,
|
||||||
|
gint *level)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
|
||||||
|
g_return_if_fail (group);
|
||||||
|
g_return_if_fail (level);
|
||||||
|
if (group)
|
||||||
|
*group = priv->group;
|
||||||
|
if (level)
|
||||||
|
*level = priv->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object);
|
||||||
|
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
|
||||||
|
|
||||||
|
g_slice_free1 (num_keysyms * sizeof (guint), priv->keysyms.data);
|
||||||
|
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
EekKeysymMatrix *matrix;
|
||||||
|
gint column, row;
|
||||||
|
gint group, level;
|
||||||
|
|
||||||
|
g_return_if_fail (EEK_IS_KEY(object));
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_KEYCODE:
|
||||||
|
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
|
||||||
|
break;
|
||||||
|
case PROP_KEYSYMS:
|
||||||
|
matrix = g_value_get_boxed (value);
|
||||||
|
eek_key_set_keysyms (EEK_KEY(object),
|
||||||
|
matrix->data,
|
||||||
|
matrix->num_groups,
|
||||||
|
matrix->num_levels);
|
||||||
|
break;
|
||||||
|
case PROP_COLUMN:
|
||||||
|
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||||
|
eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
|
||||||
|
break;
|
||||||
|
case PROP_ROW:
|
||||||
|
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||||
|
eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
case PROP_OUTLINE:
|
||||||
|
eek_key_set_outline (EEK_KEY(object), g_value_get_pointer (value));
|
||||||
|
break;
|
||||||
|
case PROP_GROUP:
|
||||||
|
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
|
||||||
|
eek_key_set_keysym_index (EEK_KEY(object), g_value_get_int (value),
|
||||||
|
level);
|
||||||
|
break;
|
||||||
|
case PROP_LEVEL:
|
||||||
|
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
|
||||||
|
eek_key_set_keysym_index (EEK_KEY(object), group,
|
||||||
|
g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_object_set_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
EekKeysymMatrix matrix;
|
||||||
|
gint column, row;
|
||||||
|
gint group, level;
|
||||||
|
|
||||||
|
g_return_if_fail (EEK_IS_KEY(object));
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_KEYCODE:
|
||||||
|
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
|
||||||
|
break;
|
||||||
|
case PROP_KEYSYMS:
|
||||||
|
eek_key_get_keysyms (EEK_KEY(object), &matrix.data, &matrix.num_groups,
|
||||||
|
&matrix.num_levels);
|
||||||
|
g_value_set_boxed (value, &matrix);
|
||||||
|
break;
|
||||||
|
case PROP_COLUMN:
|
||||||
|
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||||
|
g_value_set_int (value, column);
|
||||||
|
break;
|
||||||
|
case PROP_ROW:
|
||||||
|
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||||
|
g_value_set_int (value, row);
|
||||||
|
break;
|
||||||
|
case PROP_OUTLINE:
|
||||||
|
g_value_set_pointer (value, eek_key_get_outline (EEK_KEY(object)));
|
||||||
|
break;
|
||||||
|
case PROP_GROUP:
|
||||||
|
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
|
||||||
|
g_value_set_int (value, group);
|
||||||
|
break;
|
||||||
|
case PROP_LEVEL:
|
||||||
|
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
|
||||||
|
g_value_set_int (value, level);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_object_get_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_class_init (EekKeyClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (gobject_class,
|
||||||
|
sizeof (EekKeyPrivate));
|
||||||
|
|
||||||
|
klass->get_keycode = eek_key_real_get_keycode;
|
||||||
|
klass->set_keycode = eek_key_real_set_keycode;
|
||||||
|
klass->set_keysyms = eek_key_real_set_keysyms;
|
||||||
|
klass->get_keysyms = eek_key_real_get_keysyms;
|
||||||
|
klass->get_keysym = eek_key_real_get_keysym;
|
||||||
|
klass->set_index = eek_key_real_set_index;
|
||||||
|
klass->get_index = eek_key_real_get_index;
|
||||||
|
klass->set_outline = eek_key_real_set_outline;
|
||||||
|
klass->get_outline = eek_key_real_get_outline;
|
||||||
|
klass->set_keysym_index = eek_key_real_set_keysym_index;
|
||||||
|
klass->get_keysym_index = eek_key_real_get_keysym_index;
|
||||||
|
|
||||||
|
gobject_class->set_property = eek_key_set_property;
|
||||||
|
gobject_class->get_property = eek_key_get_property;
|
||||||
|
gobject_class->finalize = eek_key_finalize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:keycode:
|
||||||
|
*
|
||||||
|
* The keycode of #EekKey.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_uint ("keycode",
|
||||||
|
"Keycode",
|
||||||
|
"Keycode of the key",
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:keysyms:
|
||||||
|
*
|
||||||
|
* The symbol matrix of #EekKey.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_boxed ("keysyms",
|
||||||
|
"Keysyms",
|
||||||
|
"Symbol matrix of the key",
|
||||||
|
EEK_TYPE_KEYSYM_MATRIX,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_KEYSYMS, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:column:
|
||||||
|
*
|
||||||
|
* The column index of #EekKey in the parent #EekSection.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("column",
|
||||||
|
"Column",
|
||||||
|
"Column index of the key in section",
|
||||||
|
-1, G_MAXINT, -1,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:row:
|
||||||
|
*
|
||||||
|
* The row index of #EekKey in the parent #EekSection.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("row",
|
||||||
|
"Row",
|
||||||
|
"Row index of the key in section",
|
||||||
|
-1, G_MAXINT, -1,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_ROW, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:outline:
|
||||||
|
*
|
||||||
|
* The pointer to the outline shape of #EekKey.
|
||||||
|
*/
|
||||||
|
/* Use pointer instead of boxed to avoid copy, since we can
|
||||||
|
assume that only a few outline shapes are used in a whole
|
||||||
|
keyboard (unlike keysyms and bounds). */
|
||||||
|
pspec = g_param_spec_pointer ("outline",
|
||||||
|
"Outline",
|
||||||
|
"Pointer to outline shape of the key",
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_OUTLINE, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:group:
|
||||||
|
*
|
||||||
|
* The column index of #EekKey in the symbol matrix #EekKey:keysyms.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("group",
|
||||||
|
"Group",
|
||||||
|
"Current group of the key",
|
||||||
|
0, 64, 0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_GROUP, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKey:level:
|
||||||
|
*
|
||||||
|
* The row index of #EekKey in the symbol matrix #EekKey:keysyms.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("level",
|
||||||
|
"Level",
|
||||||
|
"Current level of the key",
|
||||||
|
0, 3, 0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_LEVEL, pspec);
|
||||||
|
|
||||||
|
signals[PRESSED] =
|
||||||
|
g_signal_new ("pressed",
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
signals[RELEASED] =
|
||||||
|
g_signal_new ("released",
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_key_init (EekKey *self)
|
||||||
|
{
|
||||||
|
EekKeyPrivate *priv;
|
||||||
|
|
||||||
|
priv = self->priv = EEK_KEY_GET_PRIVATE(self);
|
||||||
|
priv->keycode = 0;
|
||||||
|
memset (&priv->keysyms, 0, sizeof priv->keysyms);
|
||||||
|
priv->column = priv->row = 0;
|
||||||
|
priv->outline = NULL;
|
||||||
|
priv->group = priv->level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eek_key_set_keycode (EekKey *key,
|
||||||
|
guint keycode)
|
||||||
|
{
|
||||||
|
g_return_if_fail (EEK_IS_KEY (key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->set_keycode (key, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_key_get_keycode:
|
|
||||||
* @key: an #EekKey
|
|
||||||
*
|
|
||||||
* Get the keycode of @key.
|
|
||||||
*/
|
|
||||||
guint
|
guint
|
||||||
eek_key_get_keycode (EekKey *key)
|
eek_key_get_keycode (EekKey *key)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
|
||||||
|
return EEK_KEY_GET_CLASS(key)->get_keycode (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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
void
|
||||||
eek_key_set_keysyms (EekKey *key,
|
eek_key_set_keysyms (EekKey *key,
|
||||||
guint *keysyms,
|
guint *keysyms,
|
||||||
gint num_groups,
|
gint num_groups,
|
||||||
gint num_levels)
|
gint num_levels)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_if_fail (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->set_keysyms (key, keysyms, num_groups, num_levels);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->set_keysyms);
|
|
||||||
(*iface->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
|
void
|
||||||
eek_key_get_keysyms (EekKey *key,
|
eek_key_get_keysyms (EekKey *key,
|
||||||
guint **keysyms,
|
guint **keysyms,
|
||||||
gint *num_groups,
|
gint *num_groups,
|
||||||
gint *num_levels)
|
gint *num_levels)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_if_fail (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->get_keysyms (key, keysyms, num_groups, num_levels);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->get_keysyms);
|
|
||||||
(*iface->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
|
guint
|
||||||
eek_key_get_keysym (EekKey *key)
|
eek_key_get_keysym (EekKey *key)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_val_if_fail (EEK_IS_KEY(key), EEK_INVALID_KEYSYM);
|
||||||
|
return EEK_KEY_GET_CLASS(key)->get_keysym (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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
void
|
||||||
eek_key_set_index (EekKey *key,
|
eek_key_set_index (EekKey *key,
|
||||||
gint column,
|
gint column,
|
||||||
gint row)
|
gint row)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_if_fail (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->set_index (key, column, row);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->set_index);
|
|
||||||
(*iface->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
|
void
|
||||||
eek_key_get_index (EekKey *key,
|
eek_key_get_index (EekKey *key,
|
||||||
gint *column,
|
gint *column,
|
||||||
gint *row)
|
gint *row)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_if_fail (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->get_index (key, column, row);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->get_index);
|
|
||||||
return (*iface->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
|
void
|
||||||
eek_key_set_outline (EekKey *key,
|
eek_key_set_outline (EekKey *key,
|
||||||
EekOutline *outline)
|
EekOutline *outline)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_if_fail (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->set_outline (key, outline);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->set_outline);
|
|
||||||
(*iface->set_outline) (key, outline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_key_get_outline:
|
|
||||||
* @key: an #EekKey
|
|
||||||
*
|
|
||||||
* Get outline shape of @key as a pointer.
|
|
||||||
*/
|
|
||||||
EekOutline *
|
EekOutline *
|
||||||
eek_key_get_outline (EekKey *key)
|
eek_key_get_outline (EekKey *key)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_val_if_fail (EEK_IS_KEY (key), NULL);
|
||||||
|
return EEK_KEY_GET_CLASS(key)->get_outline (key);
|
||||||
g_return_val_if_fail (iface, NULL);
|
|
||||||
g_return_val_if_fail (iface->get_outline, NULL);
|
|
||||||
return (*iface->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
|
void
|
||||||
eek_key_set_keysym_index (EekKey *key,
|
eek_key_set_keysym_index (EekKey *key,
|
||||||
gint group,
|
gint group,
|
||||||
gint level)
|
gint level)
|
||||||
{
|
{
|
||||||
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
|
g_return_if_fail (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->set_keysym_index (key, group, level);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->set_keysym_index);
|
|
||||||
(*iface->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
|
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 (EEK_IS_KEY(key));
|
||||||
|
EEK_KEY_GET_CLASS(key)->get_keysym_index (key, group, level);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->get_keysym_index);
|
|
||||||
return (*iface->get_keysym_index) (key, column, row);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,24 +21,37 @@
|
|||||||
#define EEK_KEY_H 1
|
#define EEK_KEY_H 1
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include "eek-element.h"
|
||||||
#include "eek-types.h"
|
#include "eek-types.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define EEK_TYPE_KEY (eek_key_get_type())
|
#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(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_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 _EekKeyClass EekKeyClass;
|
||||||
typedef struct _EekKey EekKey;
|
typedef struct _EekKeyPrivate EekKeyPrivate;
|
||||||
|
|
||||||
struct _EekKeyIface
|
struct _EekKey
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GTypeInterface g_iface;
|
EekElement parent;
|
||||||
|
|
||||||
|
EekKeyPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _EekKeyClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
EekElementClass parent_class;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
void (* set_keycode) (EekKey *self,
|
||||||
|
guint keycode);
|
||||||
guint (* get_keycode) (EekKey *self);
|
guint (* get_keycode) (EekKey *self);
|
||||||
void (* set_keysyms) (EekKey *self,
|
void (* set_keysyms) (EekKey *self,
|
||||||
guint *keysyms,
|
guint *keysyms,
|
||||||
@ -48,7 +61,6 @@ struct _EekKeyIface
|
|||||||
guint **keysyms,
|
guint **keysyms,
|
||||||
gint *num_groups,
|
gint *num_groups,
|
||||||
gint *num_levels);
|
gint *num_levels);
|
||||||
gint (* get_groups) (EekKey *self);
|
|
||||||
guint (* get_keysym) (EekKey *self);
|
guint (* get_keysym) (EekKey *self);
|
||||||
|
|
||||||
void (* set_index) (EekKey *self,
|
void (* set_index) (EekKey *self,
|
||||||
@ -61,10 +73,6 @@ struct _EekKeyIface
|
|||||||
void (* set_outline) (EekKey *self,
|
void (* set_outline) (EekKey *self,
|
||||||
EekOutline *outline);
|
EekOutline *outline);
|
||||||
EekOutline *(* get_outline) (EekKey *self);
|
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,
|
void (* set_keysym_index) (EekKey *self,
|
||||||
gint group,
|
gint group,
|
||||||
@ -76,6 +84,8 @@ struct _EekKeyIface
|
|||||||
|
|
||||||
GType eek_key_get_type (void) G_GNUC_CONST;
|
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);
|
guint eek_key_get_keycode (EekKey *key);
|
||||||
void eek_key_set_keysyms (EekKey *key,
|
void eek_key_set_keysyms (EekKey *key,
|
||||||
guint *keysyms,
|
guint *keysyms,
|
||||||
@ -85,7 +95,6 @@ void eek_key_get_keysyms (EekKey *key,
|
|||||||
guint **keysyms,
|
guint **keysyms,
|
||||||
gint *num_groups,
|
gint *num_groups,
|
||||||
gint *num_levels);
|
gint *num_levels);
|
||||||
gint eek_key_get_groups (EekKey *key);
|
|
||||||
guint eek_key_get_keysym (EekKey *key);
|
guint eek_key_get_keysym (EekKey *key);
|
||||||
|
|
||||||
void eek_key_set_index (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,
|
void eek_key_set_outline (EekKey *key,
|
||||||
EekOutline *outline);
|
EekOutline *outline);
|
||||||
EekOutline *eek_key_get_outline (EekKey *key);
|
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,
|
void eek_key_set_keysym_index (EekKey *key,
|
||||||
gint group,
|
gint group,
|
||||||
|
|||||||
@ -20,14 +20,11 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:eek-keyboard
|
* SECTION:eek-keyboard
|
||||||
* @short_description: Base interface of a keyboard
|
* @short_description: Base class of a keyboard
|
||||||
* @see_also: #EekSection
|
* @see_also: #EekSection
|
||||||
*
|
*
|
||||||
* The #EekKeyboardIface interface represents a keyboard, which
|
* The #EekKeyboardClass class represents a keyboard, which consists
|
||||||
* consists of one or more sections of the #EekSectionIface interface.
|
* of one or more sections of the #EekSectionClass class.
|
||||||
*
|
|
||||||
* #EekKeyboardIface follows the Builder pattern and is responsible
|
|
||||||
* for creation of sections.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -35,85 +32,270 @@
|
|||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-keyboard.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
|
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));
|
||||||
GParamSpec *pspec;
|
|
||||||
|
|
||||||
/**
|
ki = user_data;
|
||||||
* EekKeyboard:bounds:
|
eek_key_set_keysym_index (EEK_KEY(element), ki->group, ki->level);
|
||||||
*
|
}
|
||||||
* The bounding box of #EekKeyboard.
|
|
||||||
*/
|
|
||||||
pspec = g_param_spec_boxed ("bounds",
|
|
||||||
"Bounds",
|
|
||||||
"Bounding box of the keyboard",
|
|
||||||
EEK_TYPE_BOUNDS,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
is_initialized = TRUE;
|
static void
|
||||||
|
set_keysym_index_for_section (EekElement *element,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||||
|
set_keysym_index_for_key,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_keyboard_real_set_keysym_index (EekKeyboard *self,
|
||||||
|
gint group,
|
||||||
|
gint level)
|
||||||
|
{
|
||||||
|
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
|
struct keysym_index ki;
|
||||||
|
|
||||||
|
ki.group = priv->group = group;
|
||||||
|
ki.level = priv->level = level;
|
||||||
|
|
||||||
|
eek_container_foreach_child (EEK_CONTAINER(self),
|
||||||
|
set_keysym_index_for_section,
|
||||||
|
&ki);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eek_keyboard_real_get_keysym_index (EekKeyboard *self,
|
||||||
|
gint *group,
|
||||||
|
gint *level)
|
||||||
|
{
|
||||||
|
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
|
|
||||||
|
g_return_if_fail (group || level);
|
||||||
|
if (group)
|
||||||
|
*group = priv->group;
|
||||||
|
if (level)
|
||||||
|
*level = priv->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
key_pressed_event (EekSection *section,
|
||||||
|
EekKey *key,
|
||||||
|
EekKeyboard *keyboard)
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name (keyboard, "key-pressed", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
key_released_event (EekSection *section,
|
||||||
|
EekKey *key,
|
||||||
|
EekKeyboard *keyboard)
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name (keyboard, "key-released", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static EekSection *
|
||||||
|
eek_keyboard_real_create_section (EekKeyboard *self)
|
||||||
|
{
|
||||||
|
EekSection *section;
|
||||||
|
|
||||||
|
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
||||||
|
g_return_val_if_fail (section, NULL);
|
||||||
|
g_object_ref_sink (section);
|
||||||
|
|
||||||
|
g_signal_connect (section, "key-pressed", G_CALLBACK(key_pressed_event), self);
|
||||||
|
g_signal_connect (section, "key-released", G_CALLBACK(key_released_event), self);
|
||||||
|
|
||||||
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
|
EEK_ELEMENT(section));
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_keyboard_real_set_layout (EekKeyboard *keyboard,
|
||||||
|
EekLayout *layout)
|
||||||
|
{
|
||||||
|
g_return_if_fail (EEK_IS_LAYOUT(layout));
|
||||||
|
|
||||||
|
EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
|
||||||
|
|
||||||
|
if (g_object_is_floating (layout))
|
||||||
|
g_object_unref (layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_keyboard_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
gint group, level;
|
||||||
|
|
||||||
|
g_return_if_fail (EEK_IS_KEYBOARD(object));
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_GROUP:
|
||||||
|
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level);
|
||||||
|
eek_keyboard_set_keysym_index (EEK_KEYBOARD(object),
|
||||||
|
g_value_get_int (value),
|
||||||
|
level);
|
||||||
|
break;
|
||||||
|
case PROP_LEVEL:
|
||||||
|
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level);
|
||||||
|
eek_keyboard_set_keysym_index (EEK_KEYBOARD(object),
|
||||||
|
group,
|
||||||
|
g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_object_set_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
static void
|
||||||
eek_keyboard_get_type (void)
|
eek_keyboard_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
static GType iface_type = 0;
|
gint group, level;
|
||||||
|
|
||||||
if (iface_type == 0) {
|
g_return_if_fail (EEK_IS_KEYBOARD(object));
|
||||||
static const GTypeInfo info = {
|
switch (prop_id) {
|
||||||
sizeof (EekKeyboardIface),
|
case PROP_GROUP:
|
||||||
eek_keyboard_base_init,
|
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level);
|
||||||
NULL
|
g_value_set_int (value, group);
|
||||||
};
|
break;
|
||||||
|
case PROP_LEVEL:
|
||||||
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &level, &level);
|
||||||
"EekKeyboard",
|
g_value_set_int (value, level);
|
||||||
&info,
|
break;
|
||||||
0);
|
default:
|
||||||
|
g_object_get_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return iface_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* eek_keyboard_set_bounds:
|
eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
* @bounds: bounding box of the keyboard
|
|
||||||
*
|
|
||||||
* Set the bounding box of @keyboard to @bounds.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_keyboard_set_bounds (EekKeyboard *keyboard,
|
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
g_return_if_fail (iface);
|
g_type_class_add_private (gobject_class,
|
||||||
g_return_if_fail (iface->set_bounds);
|
sizeof (EekKeyboardPrivate));
|
||||||
(*iface->set_bounds) (keyboard, bounds);
|
|
||||||
|
klass->set_keysym_index = eek_keyboard_real_set_keysym_index;
|
||||||
|
klass->get_keysym_index = eek_keyboard_real_get_keysym_index;
|
||||||
|
klass->create_section = eek_keyboard_real_create_section;
|
||||||
|
klass->set_layout = eek_keyboard_real_set_layout;
|
||||||
|
|
||||||
|
gobject_class->get_property = eek_keyboard_get_property;
|
||||||
|
gobject_class->set_property = eek_keyboard_set_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKeyboard:group:
|
||||||
|
*
|
||||||
|
* The group (row) index of symbol matrix of #EekKeyboard.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("group",
|
||||||
|
"Group",
|
||||||
|
"Group index of symbol matrix of the keyboard",
|
||||||
|
0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_GROUP,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekKeyboard:level:
|
||||||
|
*
|
||||||
|
* The level (row) index of symbol matrix of #EekKeyboard.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("level",
|
||||||
|
"Level",
|
||||||
|
"Level index of symbol matrix of the keyboard",
|
||||||
|
0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_LEVEL,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
signals[KEY_PRESSED] =
|
||||||
|
g_signal_new ("key-pressed",
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
EEK_TYPE_KEY);
|
||||||
|
|
||||||
|
signals[KEY_RELEASED] =
|
||||||
|
g_signal_new ("key-released",
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
EEK_TYPE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* eek_keyboard_get_bounds:
|
eek_keyboard_init (EekKeyboard *self)
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
* @bounds: the bounding box of @keyboard
|
|
||||||
*
|
|
||||||
* Get the bounding box of @keyboard.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_keyboard_get_bounds (EekKeyboard *keyboard,
|
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard);
|
EekKeyboardPrivate *priv;
|
||||||
|
|
||||||
g_return_if_fail (iface);
|
priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
g_return_if_fail (iface->get_bounds);
|
priv->group = priv->level = 0;
|
||||||
return (*iface->get_bounds) (keyboard, bounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,19 +307,16 @@ eek_keyboard_get_bounds (EekKeyboard *keyboard,
|
|||||||
* Select a cell of the symbol matrix of each key on @keyboard.
|
* Select a cell of the symbol matrix of each key on @keyboard.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
eek_keyboard_set_keysym_index (EekKeyboard *self,
|
eek_keyboard_set_keysym_index (EekKeyboard *keyboard,
|
||||||
gint group,
|
gint group,
|
||||||
gint level)
|
gint level)
|
||||||
{
|
{
|
||||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(self);
|
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||||
|
EEK_KEYBOARD_GET_CLASS(keyboard)->set_keysym_index (keyboard, group, level);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->set_keysym_index);
|
|
||||||
(*iface->set_keysym_index) (self, group, level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eek_keyboard_set_keysym_index:
|
* eek_keyboard_get_keysym_index:
|
||||||
* @keyboard: an #EekKeyboard
|
* @keyboard: an #EekKeyboard
|
||||||
* @group: a pointer where row index of the symbol matrix of keys on
|
* @group: a pointer where row index of the symbol matrix of keys on
|
||||||
* @keyboard will be stored
|
* @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.
|
* Get the current cell position of the symbol matrix of each key on @keyboard.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
eek_keyboard_get_keysym_index (EekKeyboard *self,
|
eek_keyboard_get_keysym_index (EekKeyboard *keyboard,
|
||||||
gint *group,
|
gint *group,
|
||||||
gint *level)
|
gint *level)
|
||||||
{
|
{
|
||||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(self);
|
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||||
|
EEK_KEYBOARD_GET_CLASS(keyboard)->get_keysym_index (keyboard, group, level);
|
||||||
g_return_if_fail (iface);
|
|
||||||
g_return_if_fail (iface->get_keysym_index);
|
|
||||||
return (*iface->get_keysym_index) (self, group, level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eek_keyboard_create_section:
|
* eek_keyboard_create_section:
|
||||||
* @keyboard: an #EekKeyboard
|
* @keyboard: an #EekKeyboard
|
||||||
* @name: name of the section
|
* @name: name of the section
|
||||||
* @angle: rotation angle of the section
|
|
||||||
* @bounds: bounding box of the section
|
* @bounds: bounding box of the section
|
||||||
*
|
*
|
||||||
* Create an #EekSection instance and attach it to @keyboard.
|
* Create an #EekSection instance and attach it to @keyboard.
|
||||||
*/
|
*/
|
||||||
EekSection *
|
EekSection *
|
||||||
eek_keyboard_create_section (EekKeyboard *keyboard,
|
eek_keyboard_create_section (EekKeyboard *keyboard)
|
||||||
const gchar *name,
|
|
||||||
gint angle,
|
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard);
|
EekSection *section;
|
||||||
|
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||||
g_return_val_if_fail (iface, NULL);
|
section = EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
|
||||||
g_return_val_if_fail (iface->create_section, NULL);
|
return section;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,10 +363,6 @@ void
|
|||||||
eek_keyboard_set_layout (EekKeyboard *keyboard,
|
eek_keyboard_set_layout (EekKeyboard *keyboard,
|
||||||
EekLayout *layout)
|
EekLayout *layout)
|
||||||
{
|
{
|
||||||
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard);
|
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||||
|
EEK_KEYBOARD_GET_CLASS(keyboard)->set_layout (keyboard, layout);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,42 +20,45 @@
|
|||||||
#ifndef EEK_KEYBOARD_H
|
#ifndef EEK_KEYBOARD_H
|
||||||
#define EEK_KEYBOARD_H 1
|
#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"
|
#include "eek-layout.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type())
|
#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(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_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 >*/
|
/*< private >*/
|
||||||
GTypeInterface g_iface;
|
EekContainer parent;
|
||||||
|
|
||||||
|
EekKeyboardPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _EekKeyboardClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
EekContainerClass parent_class;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
void (* set_bounds) (EekKeyboard *self,
|
|
||||||
EekBounds *bounds);
|
|
||||||
void (* get_bounds) (EekKeyboard *self,
|
|
||||||
EekBounds *bounds);
|
|
||||||
void (* set_keysym_index) (EekKeyboard *self,
|
void (* set_keysym_index) (EekKeyboard *self,
|
||||||
gint group,
|
gint group,
|
||||||
gint level);
|
gint level);
|
||||||
void (* get_keysym_index) (EekKeyboard *self,
|
void (* get_keysym_index) (EekKeyboard *self,
|
||||||
gint *group,
|
gint *group,
|
||||||
gint *level);
|
gint *level);
|
||||||
EekSection *(* create_section) (EekKeyboard *self,
|
|
||||||
const gchar *name,
|
|
||||||
gint angle,
|
|
||||||
EekBounds *bounds);
|
|
||||||
|
|
||||||
void (* foreach_section) (EekKeyboard *self,
|
EekSection *(* create_section) (EekKeyboard *self);
|
||||||
GFunc func,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
void (* set_layout) (EekKeyboard *self,
|
void (* set_layout) (EekKeyboard *self,
|
||||||
EekLayout *layout);
|
EekLayout *layout);
|
||||||
@ -63,10 +66,6 @@ struct _EekKeyboardIface
|
|||||||
|
|
||||||
GType eek_keyboard_get_type (void) G_GNUC_CONST;
|
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,
|
void eek_keyboard_set_keysym_index (EekKeyboard *self,
|
||||||
gint group,
|
gint group,
|
||||||
gint level);
|
gint level);
|
||||||
@ -74,14 +73,7 @@ void eek_keyboard_get_keysym_index (EekKeyboard *self,
|
|||||||
gint *group,
|
gint *group,
|
||||||
gint *level);
|
gint *level);
|
||||||
|
|
||||||
EekSection *eek_keyboard_create_section (EekKeyboard *keyboard,
|
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);
|
|
||||||
|
|
||||||
void eek_keyboard_set_layout (EekKeyboard *keyboard,
|
void eek_keyboard_set_layout (EekKeyboard *keyboard,
|
||||||
EekLayout *layout);
|
EekLayout *layout);
|
||||||
|
|||||||
@ -20,10 +20,10 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:eek-layout
|
* 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
|
* The #EekLayout class is a base interface of layout engine which
|
||||||
* which arranges keyboard elements.
|
* arranges keyboard elements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -33,31 +33,39 @@
|
|||||||
#include "eek-layout.h"
|
#include "eek-layout.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_INITIALLY_UNOWNED);
|
|
||||||
|
|
||||||
static void
|
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
|
GType
|
||||||
eek_layout_dispose (GObject *object)
|
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
|
void
|
||||||
eek_layout_class_init (EekLayoutClass *klass)
|
eek_layout_apply (EekLayout *layout,
|
||||||
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
g_return_if_fail (EEK_IS_LAYOUT(layout));
|
||||||
GParamSpec *pspec;
|
EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
|
||||||
|
|
||||||
gobject_class->finalize = eek_layout_finalize;
|
|
||||||
gobject_class->dispose = eek_layout_dispose;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
eek_layout_init (EekLayout *self)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@ -28,31 +28,24 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
#define EEK_TYPE_LAYOUT (eek_layout_get_type())
|
#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(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(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_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_LAYOUT, EekLayoutIface))
|
||||||
#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass))
|
|
||||||
|
|
||||||
typedef struct _EekLayoutClass EekLayoutClass;
|
typedef struct _EekLayoutIface EekLayoutIface;
|
||||||
typedef struct _EekLayout EekLayout;
|
typedef struct _EekLayout EekLayout;
|
||||||
|
|
||||||
struct _EekLayout
|
struct _EekLayoutIface
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GInitiallyUnowned parent;
|
GTypeInterface parent_iface;
|
||||||
|
|
||||||
|
void (*apply) (EekLayout *self,
|
||||||
|
EekKeyboard *keyboard);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EekLayoutClass
|
GType eek_layout_get_type (void) G_GNUC_CONST;
|
||||||
{
|
void eek_layout_apply (EekLayout *layout,
|
||||||
/*< private >*/
|
EekKeyboard *keyboard);
|
||||||
GInitiallyUnownedClass parent_class;
|
|
||||||
|
|
||||||
/*< public >*/
|
|
||||||
void (*apply_to_keyboard) (EekLayout *self,
|
|
||||||
EekKeyboard *keyboard);
|
|
||||||
};
|
|
||||||
|
|
||||||
GType eek_layout_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_LAYOUT_H */
|
#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,350 +20,329 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:eek-section
|
* SECTION:eek-section
|
||||||
* @short_description: Base interface of a keyboard section
|
* @short_description: Base class of a section
|
||||||
* @see_also: #EekKeyboard, #EekKey
|
* @see_also: #EekKey
|
||||||
*
|
*
|
||||||
* The #EekSectionIface interface represents a keyboard section, which
|
* The #EekSectionClass class represents a section, which consists
|
||||||
* is parented to #EekKeyboardIface and can have one or more keys of
|
* of one or more keys of the #EekKeyClass class.
|
||||||
* the #EekKeyIface interface.
|
|
||||||
*
|
|
||||||
* #EekSectionIface follows the Builder pattern and is responsible for
|
|
||||||
* creation of keys.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-section.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
|
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;
|
||||||
GParamSpec *pspec;
|
|
||||||
|
|
||||||
/**
|
g_object_notify (G_OBJECT(self), "angle");
|
||||||
* EekSection:name:
|
}
|
||||||
*
|
|
||||||
* The name of #EekSection.
|
|
||||||
*/
|
|
||||||
pspec = g_param_spec_string ("name",
|
|
||||||
"Name",
|
|
||||||
"Name",
|
|
||||||
NULL,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
static gint
|
||||||
* EekSection:columns:
|
eek_section_real_get_angle (EekSection *self)
|
||||||
*
|
{
|
||||||
* The number of columns in #EekSection.
|
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
return priv->angle;
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
static gint
|
||||||
* EekSection:angle:
|
eek_section_real_get_n_rows (EekSection *self)
|
||||||
*
|
{
|
||||||
* The rotation angle of #EekSection.
|
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||||
*/
|
|
||||||
pspec = g_param_spec_int ("angle",
|
|
||||||
"Angle",
|
|
||||||
"Rotation angle of the section",
|
|
||||||
-360, 360, 0,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_interface_install_property (g_iface, pspec);
|
|
||||||
|
|
||||||
/**
|
return g_slist_length (priv->rows);
|
||||||
* 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);
|
|
||||||
|
|
||||||
is_initialized = TRUE;
|
static void
|
||||||
|
eek_section_real_add_row (EekSection *self,
|
||||||
|
gint num_columns,
|
||||||
|
EekOrientation orientation)
|
||||||
|
{
|
||||||
|
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||||
|
EekRow *row;
|
||||||
|
|
||||||
|
row = g_slice_new (EekRow);
|
||||||
|
row->num_columns = num_columns;
|
||||||
|
row->orientation = orientation;
|
||||||
|
priv->rows = g_slist_append (priv->rows, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_section_real_get_row (EekSection *self,
|
||||||
|
gint index,
|
||||||
|
gint *num_columns,
|
||||||
|
EekOrientation *orientation)
|
||||||
|
{
|
||||||
|
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||||
|
EekRow *row;
|
||||||
|
|
||||||
|
row = g_slist_nth_data (priv->rows, index);
|
||||||
|
g_return_if_fail (row);
|
||||||
|
if (num_columns)
|
||||||
|
*num_columns = row->num_columns;
|
||||||
|
if (orientation)
|
||||||
|
*orientation = row->orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pressed_event (EekKey *key, EekSection *section)
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name (section, "key-pressed", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
released_event (EekKey *key, EekSection *section)
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name (section, "key-released", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static EekKey *
|
||||||
|
eek_section_real_create_key (EekSection *self,
|
||||||
|
gint column,
|
||||||
|
gint row)
|
||||||
|
{
|
||||||
|
EekKey *key;
|
||||||
|
gint num_columns, num_rows;
|
||||||
|
EekOrientation orientation;
|
||||||
|
|
||||||
|
num_rows = eek_section_get_n_rows (self);
|
||||||
|
g_return_val_if_fail (0 <= row && row < num_rows, NULL);
|
||||||
|
eek_section_get_row (self, row, &num_columns, &orientation);
|
||||||
|
g_return_val_if_fail (column < num_columns, NULL);
|
||||||
|
|
||||||
|
key = g_object_new (EEK_TYPE_KEY,
|
||||||
|
"column", column,
|
||||||
|
"row", row,
|
||||||
|
NULL);
|
||||||
|
g_return_val_if_fail (key, NULL);
|
||||||
|
g_object_ref_sink (key);
|
||||||
|
|
||||||
|
g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self);
|
||||||
|
g_signal_connect (key, "released", G_CALLBACK(released_event), self);
|
||||||
|
|
||||||
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
|
EEK_ELEMENT(key));
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_section_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(object);
|
||||||
|
GSList *head;
|
||||||
|
|
||||||
|
for (head = priv->rows; head; head = g_slist_next (head))
|
||||||
|
g_slice_free (EekRow, head->data);
|
||||||
|
g_slist_free (priv->rows);
|
||||||
|
|
||||||
|
for (head = priv->keys; head; head = g_slist_next (head))
|
||||||
|
g_object_unref (head->data);
|
||||||
|
g_slist_free (priv->keys);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_section_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_ANGLE:
|
||||||
|
eek_section_set_angle (EEK_SECTION(object),
|
||||||
|
g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_object_set_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
static void
|
||||||
eek_section_get_type (void)
|
eek_section_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
static GType iface_type = 0;
|
switch (prop_id) {
|
||||||
|
case PROP_ANGLE:
|
||||||
if (iface_type == 0) {
|
g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
|
||||||
static const GTypeInfo info = {
|
break;
|
||||||
sizeof (EekSectionIface),
|
default:
|
||||||
eek_section_base_init,
|
g_object_get_property (object,
|
||||||
NULL
|
g_param_spec_get_name (pspec),
|
||||||
};
|
value);
|
||||||
|
break;
|
||||||
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
|
||||||
"EekSection",
|
|
||||||
&info,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
return iface_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* eek_section_set_rows:
|
eek_section_class_init (EekSectionClass *klass)
|
||||||
* @section: an #EekSection
|
{
|
||||||
* @rows: the number of rows in @section
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
*
|
GParamSpec *pspec;
|
||||||
* Set the number of rows in @section to @rows.
|
|
||||||
*/
|
g_type_class_add_private (gobject_class, sizeof (EekSectionPrivate));
|
||||||
|
|
||||||
|
klass->set_angle = eek_section_real_set_angle;
|
||||||
|
klass->get_angle = eek_section_real_get_angle;
|
||||||
|
klass->get_n_rows = eek_section_real_get_n_rows;
|
||||||
|
klass->add_row = eek_section_real_add_row;
|
||||||
|
klass->get_row = eek_section_real_get_row;
|
||||||
|
klass->create_key = eek_section_real_create_key;
|
||||||
|
|
||||||
|
gobject_class->set_property = eek_section_set_property;
|
||||||
|
gobject_class->get_property = eek_section_get_property;
|
||||||
|
gobject_class->finalize = eek_section_finalize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekSection:angle:
|
||||||
|
*
|
||||||
|
* The rotation angle of #EekSection.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_int ("angle",
|
||||||
|
"Angle",
|
||||||
|
"Rotation angle of the section",
|
||||||
|
-360, 360, 0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_ANGLE,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
signals[KEY_PRESSED] =
|
||||||
|
g_signal_new ("key-pressed",
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
EEK_TYPE_KEY);
|
||||||
|
|
||||||
|
signals[KEY_RELEASED] =
|
||||||
|
g_signal_new ("key-released",
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
EEK_TYPE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_section_init (EekSection *self)
|
||||||
|
{
|
||||||
|
EekSectionPrivate *priv;
|
||||||
|
|
||||||
|
priv = self->priv = EEK_SECTION_GET_PRIVATE (self);
|
||||||
|
priv->angle = 0;
|
||||||
|
priv->rows = NULL;
|
||||||
|
priv->keys = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eek_section_set_rows (EekSection *section,
|
eek_section_set_angle (EekSection *section,
|
||||||
gint rows)
|
gint angle)
|
||||||
{
|
{
|
||||||
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
|
g_return_if_fail (EEK_IS_SECTION(section));
|
||||||
|
EEK_SECTION_GET_CLASS(section)->set_angle (section, angle);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_section_get_angle:
|
|
||||||
* @section: an #EekSection
|
|
||||||
*
|
|
||||||
* Get the rotation angle of @section.
|
|
||||||
*/
|
|
||||||
gint
|
gint
|
||||||
eek_section_get_angle (EekSection *section)
|
eek_section_get_angle (EekSection *section)
|
||||||
{
|
{
|
||||||
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
|
g_return_val_if_fail (EEK_IS_SECTION(section), -1);
|
||||||
|
return EEK_SECTION_GET_CLASS(section)->get_angle (section);
|
||||||
g_return_val_if_fail (iface->get_angle, 0);
|
|
||||||
return (*iface->get_angle) (section);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
gint
|
||||||
* eek_section_set_bounds:
|
eek_section_get_n_rows (EekSection *section)
|
||||||
* @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)
|
|
||||||
{
|
{
|
||||||
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
|
g_return_val_if_fail (EEK_IS_SECTION(section), -1);
|
||||||
|
return EEK_SECTION_GET_CLASS(section)->get_n_rows (section);
|
||||||
g_return_if_fail (iface->set_bounds);
|
|
||||||
(*iface->set_bounds) (section, bounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_section_get_bounds:
|
|
||||||
* @section: an #EekSection
|
|
||||||
* @bounds: the bounding box of @section
|
|
||||||
*
|
|
||||||
* Get the bounding box of @section.
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
eek_section_get_bounds (EekSection *section,
|
eek_section_add_row (EekSection *section,
|
||||||
EekBounds *bounds)
|
gint num_columns,
|
||||||
|
EekOrientation orientation)
|
||||||
{
|
{
|
||||||
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
|
g_return_if_fail (EEK_IS_SECTION(section));
|
||||||
|
EEK_SECTION_GET_CLASS(section)->add_row (section,
|
||||||
g_return_if_fail (iface->get_bounds);
|
num_columns,
|
||||||
return (*iface->get_bounds) (section, bounds);
|
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 *
|
EekKey *
|
||||||
eek_section_create_key (EekSection *section,
|
eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
|
||||||
guint keycode,
|
|
||||||
guint *keysyms,
|
|
||||||
gint num_groups,
|
|
||||||
gint num_levels,
|
|
||||||
gint column,
|
gint column,
|
||||||
gint row,
|
gint row)
|
||||||
EekOutline *outline,
|
|
||||||
EekBounds *bounds)
|
|
||||||
{
|
{
|
||||||
EekSectionIface *iface;
|
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||||
|
return EEK_SECTION_GET_CLASS(section)->create_key (section, column, row);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,102 +20,72 @@
|
|||||||
#ifndef EEK_SECTION_H
|
#ifndef EEK_SECTION_H
|
||||||
#define EEK_SECTION_H 1
|
#define EEK_SECTION_H 1
|
||||||
|
|
||||||
#include "eek-key.h"
|
#include <glib-object.h>
|
||||||
|
#include "eek-container.h"
|
||||||
|
#include "eek-types.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define EEK_TYPE_SECTION (eek_section_get_type())
|
#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(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_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 _EekSectionClass EekSectionClass;
|
||||||
typedef struct _EekSection EekSection;
|
typedef struct _EekSectionPrivate EekSectionPrivate;
|
||||||
|
|
||||||
struct _EekSectionIface
|
struct _EekSection
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GTypeInterface g_iface;
|
EekContainer parent;
|
||||||
|
|
||||||
/*< public >*/
|
EekSectionPrivate *priv;
|
||||||
void (* set_rows) (EekSection *self,
|
|
||||||
gint rows);
|
|
||||||
gint (* get_rows) (EekSection *self);
|
|
||||||
void (* set_columns) (EekSection *self,
|
|
||||||
gint row,
|
|
||||||
gint columns);
|
|
||||||
gint (* get_columns) (EekSection *self,
|
|
||||||
gint row);
|
|
||||||
void (* set_orientation) (EekSection *self,
|
|
||||||
gint row,
|
|
||||||
EekOrientation orientation);
|
|
||||||
EekOrientation (* get_orientation) (EekSection *self,
|
|
||||||
gint row);
|
|
||||||
|
|
||||||
void (* set_angle) (EekSection *self,
|
|
||||||
gint angle);
|
|
||||||
gint (* get_angle) (EekSection *self);
|
|
||||||
|
|
||||||
void (* set_bounds) (EekSection *self,
|
|
||||||
EekBounds *bounds);
|
|
||||||
void (* get_bounds) (EekSection *self,
|
|
||||||
EekBounds *bounds);
|
|
||||||
|
|
||||||
EekKey *(* create_key) (EekSection *self,
|
|
||||||
const gchar *name,
|
|
||||||
guint keycode,
|
|
||||||
guint *keysyms,
|
|
||||||
gint num_groups,
|
|
||||||
gint num_levels,
|
|
||||||
gint column,
|
|
||||||
gint row,
|
|
||||||
EekOutline *outline,
|
|
||||||
EekBounds *bounds);
|
|
||||||
|
|
||||||
void (* foreach_key) (EekSection *self,
|
|
||||||
GFunc func,
|
|
||||||
gpointer user_data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_section_get_type (void) G_GNUC_CONST;
|
struct _EekSectionClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
EekContainerClass parent_class;
|
||||||
|
|
||||||
void eek_section_set_rows (EekSection *section,
|
/*< public >*/
|
||||||
gint rows);
|
void (* set_angle) (EekSection *self,
|
||||||
gint eek_section_get_rows (EekSection *section);
|
gint angle);
|
||||||
void eek_section_set_columns (EekSection *section,
|
gint (* get_angle) (EekSection *self);
|
||||||
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 (* get_n_rows) (EekSection *self);
|
||||||
gint angle);
|
void (* add_row) (EekSection *self,
|
||||||
gint eek_section_get_angle (EekSection *section);
|
gint num_columns,
|
||||||
|
EekOrientation orientation);
|
||||||
|
void (* get_row) (EekSection *self,
|
||||||
|
gint index,
|
||||||
|
gint *num_columns,
|
||||||
|
EekOrientation *orientation);
|
||||||
|
|
||||||
void eek_section_set_bounds (EekSection *section,
|
EekKey *(* create_key) (EekSection *self,
|
||||||
EekBounds *bounds);
|
gint row,
|
||||||
void eek_section_get_bounds (EekSection *section,
|
gint column);
|
||||||
EekBounds *bounds);
|
};
|
||||||
|
|
||||||
EekKey *eek_section_create_key (EekSection *section,
|
GType eek_section_get_type (void) G_GNUC_CONST;
|
||||||
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,
|
void eek_section_set_angle (EekSection *section,
|
||||||
GFunc func,
|
gint angle);
|
||||||
gpointer user_data);
|
gint eek_section_get_angle (EekSection *section);
|
||||||
|
|
||||||
|
gint eek_section_get_n_rows (EekSection *section);
|
||||||
|
void eek_section_add_row (EekSection *section,
|
||||||
|
gint num_columns,
|
||||||
|
EekOrientation orientation);
|
||||||
|
void eek_section_get_row (EekSection *section,
|
||||||
|
gint index,
|
||||||
|
gint *num_columns,
|
||||||
|
EekOrientation *orientation);
|
||||||
|
|
||||||
|
EekKey *eek_section_create_key (EekSection *section,
|
||||||
|
gint column,
|
||||||
|
gint row);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_SECTION_H */
|
#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
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
* 02110-1301 USA
|
* 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:eek-types
|
||||||
|
* @short_description: Miscellaneous types
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|||||||
@ -30,6 +30,8 @@ typedef enum {
|
|||||||
EEK_ORIENTATION_INVALID = -1
|
EEK_ORIENTATION_INVALID = -1
|
||||||
} EekOrientation;
|
} EekOrientation;
|
||||||
|
|
||||||
|
typedef struct _EekKey EekKey;
|
||||||
|
typedef struct _EekSection EekSection;
|
||||||
typedef struct _EekKeyboard EekKeyboard;
|
typedef struct _EekKeyboard EekKeyboard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -37,10 +37,17 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "eek-xkb-layout.h"
|
#include "eek-xkb-layout.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
|
#include "eek-section.h"
|
||||||
|
#include "eek-key.h"
|
||||||
|
#include "eek-keysym.h"
|
||||||
|
|
||||||
#define noKBDRAW_DEBUG
|
#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) \
|
#define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
|
||||||
@ -72,8 +79,6 @@ struct _EekXkbLayoutPrivate
|
|||||||
gint scale_denominator;
|
gint scale_denominator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INVALID_KEYCODE ((guint)(-1))
|
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
find_keycode (EekXkbLayout *layout, gchar *key_name);
|
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;
|
return d * priv->scale_numerator / priv->scale_denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EekKey *
|
static void
|
||||||
create_key (EekXkbLayout *layout,
|
create_key (EekXkbLayout *layout,
|
||||||
EekSection *section,
|
EekSection *section,
|
||||||
gint column,
|
gint column,
|
||||||
@ -120,11 +125,11 @@ create_key (EekXkbLayout *layout,
|
|||||||
EekXkbLayoutPrivate *priv = layout->priv;
|
EekXkbLayoutPrivate *priv = layout->priv;
|
||||||
EekKey *key;
|
EekKey *key;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
guint *keysyms;
|
guint *keysyms = NULL;
|
||||||
gchar name[XkbKeyNameLength + 1];
|
gchar name[XkbKeyNameLength + 1];
|
||||||
EekOutline *outline;
|
EekOutline *outline;
|
||||||
KeyCode keycode;
|
KeyCode keycode;
|
||||||
gint num_groups, num_levels;
|
gint num_groups, num_levels, num_keysyms;
|
||||||
|
|
||||||
xkbgeometry = priv->xkb->geom;
|
xkbgeometry = priv->xkb->geom;
|
||||||
xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
|
xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
|
||||||
@ -133,7 +138,7 @@ create_key (EekXkbLayout *layout,
|
|||||||
xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
|
xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
|
||||||
xkbshape->primary;
|
xkbshape->primary;
|
||||||
|
|
||||||
outline = g_new0 (EekOutline, 1);
|
outline = g_slice_new (EekOutline);
|
||||||
outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius);
|
outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius);
|
||||||
|
|
||||||
if (xkboutline->num_points <= 2) { /* rectangular */
|
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);
|
bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
|
||||||
|
|
||||||
keycode = find_keycode (layout, name);
|
keycode = find_keycode (layout, name);
|
||||||
if (keycode == INVALID_KEYCODE)
|
if (keycode == EEK_INVALID_KEYCODE)
|
||||||
num_groups = num_levels = 0;
|
num_groups = num_levels = 0;
|
||||||
else {
|
else {
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
gint num_keysyms, i, j;
|
gint i, j;
|
||||||
|
|
||||||
num_groups = XkbKeyNumGroups (priv->xkb, keycode);
|
num_groups = XkbKeyNumGroups (priv->xkb, keycode);
|
||||||
num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
|
num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
|
||||||
num_keysyms = num_groups * num_levels;
|
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 (i = 0; i < num_groups; i++)
|
||||||
for (j = 0; j < num_levels; j++) {
|
for (j = 0; j < num_levels; j++) {
|
||||||
keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
|
keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
|
||||||
@ -196,16 +201,15 @@ create_key (EekXkbLayout *layout,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eek_section_create_key (section,
|
key = eek_section_create_key (section, column, row);
|
||||||
name,
|
eek_element_set_name (EEK_ELEMENT(key), name);
|
||||||
keycode,
|
eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
|
||||||
keysyms,
|
eek_key_set_keycode (key, keycode);
|
||||||
num_groups,
|
eek_key_set_keysyms (key, keysyms, num_groups, num_levels);
|
||||||
num_levels,
|
if (keysyms)
|
||||||
column,
|
g_slice_free1 (num_keysyms * sizeof(guint), keysyms);
|
||||||
row,
|
eek_key_set_keysym_index (key, 0, 0);
|
||||||
outline,
|
eek_key_set_outline (key, outline);
|
||||||
&bounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -229,25 +233,24 @@ create_section (EekXkbLayout *layout,
|
|||||||
priv = layout->priv;
|
priv = layout->priv;
|
||||||
xkbgeometry = priv->xkb->geom;
|
xkbgeometry = priv->xkb->geom;
|
||||||
name = XGetAtomName (priv->display, xkbsection->name);
|
name = XGetAtomName (priv->display, xkbsection->name);
|
||||||
section = eek_keyboard_create_section (keyboard,
|
section = eek_keyboard_create_section (keyboard);
|
||||||
name,
|
eek_element_set_name (EEK_ELEMENT(section), name);
|
||||||
/* angle is in tenth of degree */
|
eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
|
||||||
xkbsection->angle / 10,
|
eek_section_set_angle (section,
|
||||||
&bounds);
|
/* angle is in tenth of degree */
|
||||||
|
xkbsection->angle / 10);
|
||||||
|
|
||||||
eek_section_set_rows (section, xkbsection->num_rows);
|
|
||||||
for (i = 0; i < xkbsection->num_rows; i++) {
|
for (i = 0; i < xkbsection->num_rows; i++) {
|
||||||
XkbRowRec *xkbrow;
|
XkbRowRec *xkbrow;
|
||||||
|
|
||||||
xkbrow = &xkbsection->rows[i];
|
xkbrow = &xkbsection->rows[i];
|
||||||
left = xkbrow->left;
|
left = xkbrow->left;
|
||||||
top = xkbrow->top;
|
top = xkbrow->top;
|
||||||
eek_section_set_columns (section, i, xkbrow->num_keys);
|
eek_section_add_row (section,
|
||||||
eek_section_set_orientation (section,
|
xkbrow->num_keys,
|
||||||
i,
|
xkbrow->vertical ?
|
||||||
xkbrow->vertical ?
|
EEK_ORIENTATION_VERTICAL :
|
||||||
EEK_ORIENTATION_VERTICAL :
|
EEK_ORIENTATION_HORIZONTAL);
|
||||||
EEK_ORIENTATION_HORIZONTAL);
|
|
||||||
for (j = 0; j < xkbrow->num_keys; j++) {
|
for (j = 0; j < xkbrow->num_keys; j++) {
|
||||||
XkbKeyRec *xkbkey;
|
XkbKeyRec *xkbkey;
|
||||||
XkbBoundsRec *xkbbounds;
|
XkbBoundsRec *xkbbounds;
|
||||||
@ -280,39 +283,33 @@ create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
|
|||||||
|
|
||||||
xkbgeometry = priv->xkb->geom;
|
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);
|
setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
|
||||||
|
|
||||||
bounds.x = bounds.y = 0;
|
bounds.x = bounds.y = 0;
|
||||||
bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
|
bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
|
||||||
bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_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++) {
|
for (i = 0; i < xkbgeometry->num_sections; i++) {
|
||||||
XkbSectionRec *xkbsection;
|
XkbSectionRec *xkbsection;
|
||||||
EekSection *section;
|
|
||||||
|
|
||||||
xkbsection = &xkbgeometry->sections[i];
|
xkbsection = &xkbgeometry->sections[i];
|
||||||
create_section (layout, keyboard, xkbsection);
|
create_section (layout, keyboard, xkbsection);
|
||||||
}
|
}
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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));
|
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||||
|
|
||||||
create_keyboard (EEK_XKB_LAYOUT(layout), keyboard);
|
create_keyboard (EEK_XKB_LAYOUT(layout), keyboard);
|
||||||
|
|
||||||
if (g_object_is_floating (keyboard))
|
if (g_object_is_floating (keyboard))
|
||||||
g_object_unref (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
|
static void
|
||||||
eek_xkb_layout_finalize (GObject *object)
|
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.keycodes);
|
||||||
g_free (priv->names.geometry);
|
g_free (priv->names.geometry);
|
||||||
g_free (priv->names.symbols);
|
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 */
|
XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */
|
||||||
G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
|
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);
|
eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
g_object_set_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -377,27 +377,31 @@ eek_xkb_layout_get_property (GObject *object,
|
|||||||
g_value_set_string (value, name);
|
g_value_set_string (value, name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
g_object_get_property (object,
|
||||||
|
g_param_spec_get_name (pspec),
|
||||||
|
value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_layout_iface_init (EekLayoutIface *iface)
|
||||||
|
{
|
||||||
|
iface->apply = eek_xkb_layout_real_apply;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
|
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
|
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
|
g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
|
||||||
|
|
||||||
gobject_class->finalize = eek_xkb_layout_finalize;
|
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->set_property = eek_xkb_layout_set_property;
|
||||||
gobject_class->get_property = eek_xkb_layout_get_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",
|
pspec = g_param_spec_string ("keycodes",
|
||||||
"Keycodes",
|
"Keycodes",
|
||||||
"XKB keycodes component name",
|
"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);
|
g_object_class_install_property (gobject_class, PROP_SYMBOLS, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
outline_free (gpointer data)
|
||||||
|
{
|
||||||
|
g_slice_free (EekOutline, data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_xkb_layout_init (EekXkbLayout *self)
|
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,
|
priv->outline_hash = g_hash_table_new_full (g_direct_hash,
|
||||||
g_direct_equal,
|
g_direct_equal,
|
||||||
NULL,
|
NULL,
|
||||||
g_free);
|
outline_free);
|
||||||
if (priv->xkb == NULL) {
|
if (priv->xkb == NULL) {
|
||||||
g_critical ("XkbGetKeyboard failed to get keyboard from the server!");
|
g_critical ("XkbGetKeyboard failed to get keyboard from the server!");
|
||||||
return;
|
return;
|
||||||
@ -515,10 +525,12 @@ eek_xkb_layout_new (const gchar *keycodes,
|
|||||||
const gchar *geometry,
|
const gchar *geometry,
|
||||||
const gchar *symbols)
|
const gchar *symbols)
|
||||||
{
|
{
|
||||||
EekXkbLayout *layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL);
|
EekXkbLayout *layout;
|
||||||
EekXkbLayoutPrivate *priv = layout->priv;
|
EekXkbLayoutPrivate *priv;
|
||||||
|
|
||||||
|
layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL);
|
||||||
g_return_val_if_fail (layout, NULL);
|
g_return_val_if_fail (layout, NULL);
|
||||||
|
priv = layout->priv;
|
||||||
if (keycodes)
|
if (keycodes)
|
||||||
priv->names.keycodes = g_strdup (keycodes);
|
priv->names.keycodes = g_strdup (keycodes);
|
||||||
if (geometry)
|
if (geometry)
|
||||||
@ -609,8 +621,6 @@ G_CONST_RETURN gchar *
|
|||||||
eek_xkb_layout_get_geometry (EekXkbLayout *layout)
|
eek_xkb_layout_get_geometry (EekXkbLayout *layout)
|
||||||
{
|
{
|
||||||
EekXkbLayoutPrivate *priv = layout->priv;
|
EekXkbLayoutPrivate *priv = layout->priv;
|
||||||
char *name;
|
|
||||||
|
|
||||||
return priv->names.geometry;
|
return priv->names.geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +692,7 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
|
|||||||
EekXkbLayoutPrivate *priv = layout->priv;
|
EekXkbLayoutPrivate *priv = layout->priv;
|
||||||
|
|
||||||
if (!priv->xkb)
|
if (!priv->xkb)
|
||||||
return INVALID_KEYCODE;
|
return EEK_INVALID_KEYCODE;
|
||||||
|
|
||||||
#ifdef KBDRAW_DEBUG
|
#ifdef KBDRAW_DEBUG
|
||||||
printf (" looking for keycode for (%c%c%c%c)\n",
|
printf (" looking for keycode for (%c%c%c%c)\n",
|
||||||
@ -736,7 +746,7 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
|
|||||||
palias++;
|
palias++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INVALID_KEYCODE;
|
return EEK_INVALID_KEYCODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@ -40,7 +40,7 @@ typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate;
|
|||||||
struct _EekXkbLayout
|
struct _EekXkbLayout
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
EekLayout parent;
|
GInitiallyUnowned parent;
|
||||||
|
|
||||||
EekXkbLayoutPrivate *priv;
|
EekXkbLayoutPrivate *priv;
|
||||||
};
|
};
|
||||||
@ -48,7 +48,7 @@ struct _EekXkbLayout
|
|||||||
struct _EekXkbLayoutClass
|
struct _EekXkbLayoutClass
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
EekLayoutClass parent_class;
|
GInitiallyUnownedClass parent_class;
|
||||||
|
|
||||||
void (* set_keycodes) (EekXkbLayout *self,
|
void (* set_keycodes) (EekXkbLayout *self,
|
||||||
const gchar *keycodes);
|
const gchar *keycodes);
|
||||||
|
|||||||
@ -16,9 +16,6 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
# 02110-1301 USA
|
# 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_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_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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define CSW 1280
|
#define CSW 640
|
||||||
#define CSH 1024
|
#define CSH 480
|
||||||
|
|
||||||
static gchar *symbols = NULL;
|
static gchar *symbols = NULL;
|
||||||
static gchar *keycodes = NULL;
|
static gchar *keycodes = NULL;
|
||||||
@ -83,12 +83,21 @@ on_resize (GObject *object,
|
|||||||
&value);
|
&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
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
EekLayout *layout;
|
EekLayout *layout;
|
||||||
ClutterActor *stage;
|
ClutterActor *stage, *actor;
|
||||||
ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
|
ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
|
|
||||||
@ -116,16 +125,17 @@ main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
g_object_ref_sink (keyboard);
|
g_object_ref_sink (keyboard);
|
||||||
|
|
||||||
|
g_signal_connect (keyboard, "key-pressed", G_CALLBACK(key_pressed_event), NULL);
|
||||||
eek_keyboard_set_layout (keyboard, layout);
|
eek_keyboard_set_layout (keyboard, layout);
|
||||||
|
actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard));
|
||||||
stage = clutter_stage_get_default ();
|
stage = clutter_stage_get_default ();
|
||||||
|
|
||||||
clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
|
clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
|
||||||
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
|
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_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);
|
clutter_actor_show_all (stage);
|
||||||
|
|
||||||
@ -139,11 +149,6 @@ main (int argc, char *argv[])
|
|||||||
G_CALLBACK (on_resize),
|
G_CALLBACK (on_resize),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_signal_connect (stage,
|
|
||||||
"event",
|
|
||||||
G_CALLBACK (on_event),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
clutter_main ();
|
clutter_main ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -16,13 +16,13 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
# 02110-1301 USA
|
# 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
|
TESTS = eek-simple-test eek-xkb-test
|
||||||
noinst_PROGRAMS = $(TESTS)
|
noinst_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
eek_simple_test_SOURCES = eek-simple-test.c
|
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_SOURCES = eek-xkb-test.c
|
||||||
eek_xkb_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la
|
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
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
* 02110-1301 USA
|
* 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "eek-simple-keyboard.h"
|
#include "eek.h"
|
||||||
|
#include "eek-clutter.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_create (void)
|
test_create (void)
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
EekSection *section;
|
EekSection *section;
|
||||||
EekKey *key;
|
EekKey *key0, *key1;
|
||||||
|
|
||||||
EekOutline outline = {45.0, NULL, 0};
|
keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
|
||||||
EekBounds bounds = {0.1, 0.2, 3.0, 4.0};
|
section = eek_keyboard_create_section (keyboard);
|
||||||
EekKeysymMatrix *matrix;
|
g_assert (EEK_IS_SECTION(section));
|
||||||
GValue value = {0};
|
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
||||||
gint iv;
|
key0 = eek_section_create_key (section, 0, 0);
|
||||||
const gchar *sv;
|
g_assert (EEK_IS_KEY(key0));
|
||||||
gpointer bv;
|
key1 = eek_section_create_key (section, 1, 0);
|
||||||
guint keysyms[] = {'a', 'b', 'c', 'd', 'e', 'f'};
|
g_assert (EEK_IS_KEY(key1));
|
||||||
|
}
|
||||||
|
|
||||||
keyboard = eek_simple_keyboard_new ();
|
static void
|
||||||
g_assert (keyboard);
|
test_create_clutter (void)
|
||||||
g_assert (g_object_is_floating (keyboard));
|
{
|
||||||
|
EekKeyboard *keyboard;
|
||||||
|
EekSection *section;
|
||||||
|
EekKey *key0, *key1;
|
||||||
|
ClutterActor *actor;
|
||||||
|
|
||||||
section = eek_keyboard_create_section (keyboard,
|
keyboard = eek_clutter_keyboard_new (640.0, 480.0);
|
||||||
"test-section",
|
section = eek_keyboard_create_section (keyboard);
|
||||||
45,
|
g_assert (EEK_IS_SECTION(section));
|
||||||
&bounds);
|
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
||||||
g_assert (section);
|
key0 = eek_section_create_key (section, 0, 0);
|
||||||
g_value_init (&value, G_TYPE_STRING);
|
g_assert (EEK_IS_KEY(key0));
|
||||||
g_object_get_property (G_OBJECT(section), "name", &value);
|
key1 = eek_section_create_key (section, 1, 0);
|
||||||
sv = g_value_get_string (&value);
|
g_assert (EEK_IS_KEY(key1));
|
||||||
g_assert_cmpstr (sv, ==, "test-section");
|
actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard));
|
||||||
g_value_unset (&value);
|
g_assert (CLUTTER_IS_ACTOR(actor));
|
||||||
|
|
||||||
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);
|
|
||||||
g_object_unref (keyboard);
|
g_object_unref (keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,5 +64,7 @@ main (int argc, char **argv)
|
|||||||
g_type_init ();
|
g_type_init ();
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
g_test_add_func ("/eek-simple-test/create", test_create);
|
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 ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user