libeek: add eek_keyboard_find_key_by_position().
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
									
									
									
									
								
							@ -13,7 +13,5 @@
 | 
			
		||||
-- Caribou layout engine (XML)
 | 
			
		||||
-- matchbox-keyboard layout engine (XML)
 | 
			
		||||
-- delay initialization of XKB and XKL layouts
 | 
			
		||||
-- add eek_keyboard_find_by_position(), that takes account of section
 | 
			
		||||
   rotation, in addition to eek_container_find_by_position()
 | 
			
		||||
-- add mechanism to change appearances (colors?) of UI widgets
 | 
			
		||||
   depending on modifier states
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,7 @@ libeek_la_SOURCES = \
 | 
			
		||||
	eek-unicode-keysym-labels.h \
 | 
			
		||||
	eek-keyname-keysym-labels.h
 | 
			
		||||
libeek_la_CFLAGS = $(GOBJECT2_CFLAGS)
 | 
			
		||||
libeek_la_LIBADD = $(GOBJECT2_LIBS)
 | 
			
		||||
libeek_la_LIBADD = $(GOBJECT2_LIBS) -lm
 | 
			
		||||
 | 
			
		||||
if HAVE_CLUTTER
 | 
			
		||||
libeek_clutter_la_SOURCES = \
 | 
			
		||||
 | 
			
		||||
