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)
 | 
					-- Caribou layout engine (XML)
 | 
				
			||||||
-- matchbox-keyboard layout engine (XML)
 | 
					-- matchbox-keyboard layout engine (XML)
 | 
				
			||||||
-- delay initialization of XKB and XKL layouts
 | 
					-- 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
 | 
					-- add mechanism to change appearances (colors?) of UI widgets
 | 
				
			||||||
   depending on modifier states
 | 
					   depending on modifier states
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,7 @@ libeek_la_SOURCES = \
 | 
				
			|||||||
	eek-unicode-keysym-labels.h \
 | 
						eek-unicode-keysym-labels.h \
 | 
				
			||||||
	eek-keyname-keysym-labels.h
 | 
						eek-keyname-keysym-labels.h
 | 
				
			||||||
libeek_la_CFLAGS = $(GOBJECT2_CFLAGS)
 | 
					libeek_la_CFLAGS = $(GOBJECT2_CFLAGS)
 | 
				
			||||||
libeek_la_LIBADD = $(GOBJECT2_LIBS)
 | 
					libeek_la_LIBADD = $(GOBJECT2_LIBS) -lm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if HAVE_CLUTTER
 | 
					if HAVE_CLUTTER
 | 
				
			||||||
libeek_clutter_la_SOURCES = \
 | 
					libeek_clutter_la_SOURCES = \
 | 
				
			||||||
 | 
				
			|||||||
@ -231,23 +231,16 @@ eek_container_find (EekContainer  *container,
 | 
				
			|||||||
                                                     user_data);
 | 
					                                                     user_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _FbpData
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekKey *key;
 | 
					 | 
				
			||||||
    gint x, y;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct _FbpData FbpData;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static gint
 | 
					static gint
 | 
				
			||||||
compare_element_by_position (EekElement *element, gpointer user_data)
 | 
					compare_element_by_position (EekElement *element, gpointer user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
    FbpData *data = user_data;
 | 
					    EekPoint *point = user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_element_get_bounds (element, &bounds);
 | 
					    eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
    if (bounds.x <= data->x && bounds.y <= data->y &&
 | 
					    if (bounds.x <= point->x && bounds.y <= point->y &&
 | 
				
			||||||
        data->x <= (bounds.x + bounds.width) &&
 | 
					        point->x <= (bounds.x + bounds.width) &&
 | 
				
			||||||
        data->y <= (bounds.y + bounds.height))
 | 
					        point->y <= (bounds.y + bounds.height))
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -258,13 +251,13 @@ eek_container_find_by_position (EekContainer *container,
 | 
				
			|||||||
                                gdouble       y)
 | 
					                                gdouble       y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
    FbpData data;
 | 
					    EekPoint point;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
 | 
					    g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
 | 
				
			||||||
    eek_element_get_bounds (EEK_ELEMENT(container), &bounds);
 | 
					    eek_element_get_bounds (EEK_ELEMENT(container), &bounds);
 | 
				
			||||||
    data.x = x - bounds.x;
 | 
					    point.x = x - bounds.x;
 | 
				
			||||||
    data.y = y - bounds.y;
 | 
					    point.y = y - bounds.y;
 | 
				
			||||||
    return eek_container_find (container,
 | 
					    return eek_container_find (container,
 | 
				
			||||||
                               compare_element_by_position,
 | 
					                               compare_element_by_position,
 | 
				
			||||||
                               &data);
 | 
					                               &point);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -419,21 +419,14 @@ on_button_event (GtkWidget      *widget,
 | 
				
			|||||||
                 GdkEventButton *event,
 | 
					                 GdkEventButton *event,
 | 
				
			||||||
                 gpointer        user_data)
 | 
					                 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);
 | 
					    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
    gdouble x, y;
 | 
					    gdouble x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x = (gdouble)event->x / priv->scale;
 | 
					    x = (gdouble)event->x / priv->scale;
 | 
				
			||||||
    y = (gdouble)event->y / priv->scale;
 | 
					    y = (gdouble)event->y / priv->scale;
 | 
				
			||||||
    section = eek_container_find_by_position (EEK_CONTAINER(keyboard), x, y);
 | 
					    key = eek_keyboard_find_key_by_position (EEK_KEYBOARD(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);
 | 
					 | 
				
			||||||
    if (key)
 | 
					    if (key)
 | 
				
			||||||
        switch (event->type) {
 | 
					        switch (event->type) {
 | 
				
			||||||
        case GDK_BUTTON_PRESS:
 | 
					        case GDK_BUTTON_PRESS:
 | 
				
			||||||
@ -457,7 +450,6 @@ on_button_event (GtkWidget      *widget,
 | 
				
			|||||||
        default:
 | 
					        default:
 | 
				
			||||||
            return FALSE;
 | 
					            return FALSE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    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,
 | 
					    return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard,
 | 
				
			||||||
                                                                  keycode);
 | 
					                                                                  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);
 | 
					void        eek_keyboard_realize              (EekKeyboard *keyboard);
 | 
				
			||||||
EekKey     *eek_keyboard_find_key_by_keycode  (EekKeyboard *keyboard,
 | 
					EekKey     *eek_keyboard_find_key_by_keycode  (EekKeyboard *keyboard,
 | 
				
			||||||
                                               guint        keycode);
 | 
					                                               guint        keycode);
 | 
				
			||||||
 | 
					EekKey     *eek_keyboard_find_key_by_position (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                                               gdouble      x,
 | 
				
			||||||
 | 
					                                               gdouble      y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_KEYBOARD_H */
 | 
					#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,
 | 
					    return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section,
 | 
				
			||||||
                                                                keycode);
 | 
					                                                                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,
 | 
					EekKey *eek_section_find_key_by_keycode  (EekSection     *section,
 | 
				
			||||||
                                          guint           keycode);
 | 
					                                          guint           keycode);
 | 
				
			||||||
 | 
					EekKey *eek_section_find_key_by_position (EekSection     *section,
 | 
				
			||||||
 | 
					                                          gdouble         x,
 | 
				
			||||||
 | 
					                                          gdouble         y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_SECTION_H */
 | 
					#endif  /* EEK_SECTION_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,7 @@
 | 
				
			|||||||
#endif  /* HAVE_CONFIG_H */
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-types.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* EekKeysymMatrix */
 | 
					/* EekKeysymMatrix */
 | 
				
			||||||
static EekKeysymMatrix *
 | 
					static EekKeysymMatrix *
 | 
				
			||||||
@ -81,6 +82,19 @@ eek_point_get_type (void)
 | 
				
			|||||||
    return our_type;
 | 
					    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 */
 | 
					/* EekBounds */
 | 
				
			||||||
static EekBounds *
 | 
					static EekBounds *
 | 
				
			||||||
eek_bounds_copy (const EekBounds *bounds)
 | 
					eek_bounds_copy (const EekBounds *bounds)
 | 
				
			||||||
 | 
				
			|||||||
@ -80,6 +80,8 @@ typedef struct _EekPoint EekPoint;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define EEK_TYPE_POINT (eek_point_get_type ())
 | 
					#define EEK_TYPE_POINT (eek_point_get_type ())
 | 
				
			||||||
GType eek_point_get_type (void) G_GNUC_CONST;
 | 
					GType eek_point_get_type (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					void  eek_point_rotate   (EekPoint *point,
 | 
				
			||||||
 | 
					                          gint      angle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * EekBounds:
 | 
					 * EekBounds:
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user