diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 67cd3071..fac2ced7 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -924,7 +924,6 @@ struct _FindKeyByPositionCallbackData { EekPoint origin; gint angle; struct squeek_button *button; - EekRenderer *renderer; }; typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData; @@ -936,19 +935,12 @@ sign (EekPoint *p1, EekPoint *p2, EekPoint *p3) (p2->x - p3->x) * (p1->y - p3->y); } -static void -find_button_by_position_key_callback (struct squeek_button *button, - gpointer user_data) +uint32_t +eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_t angle) { - FindKeyByPositionCallbackData *data = user_data; - if (data->button) { - return; - } EekPoint points[4]; gboolean b1, b2, b3; - EekBounds bounds = squeek_button_get_bounds(button); - points[0].x = bounds.x; points[0].y = bounds.y; points[1].x = points[0].x + bounds.width; @@ -959,27 +951,27 @@ find_button_by_position_key_callback (struct squeek_button *button, points[3].y = points[2].y; for (uint i = 0; i < G_N_ELEMENTS(points); i++) { - eek_point_rotate (&points[i], data->angle); - points[i].x += data->origin.x; - points[i].y += data->origin.y; + eek_point_rotate (&points[i], angle); + points[i].x += origin.x; + points[i].y += origin.y; } - b1 = sign (&data->point, &points[0], &points[1]) < 0.0; - b2 = sign (&data->point, &points[1], &points[2]) < 0.0; - b3 = sign (&data->point, &points[2], &points[0]) < 0.0; + b1 = sign (&point, &points[0], &points[1]) < 0.0; + b2 = sign (&point, &points[1], &points[2]) < 0.0; + b3 = sign (&point, &points[2], &points[0]) < 0.0; if (b1 == b2 && b2 == b3) { - data->button = button; - return; + return 1; } - b1 = sign (&data->point, &points[2], &points[3]) < 0.0; - b2 = sign (&data->point, &points[3], &points[0]) < 0.0; - b3 = sign (&data->point, &points[0], &points[2]) < 0.0; + b1 = sign (&point, &points[2], &points[3]) < 0.0; + b2 = sign (&point, &points[3], &points[0]) < 0.0; + b3 = sign (&point, &points[0], &points[2]) < 0.0; if (b1 == b2 && b2 == b3) { - data->button = button; + return 1; } + return 0; } static void @@ -991,16 +983,7 @@ find_button_by_position_row_callback (gpointer item, if (data->button) { return; } - EekBounds bounds = squeek_row_get_bounds(row); - EekPoint origin; - - origin = data->origin; - data->origin.x += bounds.x; - data->origin.y += bounds.y; - data->angle = squeek_row_get_angle(row); - - squeek_row_foreach(row, find_button_by_position_key_callback, data); - data->origin = origin; + data->button = squeek_row_find_button_by_position(row, data->point, data->origin); } /** @@ -1041,7 +1024,6 @@ eek_renderer_find_button_by_position (EekRenderer *renderer, data.origin.x = 0; data.origin.y = 0; data.button = NULL; - data.renderer = renderer; eek_keyboard_foreach (view, find_button_by_position_row_callback, &data); diff --git a/src/layout.h b/src/layout.h index 3b46ae08..3f6e752e 100644 --- a/src/layout.h +++ b/src/layout.h @@ -24,6 +24,8 @@ uint32_t squeek_row_contains(struct squeek_row*, struct squeek_button *button); struct squeek_button* squeek_row_find_key(struct squeek_row*, struct squeek_key *state); +struct squeek_button *squeek_row_find_button_by_position(struct squeek_row *row, EekPoint point, EekPoint origin); + typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data); void squeek_row_foreach(struct squeek_row*, ButtonCallback callback, diff --git a/src/layout.rs b/src/layout.rs index 04d99f87..db695a8e 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -23,6 +23,14 @@ pub mod c { #[derive(Clone, Debug)] pub struct OutlineRef(u32); + /// Defined in eek-types.h + #[repr(C)] + #[derive(Clone, Debug)] + pub struct Point { + pub x: f64, + pub y: f64, + } + /// Defined in eek-types.h #[repr(C)] #[derive(Clone, Debug)] @@ -257,7 +265,7 @@ pub mod c { println!("{:?}", button); } - /// More complex procedures and algoithms which span multiple modules + /// Entry points for more complex procedures and algoithms which span multiple modules mod procedures { use super::*; @@ -270,6 +278,14 @@ pub mod c { keyboard: *const LevelKeyboard, outline: u32 ) -> Bounds; + + /// Checks if point falls within bounds, + /// which are relative to origin and rotated by angle (I think) + fn eek_are_bounds_inside (bounds: Bounds, + point: Point, + origin: Point, + angle: i32 + ) -> u32; } fn squeek_buttons_get_outlines( @@ -316,6 +332,36 @@ pub mod c { None => ptr::null_mut(), } } + + #[no_mangle] + pub extern "C" + fn squeek_row_find_button_by_position( + row: *mut Row, point: Point, origin: Point + ) -> *mut Button { + let row = unsafe { &mut *row }; + let row_bounds = row.bounds + .as_ref().expect("Missing bounds on row"); + let origin = Point { + x: origin.x + row_bounds.x, + y: origin.y + row_bounds.y, + }; + let angle = row.angle; + let result = row.buttons.iter_mut().find(|button| { + let bounds = button.bounds + .as_ref().expect("Missing bounds on button") + .clone(); + let point = point.clone(); + let origin = origin.clone(); + unsafe { + eek_are_bounds_inside(bounds, point, origin, angle) == 1 + } + }); + + match result { + Some(button) => button.as_mut() as *mut Button, + None => ptr::null_mut(), + } + } } #[cfg(test)] @@ -361,8 +407,10 @@ pub struct Button { const BUTTON_SPACING: f64 = 4.0; +/// The graphical representation of a row of buttons pub struct Row { buttons: Vec>, + /// Angle is not really used anywhere... angle: i32, bounds: Option, }