@ -231,23 +231,16 @@ eek_container_find (EekContainer  *container,
 | 
			
		||||
                                                     user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct _FbpData
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    gint x, y;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _FbpData FbpData;
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
compare_element_by_position (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    FbpData *data = user_data;
 | 
			
		||||
    EekPoint *point = user_data;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    if (bounds.x <= data->x && bounds.y <= data->y &&
 | 
			
		||||
        data->x <= (bounds.x + bounds.width) &&
 | 
			
		||||
        data->y <= (bounds.y + bounds.height))
 | 
			
		||||
    if (bounds.x <= point->x && bounds.y <= point->y &&
 | 
			
		||||
        point->x <= (bounds.x + bounds.width) &&
 | 
			
		||||
        point->y <= (bounds.y + bounds.height))
 | 
			
		||||
        return 0;
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
@ -258,13 +251,13 @@ eek_container_find_by_position (EekContainer *container,
 | 
			
		||||
                                gdouble       y)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    FbpData data;
 | 
			
		||||
    EekPoint point;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(container), &bounds);
 | 
			
		||||
    data.x = x - bounds.x;
 | 
			
		||||
    data.y = y - bounds.y;
 | 
			
		||||
    point.x = x - bounds.x;
 | 
			
		||||
    point.y = y - bounds.y;
 | 
			
		||||
    return eek_container_find (container,
 | 
			
		||||
                               compare_element_by_position,
 | 
			
		||||
                               &data);
 | 
			
		||||
                               &point);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -419,21 +419,14 @@ on_button_event (GtkWidget      *widget,
 | 
			
		||||
                 GdkEventButton *event,
 | 
			
		||||
                 gpointer        user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekElement *keyboard = user_data, *section, *key;
 | 
			
		||||
    EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(user_data), *key;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gdouble x, y;
 | 
			
		||||
 | 
			
		||||
    x = (gdouble)event->x / priv->scale;
 | 
			
		||||
    y = (gdouble)event->y / priv->scale;
 | 
			
		||||
    section = eek_container_find_by_position (EEK_CONTAINER(keyboard), x, y);
 | 
			
		||||
    if (section) {
 | 
			
		||||
        eek_element_get_bounds (keyboard, &bounds);
 | 
			
		||||
        x -= bounds.x;
 | 
			
		||||
        y -= bounds.y;
 | 
			
		||||
        key = eek_container_find_by_position (EEK_CONTAINER(section),
 | 
			
		||||
                                              x,
 | 
			
		||||
                                              y);
 | 
			
		||||
    key = eek_keyboard_find_key_by_position (EEK_KEYBOARD(keyboard), x, y);
 | 
			
		||||
    if (key)
 | 
			
		||||
        switch (event->type) {
 | 
			
		||||
        case GDK_BUTTON_PRESS:
 | 
			
		||||
@ -457,7 +450,6 @@ on_button_event (GtkWidget      *widget,
 | 
			
		||||
        default:
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -484,3 +484,59 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
 | 
			
		||||
    return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard,
 | 
			
		||||
                                                                  keycode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
compare_section_by_position (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekSection *section = EEK_SECTION(element);
 | 
			
		||||
    EekPoint *point = user_data;
 | 
			
		||||
    gint angle;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekPoint rotated;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    rotated.x = point->x - bounds.x;
 | 
			
		||||
    rotated.y = point->y - bounds.y;
 | 
			
		||||
    angle = eek_section_get_angle (section);
 | 
			
		||||
    eek_point_rotate (&rotated, -angle);
 | 
			
		||||
 | 
			
		||||
    if (0 <= rotated.x && 0 <= rotated.y &&
 | 
			
		||||
        rotated.x <= bounds.width &&
 | 
			
		||||
        rotated.y <= bounds.height)
 | 
			
		||||
        return 0;
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekSection *
 | 
			
		||||
eek_keyboard_find_section_by_position (EekKeyboard *keyboard,
 | 
			
		||||
                                       gdouble      x,
 | 
			
		||||
                                       gdouble      y)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekPoint point;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    point.x = x - bounds.x;
 | 
			
		||||
    point.y = y - bounds.y;
 | 
			
		||||
    return eek_container_find (EEK_CONTAINER(keyboard),
 | 
			
		||||
                               compare_section_by_position,
 | 
			
		||||
                               &point);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_keyboard_find_key_by_position (EekKeyboard *keyboard,
 | 
			
		||||
                                   gdouble      x,
 | 
			
		||||
                                   gdouble      y)
 | 
			
		||||
{
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    section = eek_keyboard_find_section_by_position (keyboard, x, y);
 | 
			
		||||
    if (!section)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    x -= bounds.x;
 | 
			
		||||
    y -= bounds.y;
 | 
			
		||||
    return eek_section_find_key_by_position (section, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -99,6 +99,9 @@ void        eek_keyboard_set_layout          (EekKeyboard *keyboard,
 | 
			
		||||
void        eek_keyboard_realize              (EekKeyboard *keyboard);
 | 
			
		||||
EekKey     *eek_keyboard_find_key_by_keycode  (EekKeyboard *keyboard,
 | 
			
		||||
                                               guint        keycode);
 | 
			
		||||
EekKey     *eek_keyboard_find_key_by_position (EekKeyboard *keyboard,
 | 
			
		||||
                                               gdouble      x,
 | 
			
		||||
                                               gdouble      y);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
@ -438,3 +438,26 @@ eek_section_find_key_by_keycode (EekSection *section,
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section,
 | 
			
		||||
                                                                keycode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_section_find_key_by_position (EekSection *section,
 | 
			
		||||
                                  gdouble     x,
 | 
			
		||||
                                  gdouble     y)
 | 
			
		||||
{
 | 
			
		||||
    gint angle;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekPoint point;
 | 
			
		||||
    EekElement *key;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(section), &bounds);
 | 
			
		||||
    point.x = x - bounds.x;
 | 
			
		||||
    point.y = y - bounds.y;
 | 
			
		||||
    angle = eek_section_get_angle (section);
 | 
			
		||||
    eek_point_rotate (&point, -angle);
 | 
			
		||||
    key = eek_container_find_by_position (EEK_CONTAINER(section),
 | 
			
		||||
                                          point.x + bounds.x,
 | 
			
		||||
                                          point.y + bounds.y);
 | 
			
		||||
    if (!key)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return EEK_KEY(key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -107,6 +107,9 @@ EekKey *eek_section_create_key          (EekSection     *section,
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_find_key_by_keycode  (EekSection     *section,
 | 
			
		||||
                                          guint           keycode);
 | 
			
		||||
EekKey *eek_section_find_key_by_position (EekSection     *section,
 | 
			
		||||
                                          gdouble         x,
 | 
			
		||||
                                          gdouble         y);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_SECTION_H */
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
/* EekKeysymMatrix */
 | 
			
		||||
static EekKeysymMatrix *
 | 
			
		||||
@ -81,6 +82,19 @@ eek_point_get_type (void)
 | 
			
		||||
    return our_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_point_rotate (EekPoint *point, gint angle)
 | 
			
		||||
{
 | 
			
		||||
    EekPoint *p;
 | 
			
		||||
    gdouble r, phi;
 | 
			
		||||
 | 
			
		||||
    phi = atan2 (point->y, point->x);
 | 
			
		||||
    r = sqrt (point->x * point->x + point->y * point->y);
 | 
			
		||||
    phi += angle * M_PI / 180;
 | 
			
		||||
    point->x = r * cos (phi);
 | 
			
		||||
    point->y = r * sin (phi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* EekBounds */
 | 
			
		||||
static EekBounds *
 | 
			
		||||
eek_bounds_copy (const EekBounds *bounds)
 | 
			
		||||
 | 
			
		||||
@ -80,6 +80,8 @@ typedef struct _EekPoint EekPoint;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_POINT (eek_point_get_type ())
 | 
			
		||||
GType eek_point_get_type (void) G_GNUC_CONST;
 | 
			
		||||
void  eek_point_rotate   (EekPoint *point,
 | 
			
		||||
                          gint      angle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekBounds:
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user