eekkey: Dropped in favor of Button
Each Button has a KeyState, which may be shared with other buttons. The list of pressed and locked buttons is used as a list of keys, causing a search for the button in the current view.
This commit is contained in:
@ -35,7 +35,6 @@
|
||||
#include "eek-renderer.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
#include "eek-gtk-keyboard.h"
|
||||
@ -64,18 +63,16 @@ typedef struct _EekGtkKeyboardPrivate
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
||||
|
||||
static void on_key_pressed (EekKey *key, EekKeyboard *view,
|
||||
static void on_button_pressed (struct squeek_button *button, EekKeyboard *view,
|
||||
EekGtkKeyboard *self);
|
||||
static void on_key_released (EekKey *key,
|
||||
static void on_button_released (struct squeek_button *button,
|
||||
EekKeyboard *view,
|
||||
EekGtkKeyboard *self);
|
||||
static void render_pressed_key (GtkWidget *widget, EekKeyboard *view,
|
||||
EekKey *key);
|
||||
static void render_locked_key (GtkWidget *widget,
|
||||
EekKeyboard *view,
|
||||
EekKey *key);
|
||||
static void render_released_key (GtkWidget *widget,
|
||||
EekKey *key);
|
||||
static void render_pressed_button (GtkWidget *widget, struct button_place *place);
|
||||
static void render_locked_button (GtkWidget *widget,
|
||||
struct button_place *place);
|
||||
static void render_released_button (GtkWidget *widget,
|
||||
struct squeek_button *button);
|
||||
|
||||
static void
|
||||
eek_gtk_keyboard_real_realize (GtkWidget *self)
|
||||
@ -117,15 +114,23 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
||||
EekKeyboard *view = priv->keyboard->views[priv->keyboard->level];
|
||||
|
||||
/* redraw pressed key */
|
||||
const GList *list = priv->keyboard->pressed_keys;
|
||||
const GList *list = priv->keyboard->pressed_buttons;
|
||||
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||
render_pressed_key (self, view, head->data);
|
||||
struct button_place place = eek_keyboard_get_button_by_state(
|
||||
view, squeek_button_get_key(head->data)
|
||||
);
|
||||
render_pressed_button (self, &place);
|
||||
}
|
||||
|
||||
/* redraw locked key */
|
||||
list = priv->keyboard->locked_keys;
|
||||
list = priv->keyboard->locked_buttons;
|
||||
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||
render_locked_key (self, view, ((EekModifierKey *)head->data)->key);
|
||||
struct button_place place = eek_keyboard_get_button_by_state(
|
||||
view, squeek_button_get_key(
|
||||
((EekModifierKey *)head->data)->button
|
||||
)
|
||||
);
|
||||
render_locked_button (self, &place);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -152,11 +157,11 @@ static void depress(EekGtkKeyboard *self,
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKeyboard *view = level_keyboard_current(priv->keyboard);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, view, x, y);
|
||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
||||
|
||||
if (key) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, view, self);
|
||||
if (button) {
|
||||
eek_keyboard_press_button(priv->keyboard, button, time);
|
||||
on_button_pressed(button, view, self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,32 +169,32 @@ static void drag(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKeyboard *view = level_keyboard_current(priv->keyboard);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, view, x, y);
|
||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
||||
GList *list, *head;
|
||||
|
||||
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
|
||||
if (key) {
|
||||
if (button) {
|
||||
gboolean found = FALSE;
|
||||
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
if (head->data == key) {
|
||||
if (head->data == button) {
|
||||
found = TRUE;
|
||||
} else {
|
||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||
on_key_released(key, view, self);
|
||||
eek_keyboard_release_button(priv->keyboard, head->data, time);
|
||||
on_button_released(button, view, self);
|
||||
}
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
if (!found) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, view, self);
|
||||
eek_keyboard_press_button(priv->keyboard, button, time);
|
||||
on_button_pressed(button, view, self);
|
||||
}
|
||||
} else {
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||
on_key_released(EEK_KEY(head->data), view, self);
|
||||
eek_keyboard_release_button(priv->keyboard, button, time);
|
||||
on_button_released(button, view, self);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
@ -200,11 +205,11 @@ static void release(EekGtkKeyboard *self, guint32 time) {
|
||||
|
||||
EekKeyboard *view = level_keyboard_current(priv->keyboard);
|
||||
|
||||
GList *list = g_list_copy(priv->keyboard->pressed_keys);
|
||||
GList *list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
for (GList *head = list; head; head = g_list_next (head)) {
|
||||
EekKey *key = EEK_KEY(head->data);
|
||||
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||
on_key_released(key, view, self);
|
||||
struct squeek_button *button = head->data;
|
||||
eek_keyboard_release_button(priv->keyboard, button, time);
|
||||
on_button_released(button, view, self);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
@ -287,7 +292,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
||||
elements, so that the default handler of
|
||||
EekKeyboard::key-released signal can remove elements from its
|
||||
internal copy */
|
||||
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
|
||||
g_signal_emit_by_name (head->data, "released");
|
||||
@ -309,11 +314,11 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKeyboard *view = level_keyboard_current(priv->keyboard);
|
||||
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer,
|
||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer,
|
||||
view,
|
||||
(gdouble)x,
|
||||
(gdouble)y);
|
||||
if (key) {
|
||||
if (button) {
|
||||
//struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
|
||||
const gchar *text = NULL; // FIXME
|
||||
if (text) {
|
||||
@ -369,7 +374,7 @@ eek_gtk_keyboard_dispose (GObject *object)
|
||||
if (priv->keyboard) {
|
||||
GList *list, *head;
|
||||
|
||||
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||
g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
|
||||
@ -452,9 +457,8 @@ eek_gtk_keyboard_new (LevelKeyboard *keyboard)
|
||||
}
|
||||
|
||||
static void
|
||||
render_pressed_key (GtkWidget *widget,
|
||||
EekKeyboard *view,
|
||||
EekKey *key)
|
||||
render_pressed_button (GtkWidget *widget,
|
||||
struct button_place *place)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
@ -464,7 +468,7 @@ render_pressed_key (GtkWidget *widget,
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_render_key (priv->renderer, cr, view, key, 1.0, TRUE);
|
||||
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
|
||||
/*
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
||||
*/
|
||||
@ -474,9 +478,7 @@ render_pressed_key (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
render_locked_key (GtkWidget *widget,
|
||||
EekKeyboard *view,
|
||||
EekKey *key)
|
||||
render_locked_button (GtkWidget *widget, struct button_place *place)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
@ -486,7 +488,7 @@ render_locked_key (GtkWidget *widget,
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_render_key (priv->renderer, cr, view, key, 1.0, TRUE);
|
||||
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
|
||||
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
@ -494,10 +496,10 @@ render_locked_key (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
render_released_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
render_released_button (GtkWidget *widget,
|
||||
struct squeek_button *button)
|
||||
{
|
||||
(void)key;
|
||||
(void)button;
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
@ -514,7 +516,7 @@ render_released_key (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_pressed (EekKey *key,
|
||||
on_button_pressed (struct squeek_button *button,
|
||||
EekKeyboard *view,
|
||||
EekGtkKeyboard *self)
|
||||
{
|
||||
@ -524,7 +526,14 @@ on_key_pressed (EekKey *key,
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_pressed_key (GTK_WIDGET(self), view, key);
|
||||
struct button_place place = {
|
||||
.button = button,
|
||||
.section = eek_keyboard_get_section(view, button),
|
||||
};
|
||||
if (!place.section) {
|
||||
return;
|
||||
}
|
||||
render_pressed_button (GTK_WIDGET(self), &place);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||
|
||||
#if HAVE_LIBCANBERRA
|
||||
@ -537,7 +546,7 @@ on_key_pressed (EekKey *key,
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_released (EekKey *key,
|
||||
on_button_released (struct squeek_button *button,
|
||||
EekKeyboard *view,
|
||||
EekGtkKeyboard *self)
|
||||
{
|
||||
@ -548,7 +557,7 @@ on_key_released (EekKey *key,
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_released_key (GTK_WIDGET(self), key);
|
||||
render_released_button (GTK_WIDGET(self), button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||
|
||||
#if HAVE_LIBCANBERRA
|
||||
|
||||
277
eek/eek-key.c
277
eek/eek-key.c
@ -1,277 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 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-key
|
||||
* @short_description: Base class of a key
|
||||
*
|
||||
* The #EekKeyClass class represents a key.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-section.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "src/keyboard.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
#include "eek-key.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_OREF,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekKeyPrivate
|
||||
{
|
||||
gulong oref; // UI outline reference
|
||||
struct squeek_key *state;
|
||||
} EekKeyPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
|
||||
|
||||
void
|
||||
eek_key_set_locked (EekKey *self, gboolean value)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
squeek_key_set_pressed(priv->state, value);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_finalize (GObject *object)
|
||||
{
|
||||
EekKey *self = EEK_KEY (object);
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
|
||||
squeek_key_free (priv->state);
|
||||
|
||||
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)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_OREF:
|
||||
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_OREF:
|
||||
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_class_init (EekKeyClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = eek_key_set_property;
|
||||
gobject_class->get_property = eek_key_get_property;
|
||||
gobject_class->finalize = eek_key_finalize;
|
||||
|
||||
/**
|
||||
* EekKey:oref:
|
||||
*
|
||||
* The outline id of #EekKey.
|
||||
*/
|
||||
pspec = g_param_spec_ulong ("oref",
|
||||
"Oref",
|
||||
"Outline id of the key",
|
||||
0, G_MAXULONG, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_OREF, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_init (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
priv->state = squeek_key_new (0);
|
||||
}
|
||||
|
||||
void eek_key_share_state(EekKey *self, struct squeek_key *state) {
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
priv->state = state;
|
||||
}
|
||||
/**
|
||||
* eek_key_set_keycode:
|
||||
* @key: an #EekKey
|
||||
* @keycode: keycode
|
||||
*
|
||||
* Set the keycode of @key to @keycode. Since typically the keycode
|
||||
* value is used to find a key in a keyboard by calling
|
||||
* eek_keyboard_find_key_by_keycode, it is not necessarily the same as
|
||||
* the X keycode but it should be unique in the keyboard @key belongs
|
||||
* to.
|
||||
*/
|
||||
void
|
||||
eek_key_set_keycode (EekKey *key,
|
||||
guint keycode)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY (key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
squeek_key_set_keycode(priv->state, keycode);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_keycode:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Get keycode of @key.
|
||||
* Returns: keycode or %EEK_INVALID_KEYCODE on failure
|
||||
*/
|
||||
guint
|
||||
eek_key_get_keycode (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return squeek_key_get_keycode(priv->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_symbol_at_index:
|
||||
* @key: an #EekKey
|
||||
* @group: group index of the symbol matrix
|
||||
* @level: level index of the symbol matrix
|
||||
* @fallback_group: fallback group index
|
||||
* @fallback_level: fallback level index
|
||||
*
|
||||
* Get the symbol at (@group, @level) in the symbol matrix of @key.
|
||||
* Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
|
||||
*/
|
||||
struct squeek_symbol*
|
||||
eek_key_get_symbol_at_index (EekKey *key,
|
||||
gint group)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
return squeek_key_get_symbol(priv->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_oref:
|
||||
* @key: an #EekKey
|
||||
* @oref: outline id of @key
|
||||
*
|
||||
* Set the outline id of @key to @oref.
|
||||
*/
|
||||
void
|
||||
eek_key_set_oref (EekKey *key,
|
||||
guint oref)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (priv->oref != oref) {
|
||||
priv->oref = oref;
|
||||
g_object_notify (G_OBJECT(key), "oref");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_oref:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Get the outline id of @key.
|
||||
* Returns: unsigned integer
|
||||
*/
|
||||
guint
|
||||
eek_key_get_oref (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY (key), 0);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return priv->oref;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_is_pressed:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Return %TRUE if key is marked as pressed.
|
||||
*/
|
||||
gboolean
|
||||
eek_key_is_pressed (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
|
||||
|
||||
EekKeyPrivate *priv = (EekKeyPrivate*)eek_key_get_instance_private (key);
|
||||
|
||||
return (bool)squeek_key_is_pressed(priv->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_is_locked:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Return %TRUE if key is marked as locked.
|
||||
*/
|
||||
gboolean
|
||||
eek_key_is_locked (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return (bool)squeek_key_is_locked(priv->state);
|
||||
}
|
||||
|
||||
void eek_key_set_pressed(EekKey *key, gboolean value)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
squeek_key_set_pressed(priv->state, value);
|
||||
}
|
||||
|
||||
struct squeek_key *eek_key_get_state(EekKey *key) {
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
return priv->state;
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 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
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_KEY_H
|
||||
#define EEK_KEY_H 1
|
||||
|
||||
#include "eek-element.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_KEY (eek_key_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
|
||||
|
||||
/**
|
||||
* EekKeyClass:
|
||||
* @pressed: class handler for #EekKey::pressed signal
|
||||
* @released: class handler for #EekKey::released signal
|
||||
* @locked: class handler for #EekKey::locked signal
|
||||
* @unlocked: class handler for #EekKey::unlocked signal
|
||||
* @cancelled: class handler for #EekKey::cancelled signal
|
||||
* @is_pressed: virtual function for getting whether the key is pressed
|
||||
* @is_locked: virtual function for getting whether the key is locked
|
||||
*/
|
||||
struct _EekKeyClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekElementClass parent_class;
|
||||
};
|
||||
|
||||
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);
|
||||
struct squeek_key *eek_key_get_state(EekKey *key);
|
||||
struct squeek_symbol *eek_key_get_symbol_at_index (EekKey *key,
|
||||
gint group);
|
||||
|
||||
void eek_key_set_oref (EekKey *key,
|
||||
guint oref);
|
||||
guint eek_key_get_oref (EekKey *key);
|
||||
|
||||
gboolean eek_key_is_pressed (EekKey *key);
|
||||
gboolean eek_key_is_locked (EekKey *key);
|
||||
void eek_key_set_pressed (EekKey *key,
|
||||
gboolean value);
|
||||
void
|
||||
eek_key_set_locked (EekKey *self, gboolean value);
|
||||
void eek_key_share_state(EekKey *self, struct squeek_key *state);
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEY_H */
|
||||
@ -31,7 +31,6 @@
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-enumtypes.h"
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "keymap.h"
|
||||
@ -81,7 +80,6 @@ eek_modifier_key_copy (EekModifierKey *modkey)
|
||||
void
|
||||
eek_modifier_key_free (EekModifierKey *modkey)
|
||||
{
|
||||
g_object_unref (modkey->key);
|
||||
g_slice_free (EekModifierKey, modkey);
|
||||
}
|
||||
|
||||
@ -129,30 +127,30 @@ eek_keyboard_get_property (GObject *object,
|
||||
/// and instead refer to the contained symbols
|
||||
static guint
|
||||
set_key_states (LevelKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
struct squeek_button *button,
|
||||
guint new_level)
|
||||
{
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
// Keys locking rules hardcoded for the time being...
|
||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
|
||||
// Lock the shift whenever it's pressed on the baselevel
|
||||
// TODO: need to lock shift on the destination level
|
||||
if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
|
||||
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
||||
modifier_key->modifiers = 0;
|
||||
modifier_key->key = g_object_ref (key);
|
||||
keyboard->locked_keys =
|
||||
g_list_prepend (keyboard->locked_keys, modifier_key);
|
||||
eek_key_set_locked(modifier_key->key, true);
|
||||
modifier_key->button = button;
|
||||
keyboard->locked_buttons =
|
||||
g_list_prepend (keyboard->locked_buttons, modifier_key);
|
||||
squeek_key_set_locked(key, true);
|
||||
}
|
||||
|
||||
if (keyboard->level == 1) {
|
||||
// Only shift is locked in this state, unlock on any key press
|
||||
for (GList *head = keyboard->locked_keys; head; ) {
|
||||
for (GList *head = keyboard->locked_buttons; head; ) {
|
||||
EekModifierKey *modifier_key = head->data;
|
||||
GList *next = g_list_next (head);
|
||||
keyboard->locked_keys =
|
||||
g_list_remove_link (keyboard->locked_keys, head);
|
||||
eek_key_set_locked(modifier_key->key, false);
|
||||
keyboard->locked_buttons =
|
||||
g_list_remove_link (keyboard->locked_buttons, head);
|
||||
squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
|
||||
g_list_free1 (head);
|
||||
head = next;
|
||||
}
|
||||
@ -163,13 +161,13 @@ set_key_states (LevelKeyboard *keyboard,
|
||||
|
||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
|
||||
static void
|
||||
set_level_from_press (LevelKeyboard *keyboard, EekKey *key)
|
||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
|
||||
{
|
||||
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
||||
guint level = keyboard->level;
|
||||
/* Handle non-emitting keys */
|
||||
if (key) {
|
||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||
if (button) {
|
||||
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
|
||||
if (g_strcmp0(name, "show_numbers") == 0) {
|
||||
level = 2;
|
||||
} else if (g_strcmp0(name, "show_letters") == 0) {
|
||||
@ -181,18 +179,17 @@ set_level_from_press (LevelKeyboard *keyboard, EekKey *key)
|
||||
}
|
||||
}
|
||||
|
||||
keyboard->level = set_key_states(keyboard, key, level);
|
||||
keyboard->level = set_key_states(keyboard, button, level);
|
||||
|
||||
eek_layout_update_layout(keyboard);
|
||||
}
|
||||
|
||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp) {
|
||||
eek_key_set_pressed(key, TRUE);
|
||||
keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
|
||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
squeek_key_set_pressed(key, TRUE);
|
||||
keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
|
||||
|
||||
struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
|
||||
key, 0
|
||||
);
|
||||
struct squeek_symbol *symbol = squeek_key_get_symbol(key);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
@ -201,32 +198,31 @@ void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timest
|
||||
|
||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
guint keycode = squeek_key_get_keycode (key);
|
||||
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
|
||||
}
|
||||
|
||||
void eek_keyboard_release_key(LevelKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
void eek_keyboard_release_button(LevelKeyboard *keyboard,
|
||||
struct squeek_button *button,
|
||||
guint32 timestamp) {
|
||||
for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
|
||||
if (head->data == key) {
|
||||
keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
|
||||
for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
|
||||
if (head->data == button) {
|
||||
keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head);
|
||||
g_list_free1 (head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
|
||||
key, 0);
|
||||
struct squeek_symbol *symbol = squeek_button_get_symbol(button);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
set_level_from_press (keyboard, key);
|
||||
set_level_from_press (keyboard, button);
|
||||
|
||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
guint keycode = squeek_key_get_keycode (squeek_button_get_key(button));
|
||||
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
|
||||
}
|
||||
@ -306,14 +302,14 @@ void level_keyboard_init(LevelKeyboard *self) {
|
||||
self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||
}
|
||||
|
||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash) {
|
||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_button_hash) {
|
||||
LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
|
||||
level_keyboard_init(keyboard);
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
keyboard->views[i] = views[i];
|
||||
}
|
||||
keyboard->manager = manager;
|
||||
keyboard->names = name_key_hash;
|
||||
keyboard->names = name_button_hash;
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
@ -325,8 +321,8 @@ LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *
|
||||
* Find an #EekKey whose name is @name.
|
||||
* Return value: (transfer none): #EekKey whose name is @name
|
||||
*/
|
||||
EekKey *
|
||||
eek_keyboard_find_key_by_name (LevelKeyboard *keyboard,
|
||||
struct squeek_button*
|
||||
eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
|
||||
const gchar *name)
|
||||
{
|
||||
return g_hash_table_lookup (keyboard->names, name);
|
||||
@ -386,15 +382,16 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard)
|
||||
|
||||
/* Iterate over the keys in the name-to-key hash table. */
|
||||
GHashTableIter iter;
|
||||
gchar *key_name;
|
||||
gpointer key_ptr;
|
||||
gchar *button_name;
|
||||
gpointer button_ptr;
|
||||
g_hash_table_iter_init(&iter, keyboard->names);
|
||||
|
||||
while (g_hash_table_iter_next(&iter, (gpointer)&key_name, &key_ptr)) {
|
||||
while (g_hash_table_iter_next(&iter, (gpointer)&button_name, &button_ptr)) {
|
||||
|
||||
gchar *current, *line;
|
||||
EekKey *key = EEK_KEY(key_ptr);
|
||||
guint keycode = eek_key_get_keycode(key);
|
||||
struct squeek_button *button = button_ptr;
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
guint keycode = squeek_key_get_keycode(key);
|
||||
|
||||
/* Don't include invalid keycodes in the keymap. */
|
||||
if (keycode == EEK_INVALID_KEYCODE)
|
||||
@ -402,7 +399,7 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard)
|
||||
|
||||
/* Append a key name-to-keycode definition to the keycodes section. */
|
||||
current = keycodes;
|
||||
line = g_strdup_printf(" <%s> = %i;\n", (char *)key_name, keycode);
|
||||
line = g_strdup_printf(" <%s> = %i;\n", (char *)button_name, keycode);
|
||||
|
||||
keycodes = g_strconcat(current, line, NULL);
|
||||
g_free(line);
|
||||
@ -410,8 +407,8 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard)
|
||||
|
||||
// FIXME: free
|
||||
const char *key_str = squeek_key_to_keymap_entry(
|
||||
(char*)key_name,
|
||||
eek_key_get_state(key)
|
||||
(char*)button_name,
|
||||
key
|
||||
);
|
||||
current = symbols;
|
||||
symbols = g_strconcat(current, key_str, NULL);
|
||||
@ -435,34 +432,57 @@ EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard)
|
||||
}
|
||||
|
||||
struct GetSectionData {
|
||||
const EekKey *key;
|
||||
const struct squeek_button *button;
|
||||
EekSection *section;
|
||||
const struct squeek_key *needle;
|
||||
};
|
||||
|
||||
gint check_right_key(EekElement *element, gpointer user_data) {
|
||||
EekKey *key = EEK_KEY(element);
|
||||
struct GetSectionData *data = user_data;
|
||||
if (key == data->key) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void find_key_in_section(EekElement *element, gpointer user_data) {
|
||||
void find_button_in_section(EekElement *element, gpointer user_data) {
|
||||
EekSection *section = EEK_SECTION(element);
|
||||
struct GetSectionData *data = user_data;
|
||||
if (eek_container_find(EEK_CONTAINER(section), check_right_key, &data)) {
|
||||
if (data->section) {
|
||||
return;
|
||||
}
|
||||
if (eek_section_find(section, data->button)) {
|
||||
data->section = section;
|
||||
}
|
||||
}
|
||||
|
||||
EekSection *eek_keyboard_get_section(EekKeyboard *keyboard,
|
||||
const EekKey *key) {
|
||||
const struct squeek_button *button) {
|
||||
struct GetSectionData data = {
|
||||
.key = key,
|
||||
.button = button,
|
||||
.section = NULL,
|
||||
};
|
||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), find_key_in_section, &data);
|
||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), find_button_in_section, &data);
|
||||
return data.section;
|
||||
}
|
||||
|
||||
void find_key_in_section(EekElement *element, gpointer user_data) {
|
||||
EekSection *section = EEK_SECTION(element);
|
||||
struct GetSectionData *data = user_data;
|
||||
if (data->button) {
|
||||
return;
|
||||
}
|
||||
data->button = eek_section_find_key(section, data->needle);
|
||||
if (data->button) {
|
||||
data->section = section;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: return multiple
|
||||
struct button_place eek_keyboard_get_button_by_state(EekKeyboard *keyboard,
|
||||
const struct squeek_key *key) {
|
||||
struct GetSectionData data = {
|
||||
.section = NULL,
|
||||
.button = NULL,
|
||||
.needle = key,
|
||||
};
|
||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), find_key_in_section, &data);
|
||||
struct button_place ret = {
|
||||
.section = data.section,
|
||||
.button = (struct squeek_button*)data.button,
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "eek-container.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-layout.h"
|
||||
#include "src/layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -113,7 +114,7 @@ struct _EekKeyboardClass
|
||||
struct _EekModifierKey {
|
||||
/*< public >*/
|
||||
EekModifierType modifiers;
|
||||
EekKey *key;
|
||||
struct squeek_button *button;
|
||||
};
|
||||
typedef struct _EekModifierKey EekModifierKey;
|
||||
|
||||
@ -126,10 +127,10 @@ struct _LevelKeyboard {
|
||||
size_t keymap_len; // length of the data inside keymap_fd
|
||||
GArray *outline_array;
|
||||
|
||||
GList *pressed_keys;
|
||||
GList *locked_keys;
|
||||
GList *pressed_buttons; // struct squeek_button*
|
||||
GList *locked_buttons; // struct squeek_button*
|
||||
|
||||
/* Map key names to key objects: */
|
||||
/* Map button names to button objects: */
|
||||
GHashTable *names;
|
||||
|
||||
guint id; // as a key to layout choices
|
||||
@ -157,11 +158,18 @@ EekSection *eek_keyboard_create_section
|
||||
(EekKeyboard *keyboard);
|
||||
EekSection *eek_keyboard_get_section
|
||||
(EekKeyboard *keyboard,
|
||||
const EekKey *key);
|
||||
EekKey *eek_keyboard_find_key_by_name
|
||||
(LevelKeyboard *keyboard,
|
||||
const struct squeek_button *button);
|
||||
struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard,
|
||||
const gchar *name);
|
||||
|
||||
/// Represents the path to the button within a view
|
||||
struct button_place {
|
||||
EekSection *section;
|
||||
struct squeek_button *button;
|
||||
};
|
||||
|
||||
struct button_place eek_keyboard_get_button_by_state(EekKeyboard *keyboard,
|
||||
const struct squeek_key *key);
|
||||
|
||||
EekOutline *level_keyboard_get_outline
|
||||
(LevelKeyboard *keyboard,
|
||||
@ -171,14 +179,14 @@ EekModifierKey *eek_modifier_key_copy
|
||||
void eek_modifier_key_free
|
||||
(EekModifierKey *modkey);
|
||||
|
||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||
void eek_keyboard_release_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
|
||||
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
|
||||
|
||||
gchar * eek_keyboard_get_keymap
|
||||
(LevelKeyboard *keyboard);
|
||||
|
||||
EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard);
|
||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash);
|
||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_button_hash);
|
||||
void level_keyboard_deinit(LevelKeyboard *self);
|
||||
void level_keyboard_free(LevelKeyboard *self);
|
||||
/* Create an #EekSection instance and append it to @keyboard. This
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
#include <string.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include "eek-key.h"
|
||||
#include "eek-section.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
@ -76,33 +75,33 @@ extern void _eek_rounded_polygon (cairo_t *cr,
|
||||
EekPoint *points,
|
||||
guint num_points);
|
||||
|
||||
static void eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
static void eek_renderer_real_render_button_label (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
EekKey *key);
|
||||
struct squeek_button *button);
|
||||
|
||||
static void invalidate (EekRenderer *renderer);
|
||||
static void render_key (EekRenderer *self,
|
||||
cairo_t *cr, EekKeyboard *view,
|
||||
EekKey *key,
|
||||
static void render_button (EekRenderer *self,
|
||||
cairo_t *cr, struct button_place *place,
|
||||
gboolean active);
|
||||
|
||||
struct _CreateKeyboardSurfaceCallbackData {
|
||||
cairo_t *cr;
|
||||
EekRenderer *renderer;
|
||||
EekKeyboard *view;
|
||||
EekSection *section;
|
||||
};
|
||||
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
|
||||
|
||||
static void
|
||||
create_keyboard_surface_key_callback (EekElement *element,
|
||||
create_keyboard_surface_button_callback (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct squeek_button *button = item;
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
EekBounds bounds;
|
||||
EekBounds bounds = squeek_button_get_bounds(button);
|
||||
|
||||
cairo_save (data->cr);
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
cairo_translate (data->cr, bounds.x, bounds.y);
|
||||
cairo_rectangle (data->cr,
|
||||
0.0,
|
||||
@ -110,7 +109,11 @@ create_keyboard_surface_key_callback (EekElement *element,
|
||||
bounds.width + 100,
|
||||
bounds.height + 100);
|
||||
cairo_clip (data->cr);
|
||||
render_key (data->renderer, data->cr, data->view, EEK_KEY(element), FALSE);
|
||||
struct button_place place = {
|
||||
.section = data->section,
|
||||
.button = button,
|
||||
};
|
||||
render_button (data->renderer, data->cr, &place, FALSE);
|
||||
|
||||
cairo_restore (data->cr);
|
||||
}
|
||||
@ -131,8 +134,9 @@ create_keyboard_surface_section_callback (EekElement *element,
|
||||
angle = eek_section_get_angle (EEK_SECTION(element));
|
||||
cairo_rotate (data->cr, angle * G_PI / 180);
|
||||
|
||||
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||
create_keyboard_surface_key_callback,
|
||||
data->section = EEK_SECTION(element);
|
||||
eek_section_foreach(EEK_SECTION(element),
|
||||
create_keyboard_surface_button_callback,
|
||||
data);
|
||||
|
||||
cairo_restore (data->cr);
|
||||
@ -185,22 +189,20 @@ render_keyboard_surface (EekRenderer *renderer, EekKeyboard *view)
|
||||
}
|
||||
|
||||
static void
|
||||
render_key_outline (EekRenderer *renderer,
|
||||
render_button_outline (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
struct squeek_button *button,
|
||||
gboolean active)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
EekOutline *outline;
|
||||
EekBounds bounds;
|
||||
guint oref;
|
||||
|
||||
oref = eek_key_get_oref (key);
|
||||
guint oref = squeek_button_get_oref(button);
|
||||
outline = level_keyboard_get_outline (priv->keyboard, oref);
|
||||
if (outline == NULL)
|
||||
return;
|
||||
|
||||
eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
|
||||
EekBounds bounds = squeek_button_get_bounds(button);
|
||||
gtk_style_context_set_state(priv->key_context,
|
||||
active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
|
||||
|
||||
@ -213,30 +215,26 @@ render_key_outline (EekRenderer *renderer,
|
||||
}
|
||||
|
||||
static void
|
||||
render_key (EekRenderer *self,
|
||||
render_button (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gboolean active)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekOutline *outline;
|
||||
cairo_surface_t *outline_surface;
|
||||
EekBounds bounds;
|
||||
guint oref;
|
||||
struct squeek_symbol *symbol;
|
||||
GHashTable *outline_surface_cache;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle extents = { 0, };
|
||||
EekColor foreground;
|
||||
|
||||
oref = eek_key_get_oref (key);
|
||||
guint oref = squeek_button_get_oref (place->button);
|
||||
outline = level_keyboard_get_outline (priv->keyboard, oref);
|
||||
if (outline == NULL)
|
||||
return;
|
||||
|
||||
/* render outline */
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
|
||||
EekBounds bounds = squeek_button_get_bounds(place->button);
|
||||
|
||||
if (active)
|
||||
outline_surface_cache = priv->active_outline_surface_cache;
|
||||
@ -260,8 +258,8 @@ render_key (EekRenderer *self,
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_save (cr);
|
||||
eek_renderer_apply_transformation_for_key (self, cr, view, key, 1.0, FALSE);
|
||||
render_key_outline (self, cr, key, active);
|
||||
eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE);
|
||||
render_button_outline (self, cr, place->button, active);
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
@ -276,7 +274,7 @@ render_key (EekRenderer *self,
|
||||
|
||||
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
|
||||
/* render icon (if any) */
|
||||
symbol = eek_key_get_symbol_at_index (key, 0);
|
||||
struct squeek_symbol *symbol = squeek_button_get_symbol(place->button);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
@ -312,7 +310,7 @@ render_key (EekRenderer *self,
|
||||
|
||||
/* render label */
|
||||
layout = pango_cairo_create_layout (cr);
|
||||
eek_renderer_real_render_key_label (self, layout, key);
|
||||
eek_renderer_real_render_button_label (self, layout, place->button);
|
||||
pango_layout_get_extents (layout, NULL, &extents);
|
||||
|
||||
cairo_save (cr);
|
||||
@ -348,23 +346,20 @@ render_key (EekRenderer *self,
|
||||
* normal keys for popups.
|
||||
*/
|
||||
void
|
||||
eek_renderer_apply_transformation_for_key (EekRenderer *self,
|
||||
eek_renderer_apply_transformation_for_button (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate)
|
||||
{
|
||||
EekSection *section;
|
||||
EekBounds bounds, rotated_bounds;
|
||||
gint angle;
|
||||
gdouble s;
|
||||
|
||||
eek_renderer_get_key_bounds (self, view, key, &bounds, FALSE);
|
||||
eek_renderer_get_key_bounds (self, view, key, &rotated_bounds, TRUE);
|
||||
eek_renderer_get_button_bounds (self, place, &bounds, FALSE);
|
||||
eek_renderer_get_button_bounds (self, place, &rotated_bounds, TRUE);
|
||||
|
||||
section = eek_keyboard_get_section(view, key);
|
||||
angle = eek_section_get_angle (section);
|
||||
angle = eek_section_get_angle (place->section);
|
||||
|
||||
cairo_scale (cr, scale, scale);
|
||||
if (rotate) {
|
||||
@ -378,19 +373,18 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self,
|
||||
}
|
||||
|
||||
static void
|
||||
eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
eek_renderer_real_render_button_label (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
EekKey *key)
|
||||
struct squeek_button *button)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
struct squeek_symbol *symbol;
|
||||
|
||||
const gchar *label;
|
||||
EekBounds bounds;
|
||||
PangoFontDescription *font;
|
||||
PangoLayoutLine *line;
|
||||
gdouble scale;
|
||||
|
||||
symbol = eek_key_get_symbol_at_index(key, 0);
|
||||
struct squeek_symbol *symbol = squeek_button_get_symbol(button);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
@ -415,7 +409,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
pango_font_description_set_size (priv->font, (gint)round(size * 0.6));
|
||||
}
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
|
||||
EekBounds bounds = squeek_button_get_bounds(button);
|
||||
scale = MIN((bounds.width - priv->border_width) / bounds.width,
|
||||
(bounds.height - priv->border_width) / bounds.height);
|
||||
|
||||
@ -434,16 +428,19 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
}
|
||||
|
||||
static void
|
||||
eek_renderer_real_render_key_outline (EekRenderer *self,
|
||||
eek_renderer_real_render_button_outline (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate)
|
||||
{
|
||||
cairo_save (cr);
|
||||
eek_renderer_apply_transformation_for_key (self, cr, view, key, scale, rotate);
|
||||
render_key_outline (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
|
||||
eek_renderer_apply_transformation_for_button (self, cr, place, scale, rotate);
|
||||
struct squeek_key *key = squeek_button_get_key(place->button);
|
||||
render_button_outline (
|
||||
self, cr, place->button,
|
||||
squeek_key_is_pressed(key) || squeek_key_is_locked (key)
|
||||
);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
@ -459,17 +456,16 @@ eek_renderer_real_render_key_outline (EekRenderer *self,
|
||||
* Renders a key separately from the normal keyboard rendering.
|
||||
*/
|
||||
static void
|
||||
eek_renderer_real_render_key (EekRenderer *self,
|
||||
eek_renderer_real_render_button (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekBounds bounds;
|
||||
|
||||
eek_renderer_get_key_bounds (self, view, key, &bounds, rotate);
|
||||
eek_renderer_get_button_bounds (self, place, &bounds, rotate);
|
||||
|
||||
cairo_save (cr);
|
||||
/* Because this function is called separately from the keyboard rendering
|
||||
@ -478,8 +474,12 @@ eek_renderer_real_render_key (EekRenderer *self,
|
||||
cairo_scale (cr, priv->scale, priv->scale);
|
||||
cairo_translate (cr, bounds.x, bounds.y);
|
||||
|
||||
eek_renderer_apply_transformation_for_key (self, cr, view, key, scale, rotate);
|
||||
render_key (self, cr, view, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
|
||||
eek_renderer_apply_transformation_for_button (self, cr, place, scale, rotate);
|
||||
struct squeek_key *key = squeek_button_get_key(place->button);
|
||||
render_button (
|
||||
self, cr, place,
|
||||
squeek_key_is_pressed(key) || squeek_key_is_locked (key)
|
||||
);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
@ -593,8 +593,8 @@ eek_renderer_class_init (EekRendererClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
klass->render_key_outline = eek_renderer_real_render_key_outline;
|
||||
klass->render_key = eek_renderer_real_render_key;
|
||||
klass->render_key_outline = eek_renderer_real_render_button_outline;
|
||||
klass->render_button = eek_renderer_real_render_button;
|
||||
klass->render_keyboard = eek_renderer_real_render_keyboard;
|
||||
|
||||
gobject_class->set_property = eek_renderer_set_property;
|
||||
@ -757,44 +757,43 @@ eek_renderer_get_size (EekRenderer *renderer,
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
eek_renderer_get_button_bounds (EekRenderer *renderer,
|
||||
struct button_place *place,
|
||||
EekBounds *bounds,
|
||||
gboolean rotate)
|
||||
{
|
||||
EekSection *section = eek_keyboard_get_section(view, key);
|
||||
EekBounds section_bounds, keyboard_bounds;
|
||||
gint angle = 0;
|
||||
EekPoint points[4], min, max;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (place);
|
||||
g_return_if_fail (bounds != NULL);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), bounds);
|
||||
eek_element_get_bounds (EEK_ELEMENT(section), §ion_bounds);
|
||||
EekBounds button_bounds = squeek_button_get_bounds(place->button);
|
||||
eek_element_get_bounds (EEK_ELEMENT(place->section), §ion_bounds);
|
||||
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)),
|
||||
&keyboard_bounds);
|
||||
|
||||
if (!rotate) {
|
||||
bounds->x += keyboard_bounds.x + section_bounds.x;
|
||||
bounds->y += keyboard_bounds.y + section_bounds.y;
|
||||
button_bounds.x += keyboard_bounds.x + section_bounds.x;
|
||||
button_bounds.y += keyboard_bounds.y + section_bounds.y;
|
||||
*bounds = button_bounds;
|
||||
return;
|
||||
}
|
||||
points[0].x = bounds->x;
|
||||
points[0].y = bounds->y;
|
||||
points[1].x = points[0].x + bounds->width;
|
||||
points[0].x = button_bounds.x;
|
||||
points[0].y = button_bounds.y;
|
||||
points[1].x = points[0].x + button_bounds.width;
|
||||
points[1].y = points[0].y;
|
||||
points[2].x = points[1].x;
|
||||
points[2].y = points[1].y + bounds->height;
|
||||
points[2].y = points[1].y + button_bounds.height;
|
||||
points[3].x = points[0].x;
|
||||
points[3].y = points[2].y;
|
||||
|
||||
if (rotate)
|
||||
angle = eek_section_get_angle (EEK_SECTION(section));
|
||||
angle = eek_section_get_angle (EEK_SECTION(place->section));
|
||||
|
||||
min = points[2];
|
||||
max = points[0];
|
||||
@ -847,19 +846,17 @@ eek_renderer_create_pango_layout (EekRenderer *renderer)
|
||||
void
|
||||
eek_renderer_render_key_outline (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (place);
|
||||
g_return_if_fail (scale >= 0.0);
|
||||
|
||||
EEK_RENDERER_GET_CLASS(renderer)->render_key_outline (renderer,
|
||||
cr,
|
||||
view,
|
||||
key,
|
||||
place,
|
||||
scale,
|
||||
rotate);
|
||||
}
|
||||
@ -899,19 +896,18 @@ eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_render_key (EekRenderer *renderer,
|
||||
eek_renderer_render_button (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (place);
|
||||
g_return_if_fail (scale >= 0.0);
|
||||
|
||||
EEK_RENDERER_GET_CLASS(renderer)->
|
||||
render_key (renderer, cr, view, key, scale, rotate);
|
||||
render_button (renderer, cr, place, scale, rotate);
|
||||
}
|
||||
|
||||
void
|
||||
@ -968,7 +964,7 @@ struct _FindKeyByPositionCallbackData {
|
||||
EekPoint point;
|
||||
EekPoint origin;
|
||||
gint angle;
|
||||
EekKey *key;
|
||||
struct squeek_button *button;
|
||||
EekRenderer *renderer;
|
||||
};
|
||||
typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData;
|
||||
@ -981,16 +977,19 @@ sign (EekPoint *p1, EekPoint *p2, EekPoint *p3)
|
||||
(p2->x - p3->x) * (p1->y - p3->y);
|
||||
}
|
||||
|
||||
static gint
|
||||
find_key_by_position_key_callback (EekElement *element,
|
||||
static void
|
||||
find_button_by_position_key_callback (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct squeek_button *button = item;
|
||||
FindKeyByPositionCallbackData *data = user_data;
|
||||
EekBounds bounds;
|
||||
if (data->button) {
|
||||
return;
|
||||
}
|
||||
EekPoint points[4];
|
||||
gboolean b1, b2, b3;
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
EekBounds bounds = squeek_button_get_bounds(button);
|
||||
|
||||
points[0].x = bounds.x;
|
||||
points[0].y = bounds.y;
|
||||
@ -1012,8 +1011,8 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
b3 = sign (&data->point, &points[2], &points[0]) < 0.0;
|
||||
|
||||
if (b1 == b2 && b2 == b3) {
|
||||
data->key = EEK_KEY(element);
|
||||
return 0;
|
||||
data->button = button;
|
||||
return;
|
||||
}
|
||||
|
||||
b1 = sign (&data->point, &points[2], &points[3]) < 0.0;
|
||||
@ -1021,17 +1020,15 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
b3 = sign (&data->point, &points[0], &points[2]) < 0.0;
|
||||
|
||||
if (b1 == b2 && b2 == b3) {
|
||||
data->key = EEK_KEY(element);
|
||||
return 0;
|
||||
data->button = button;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gint
|
||||
find_key_by_position_section_callback (EekElement *element,
|
||||
find_button_by_position_section_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekSection *section = EEK_SECTION(element);
|
||||
FindKeyByPositionCallbackData *data = user_data;
|
||||
EekBounds bounds;
|
||||
EekPoint origin;
|
||||
@ -1042,11 +1039,9 @@ find_key_by_position_section_callback (EekElement *element,
|
||||
data->origin.y += bounds.y;
|
||||
data->angle = eek_section_get_angle (EEK_SECTION(element));
|
||||
|
||||
eek_container_find (EEK_CONTAINER(element),
|
||||
find_key_by_position_key_callback,
|
||||
data);
|
||||
eek_section_foreach(section, find_button_by_position_key_callback, data);
|
||||
data->origin = origin;
|
||||
return data->key ? 0 : -1;
|
||||
return data->button ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1058,8 +1053,8 @@ find_key_by_position_section_callback (EekElement *element,
|
||||
* Return value: the key located at the position x, y in widget coordinates, or
|
||||
* NULL if no key can be found at that location
|
||||
**/
|
||||
EekKey *
|
||||
eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
struct squeek_button *
|
||||
eek_renderer_find_button_by_position (EekRenderer *renderer,
|
||||
EekKeyboard *view,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
@ -1086,11 +1081,11 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
data.point.y = y;
|
||||
data.origin.x = 0;
|
||||
data.origin.y = 0;
|
||||
data.key = NULL;
|
||||
data.button = NULL;
|
||||
data.renderer = renderer;
|
||||
|
||||
eek_container_find (EEK_CONTAINER(view),
|
||||
find_key_by_position_section_callback,
|
||||
find_button_by_position_section_callback,
|
||||
&data);
|
||||
return data.key;
|
||||
return data.button;
|
||||
}
|
||||
|
||||
@ -38,15 +38,13 @@ struct _EekRendererClass
|
||||
|
||||
void (* render_key_outline) (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void (* render_key) (EekRenderer *self,
|
||||
void (* render_button) (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
@ -74,8 +72,8 @@ void eek_renderer_set_allocation_size
|
||||
void eek_renderer_get_size (EekRenderer *renderer,
|
||||
gdouble *width,
|
||||
gdouble *height);
|
||||
void eek_renderer_get_key_bounds (EekRenderer *renderer, EekKeyboard *view,
|
||||
EekKey *key,
|
||||
void eek_renderer_get_button_bounds (EekRenderer *renderer,
|
||||
struct button_place *button,
|
||||
EekBounds *bounds,
|
||||
gboolean rotate);
|
||||
|
||||
@ -91,15 +89,14 @@ void eek_renderer_render_key_label (EekRenderer *renderer,
|
||||
|
||||
void eek_renderer_render_key_outline
|
||||
(EekRenderer *renderer,
|
||||
cairo_t *cr, EekKeyboard *view,
|
||||
EekKey *key,
|
||||
cairo_t *cr,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void eek_renderer_render_key (EekRenderer *renderer,
|
||||
void eek_renderer_render_button (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKeyboard *view,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
@ -123,14 +120,12 @@ void eek_renderer_get_foreground_color
|
||||
EekColor *color);
|
||||
void eek_renderer_set_border_width (EekRenderer *renderer,
|
||||
gdouble border_width);
|
||||
EekKey *eek_renderer_find_key_by_position
|
||||
(EekRenderer *renderer, EekKeyboard *view,
|
||||
struct squeek_button *eek_renderer_find_button_by_position(EekRenderer *renderer, EekKeyboard *view,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void eek_renderer_apply_transformation_for_key
|
||||
void eek_renderer_apply_transformation_for_button
|
||||
(EekRenderer *renderer,
|
||||
cairo_t *cr, EekKeyboard *view,
|
||||
EekKey *key,
|
||||
cairo_t *cr, struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-key.h"
|
||||
#include "layout.h"
|
||||
|
||||
#include "eek-section.h"
|
||||
|
||||
@ -46,41 +46,32 @@ typedef struct _EekSectionPrivate
|
||||
{
|
||||
gint angle;
|
||||
EekModifierType modifiers;
|
||||
GPtrArray *buttons; // struct squeek_button*
|
||||
} EekSectionPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_ELEMENT)
|
||||
|
||||
static EekKey *
|
||||
eek_section_real_create_key (EekSection *self,
|
||||
struct squeek_button*
|
||||
eek_section_create_button (EekSection *self,
|
||||
const gchar *name,
|
||||
gint keycode,
|
||||
guint keycode,
|
||||
guint oref)
|
||||
{
|
||||
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
||||
"name", name,
|
||||
NULL);
|
||||
g_return_val_if_fail (key, NULL);
|
||||
eek_key_set_keycode(key, keycode);
|
||||
eek_key_set_oref(key, oref);
|
||||
|
||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||
EEK_ELEMENT(key));
|
||||
|
||||
return key;
|
||||
struct squeek_button *button = squeek_button_new(keycode, oref);
|
||||
g_return_val_if_fail (button, NULL);
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
g_ptr_array_add(priv->buttons, button);
|
||||
return button;
|
||||
}
|
||||
|
||||
EekKey *eek_section_create_button(EekSection *self,
|
||||
struct squeek_button *eek_section_create_button_with_state(EekSection *self,
|
||||
const gchar *name,
|
||||
struct squeek_key *state) {
|
||||
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
||||
"name", name,
|
||||
NULL);
|
||||
g_return_val_if_fail (key, NULL);
|
||||
eek_key_share_state(key, state);
|
||||
|
||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||
EEK_ELEMENT(key));
|
||||
return key;
|
||||
struct squeek_button *source) {
|
||||
struct squeek_button *button = squeek_button_new_with_state(source);
|
||||
g_return_val_if_fail (button, NULL);
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
g_ptr_array_add(priv->buttons, button);
|
||||
return button;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -122,35 +113,13 @@ eek_section_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_child_added (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
(void)self;
|
||||
(void)element;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_child_removed (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
(void)self;
|
||||
(void)element;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_class_init (EekSectionClass *klass)
|
||||
{
|
||||
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
klass->create_key = eek_section_real_create_key;
|
||||
|
||||
/* signals */
|
||||
container_class->child_added = eek_section_real_child_added;
|
||||
container_class->child_removed = eek_section_real_child_removed;
|
||||
|
||||
gobject_class->set_property = eek_section_set_property;
|
||||
gobject_class->get_property = eek_section_get_property;
|
||||
gobject_class->finalize = eek_section_finalize;
|
||||
@ -173,7 +142,8 @@ eek_section_class_init (EekSectionClass *klass)
|
||||
static void
|
||||
eek_section_init (EekSection *self)
|
||||
{
|
||||
/* void */
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
priv->buttons = g_ptr_array_new();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,30 +183,6 @@ eek_section_get_angle (EekSection *section)
|
||||
return priv->angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_create_key:
|
||||
* @section: an #EekSection
|
||||
* @name: a name
|
||||
* @keycode: a keycode
|
||||
* @column: the column index of the key
|
||||
* @row: the row index of the key
|
||||
*
|
||||
* Create an #EekKey instance and append it to @section. This
|
||||
* function is rarely called by application but called by #EekLayout
|
||||
* implementation.
|
||||
*/
|
||||
EekKey *
|
||||
eek_section_create_key (EekSection *section,
|
||||
const gchar *name,
|
||||
guint keycode,
|
||||
guint oref)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||
return eek_section_real_create_key (section,
|
||||
name,
|
||||
keycode, oref);
|
||||
}
|
||||
|
||||
const double keyspacing = 4.0;
|
||||
|
||||
struct keys_info {
|
||||
@ -245,13 +191,14 @@ struct keys_info {
|
||||
double biggest_height;
|
||||
};
|
||||
|
||||
/// Set button size to match the outline. Reset position
|
||||
static void
|
||||
keysizer(EekElement *element, gpointer user_data)
|
||||
buttonsizer(gpointer item, gpointer user_data)
|
||||
{
|
||||
EekKey *key = EEK_KEY(element);
|
||||
struct squeek_button *button = item;
|
||||
|
||||
LevelKeyboard *keyboard = user_data;
|
||||
uint oref = eek_key_get_oref (key);
|
||||
uint oref = squeek_button_get_oref(button);
|
||||
EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
|
||||
if (outline && outline->num_points > 0) {
|
||||
double minx = outline->points[0].x;
|
||||
@ -272,21 +219,23 @@ keysizer(EekElement *element, gpointer user_data)
|
||||
maxy = p.y;
|
||||
}
|
||||
}
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
key_bounds.height = maxy - miny;
|
||||
key_bounds.width = maxx - minx;
|
||||
eek_element_set_bounds(element, &key_bounds);
|
||||
EekBounds key_bounds = {
|
||||
.height = maxy - miny,
|
||||
.width = maxx - minx,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
};
|
||||
squeek_button_set_bounds(button, key_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keycounter (EekElement *element, gpointer user_data)
|
||||
buttoncounter (gpointer item, gpointer user_data)
|
||||
{
|
||||
struct squeek_button *button = item;
|
||||
struct keys_info *data = user_data;
|
||||
data->count++;
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
EekBounds key_bounds = squeek_button_get_bounds(button);
|
||||
data->total_width += key_bounds.width;
|
||||
if (key_bounds.height > data->biggest_height) {
|
||||
data->biggest_height = key_bounds.height;
|
||||
@ -294,30 +243,63 @@ keycounter (EekElement *element, gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
keyplacer(EekElement *element, gpointer user_data)
|
||||
buttonplacer(gpointer item, gpointer user_data)
|
||||
{
|
||||
struct squeek_button *button = item;
|
||||
double *current_offset = user_data;
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
EekBounds key_bounds = squeek_button_get_bounds(button);
|
||||
key_bounds.x = *current_offset;
|
||||
key_bounds.y = 0;
|
||||
eek_element_set_bounds(element, &key_bounds);
|
||||
squeek_button_set_bounds(button, key_bounds);
|
||||
*current_offset += key_bounds.width + keyspacing;
|
||||
}
|
||||
|
||||
void
|
||||
eek_section_place_keys(EekSection *section, LevelKeyboard *keyboard)
|
||||
{
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (section);
|
||||
|
||||
g_ptr_array_foreach(priv->buttons, buttonsizer, keyboard);
|
||||
|
||||
struct keys_info keyinfo = {0};
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
|
||||
g_ptr_array_foreach(priv->buttons, buttoncounter, &keyinfo);
|
||||
|
||||
EekBounds section_bounds = {0};
|
||||
eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
|
||||
|
||||
double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
|
||||
g_ptr_array_foreach(priv->buttons, buttonplacer, &key_offset);
|
||||
|
||||
section_bounds.height = keyinfo.biggest_height;
|
||||
eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
|
||||
}
|
||||
|
||||
void eek_section_foreach (EekSection *section,
|
||||
GFunc func,
|
||||
gpointer user_data) {
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (section);
|
||||
g_ptr_array_foreach(priv->buttons, func, user_data);
|
||||
}
|
||||
|
||||
gboolean eek_section_find(EekSection *section,
|
||||
const struct squeek_button *button) {
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (section);
|
||||
return g_ptr_array_find(priv->buttons, button, NULL);
|
||||
}
|
||||
|
||||
static gboolean button_has_key(gconstpointer buttonptr, gconstpointer keyptr) {
|
||||
const struct squeek_button *button = buttonptr;
|
||||
const struct squeek_key *key = keyptr;
|
||||
return squeek_button_has_key((struct squeek_button*)button, key) != 0;
|
||||
}
|
||||
|
||||
struct squeek_button *eek_section_find_key(EekSection *section,
|
||||
const struct squeek_key *key) {
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (section);
|
||||
guint index;
|
||||
gboolean ret = g_ptr_array_find_with_equal_func(priv->buttons, key, button_has_key, &index);
|
||||
if (ret) {
|
||||
return g_ptr_array_index(priv->buttons, index);
|
||||
}
|
||||
return NULL;// TODO: store keys in locked_keys, pressed_keys
|
||||
}
|
||||
|
||||
@ -30,11 +30,12 @@
|
||||
#include "eek-types.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "src/keyboard.h"
|
||||
#include "src/layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_SECTION (eek_section_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekElement)
|
||||
|
||||
/**
|
||||
* EekSectionClass:
|
||||
@ -51,13 +52,7 @@ G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
|
||||
struct _EekSectionClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekContainerClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
EekKey *(* create_key) (EekSection *self,
|
||||
const gchar *name,
|
||||
gint keycode,
|
||||
guint oref);
|
||||
EekElementClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
@ -70,13 +65,21 @@ void eek_section_set_angle (EekSection *section,
|
||||
gint angle);
|
||||
gint eek_section_get_angle (EekSection *section);
|
||||
|
||||
EekKey *eek_section_create_key (EekSection *section,
|
||||
struct squeek_button *eek_section_create_button (EekSection *section,
|
||||
const gchar *name,
|
||||
guint keycode, guint oref);
|
||||
EekKey *eek_section_create_button(EekSection *self,
|
||||
struct squeek_button *eek_section_create_button_with_state(EekSection *self,
|
||||
const gchar *name,
|
||||
struct squeek_key *state);
|
||||
struct squeek_button *source);
|
||||
void eek_section_place_keys (EekSection *section, LevelKeyboard *keyboard);
|
||||
void eek_section_foreach (EekSection *section,
|
||||
GFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean eek_section_find(EekSection *section,
|
||||
const struct squeek_button *button);
|
||||
|
||||
struct squeek_button *eek_section_find_key(EekSection *section,
|
||||
const struct squeek_key *key);
|
||||
G_END_DECLS
|
||||
#endif /* EEK_SECTION_H */
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "src/keyboard.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
@ -68,7 +67,7 @@ static GList *parse_prerequisites
|
||||
(const gchar *path,
|
||||
GError **error);
|
||||
static gboolean parse_geometry (const gchar *path,
|
||||
EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash,
|
||||
EekKeyboard **views, GArray *outline_array, GHashTable *name_button_hash,
|
||||
GError **error);
|
||||
static gboolean parse_symbols_with_prerequisites
|
||||
(const gchar *keyboards_dir,
|
||||
@ -236,7 +235,6 @@ struct _GeometryParseData {
|
||||
EekKeyboard **views;
|
||||
guint view_idx;
|
||||
EekSection *section;
|
||||
EekKey *key;
|
||||
gint num_rows;
|
||||
EekOrientation orientation;
|
||||
gdouble corner_radius;
|
||||
@ -250,14 +248,14 @@ struct _GeometryParseData {
|
||||
|
||||
GArray *outline_array;
|
||||
|
||||
GHashTable *name_key_hash; // char* -> EekKey*
|
||||
GHashTable *name_button_hash; // char* -> struct squeek_button*
|
||||
GHashTable *keyname_oref_hash; // char* -> guint
|
||||
GHashTable *outlineid_oref_hash; // char* -> guint
|
||||
};
|
||||
typedef struct _GeometryParseData GeometryParseData;
|
||||
|
||||
static GeometryParseData *
|
||||
geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray *outline_array)
|
||||
geometry_parse_data_new (EekKeyboard **views, GHashTable *name_button_hash, GArray *outline_array)
|
||||
{
|
||||
GeometryParseData *data = g_slice_new0 (GeometryParseData);
|
||||
|
||||
@ -274,7 +272,7 @@ geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray
|
||||
g_free,
|
||||
NULL);
|
||||
|
||||
data->name_key_hash = name_key_hash;
|
||||
data->name_button_hash = name_button_hash;
|
||||
data->text = g_string_sized_new (BUFSIZE);
|
||||
data->keycode = 8;
|
||||
return data;
|
||||
@ -418,15 +416,16 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
g_strdup(name),
|
||||
GUINT_TO_POINTER(oref));
|
||||
|
||||
EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
|
||||
struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
|
||||
// never gets used! this section gets executed before any buttons get defined
|
||||
if (key) {
|
||||
if (button) {
|
||||
if (keycode_name != NULL) {
|
||||
// This sets the keycode for all buttons,
|
||||
// since they share state
|
||||
// TODO: get rid of this in the parser;
|
||||
// this belongs after keymap is defined
|
||||
eek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
squeek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,31 +558,30 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
||||
}
|
||||
|
||||
gchar *name = g_strndup (&text[start], end - start);
|
||||
EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
|
||||
if (!key) {
|
||||
struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
|
||||
if (!button) {
|
||||
// Save button name together with its level,
|
||||
// to account for buttons with the same name in multiple levels
|
||||
guint keycode = data->keycode++;
|
||||
|
||||
guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name));
|
||||
// default value gives idx 0, which is guaranteed to be occupied
|
||||
key = eek_section_create_key (data->section,
|
||||
button = eek_section_create_button (data->section,
|
||||
name,
|
||||
keycode,
|
||||
oref);
|
||||
g_hash_table_insert (data->name_key_hash,
|
||||
g_hash_table_insert (data->name_button_hash,
|
||||
g_strdup(name),
|
||||
key);
|
||||
button);
|
||||
} else {
|
||||
EekKey *new_key = eek_section_create_button(data->section, name, eek_key_get_state(key));
|
||||
if (!new_key) {
|
||||
struct squeek_button *new_button = eek_section_create_button_with_state(data->section, name, button);
|
||||
if (!new_button) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"Couldn't create a shared button");
|
||||
return;
|
||||
}
|
||||
eek_key_set_oref(new_key, eek_key_get_oref(key));
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,11 +734,11 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
||||
if (g_strcmp0 (element_name, "symbol") == 0) {
|
||||
|
||||
gchar *name = text;
|
||||
EekKey *key = eek_keyboard_find_key_by_name (data->keyboard,
|
||||
struct squeek_button *button = eek_keyboard_find_button_by_name (data->keyboard,
|
||||
name);
|
||||
if (key) {
|
||||
if (button) {
|
||||
squeek_key_add_symbol(
|
||||
eek_key_get_state(key),
|
||||
squeek_button_get_key(button),
|
||||
element_name,
|
||||
text,
|
||||
data->keyval,
|
||||
@ -887,8 +885,8 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||
|
||||
GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||
|
||||
// char* -> EekKey*
|
||||
GHashTable *name_key_hash =
|
||||
// char* -> struct squeek_button*
|
||||
GHashTable *name_button_hash =
|
||||
g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
@ -897,7 +895,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||
EekKeyboard *views[4] = {0};
|
||||
|
||||
GError *error = NULL;
|
||||
retval = parse_geometry (path, views, outline_array, name_key_hash, &error);
|
||||
retval = parse_geometry (path, views, outline_array, name_button_hash, &error);
|
||||
g_free (path);
|
||||
if (!retval) {
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
@ -911,7 +909,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||
}
|
||||
|
||||
|
||||
LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_key_hash);
|
||||
LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_button_hash);
|
||||
|
||||
keyboard->outline_array = outline_array;
|
||||
// FIXME: are symbols shared betwen views?
|
||||
@ -1129,7 +1127,7 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash, GError **error)
|
||||
parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_button_hash, GError **error)
|
||||
{
|
||||
GeometryParseData *data;
|
||||
GMarkupParseContext *pcontext;
|
||||
@ -1146,7 +1144,7 @@ parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, G
|
||||
if (input == NULL)
|
||||
return FALSE;
|
||||
|
||||
data = geometry_parse_data_new (views, name_key_hash, outline_array);
|
||||
data = geometry_parse_data_new (views, name_button_hash, outline_array);
|
||||
pcontext = g_markup_parse_context_new (&geometry_parser,
|
||||
0,
|
||||
data,
|
||||
@ -1357,7 +1355,7 @@ validate (const gchar **valid_path_list,
|
||||
GSList *element_stack,
|
||||
GError **error)
|
||||
{
|
||||
gint i;
|
||||
guint i;
|
||||
gchar *element_path;
|
||||
GSList *head, *p;
|
||||
GString *string;
|
||||
|
||||
Reference in New Issue
Block a user