widget: Add widget_xy_to_relative helper

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
This commit is contained in:
Quentin Glidic 2017-05-30 12:37:11 +02:00
parent 6a750669d7
commit 30da7e587a
No known key found for this signature in database
GPG Key ID: AC203F96E2C34BB7
6 changed files with 48 additions and 46 deletions

View File

@ -72,15 +72,14 @@ typedef enum
/**
* @param widget The container widget itself
* @param type The widget type searched for
* @param x A pointer to the X coordination of the mouse event relative to @widget
* @param y A pointer to the Y coordination of the mouse event relative to @widget
* @param x The X coordination of the mouse event relative to @widget
* @param y The Y coordination of the mouse event relative to @widget
*
* This callback must only iterate over the children of a Widget, and return NULL if none of them is relevant.
* If one was found, @x and @y must be adjusted to be relative to this child.
*
* @returns A child widget if found, NULL otherwise
*/
typedef widget * ( *widget_find_mouse_target_cb )( widget *widget, WidgetType type, gint *x, gint *y );
typedef widget * ( *widget_find_mouse_target_cb )( widget *widget, WidgetType type, gint x, gint y );
/**
* @param widget The target widget
@ -198,6 +197,15 @@ int widget_get_y_pos ( widget *widget );
*/
int widget_get_x_pos ( widget *widget );
/**
* @param widget The widget handle
* @param x A pointer to the absolute X coordinates
* @param y A pointer to the absolute Y coordinates
*
* Will modify @x and @y to make them relative to @widget.
*/
void widget_xy_to_relative ( widget *widget, gint *x, gint *y );
/**
* @param widget The widget handle
*
@ -221,15 +229,14 @@ gboolean widget_need_redraw ( widget *wid );
/**
* @param wid The widget handle
* @param x A pointer to the x coordinate of the mouse event
* @param y A pointer to the y coordinate of the mouse event
* @param x The x coordinate of the mouse event
* @param y The y coordinate of the mouse event
*
* Get the widget that should handle a mouse event.
* @x and @y are adjusted to be relative to the widget.
*
* @returns returns the widget that should handle the mouse event.
*/
widget *widget_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y );
widget *widget_find_mouse_target ( widget *wid, WidgetType type, gint x, gint y );
/**
* @param wid The widget handle

View File

@ -1358,11 +1358,11 @@ gboolean rofi_view_trigger_action ( guint scope, gpointer user_data )
case SCOPE_MOUSE_SIDEBAR_MODI:
{
gint x = state->mouse.x, y = state->mouse.y;
widget *target = widget_find_mouse_target ( WIDGET ( state->main_window ), scope, &x, &y );
widget *target = widget_find_mouse_target ( WIDGET ( state->main_window ), scope, x, y );
if ( target == NULL ) {
return FALSE;
}
widget_xy_to_relative ( target, &x, &y );
return widget_trigger_action ( target, GPOINTER_TO_UINT ( user_data ), x, y );
}
}

View File

@ -277,7 +277,7 @@ static void box_resize ( widget *widget, short w, short h )
}
}
static widget *box_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
static widget *box_find_mouse_target ( widget *wid, WidgetType type, gint x, gint y )
{
box *b = (box *) wid;
for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) {
@ -285,13 +285,11 @@ static widget *box_find_mouse_target ( widget *wid, WidgetType type, gint *x, gi
if ( !child->enabled ) {
continue;
}
if ( widget_intersect ( child, *x, *y ) ) {
gint rx = *x - child->x;
gint ry = *y - child->y;
widget *target = widget_find_mouse_target ( child, type, &rx, &ry );
if ( widget_intersect ( child, x, y ) ) {
gint rx = x - child->x;
gint ry = y - child->y;
widget *target = widget_find_mouse_target ( child, type, rx, ry );
if ( target != NULL ) {
*x = rx;
*y = ry;
return target;
}
}

View File

@ -88,24 +88,18 @@ static void container_resize ( widget *widget, short w, short h )
}
}
static widget *container_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
static widget *container_find_mouse_target ( widget *wid, WidgetType type, gint x, gint y )
{
container *b = (container *) wid;
if ( !widget_intersect ( b->child, *x, *y ) ) {
if ( !widget_intersect ( b->child, x, y ) ) {
return NULL;
}
gint rx = *x - b->child->x;
gint ry = *y - b->child->y;
widget *target = widget_find_mouse_target ( b->child, type, &rx, &ry );
if ( target == NULL ) {
return NULL;
x -= b->child->x;
y -= b->child->y;
return widget_find_mouse_target ( b->child, type, x, y );
}
*x = rx;
*y = ry;
return target;
}
static gboolean container_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
{
container *b = (container *) wid;

View File

@ -302,37 +302,31 @@ static void listview_resize ( widget *wid, short w, short h )
widget_queue_redraw ( wid );
}
static widget *listview_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
static widget *listview_find_mouse_target ( widget *wid, WidgetType type, gint x, gint y )
{
widget *target = NULL;
gint rx, ry;
listview *lv = (listview *) wid;
if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) && widget_intersect ( WIDGET ( lv->scrollbar ), *x, *y ) ) {
rx = *x - widget_get_x_pos ( WIDGET ( lv->scrollbar ) );
ry = *y - widget_get_y_pos ( WIDGET ( lv->scrollbar ) );
target = widget_find_mouse_target ( WIDGET ( lv->scrollbar ), type, &rx, &ry );
if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) && widget_intersect ( WIDGET ( lv->scrollbar ), x, y ) ) {
rx = x - widget_get_x_pos ( WIDGET ( lv->scrollbar ) );
ry = y - widget_get_y_pos ( WIDGET ( lv->scrollbar ) );
target = widget_find_mouse_target ( WIDGET ( lv->scrollbar ), type, rx, ry );
}
unsigned int max = MIN ( lv->cur_elements, lv->req_elements - lv->last_offset );
unsigned int i;
for ( i = 0; i < max && target == NULL; i++ ) {
widget *w = WIDGET ( lv->boxes[i] );
if ( widget_intersect ( w, *x, *y ) ) {
rx = *x - widget_get_x_pos ( w );
ry = *y - widget_get_y_pos ( w );
target = widget_find_mouse_target ( w, type, &rx, &ry );
if ( widget_intersect ( w, x, y ) ) {
rx = x - widget_get_x_pos ( w );
ry = y - widget_get_y_pos ( w );
target = widget_find_mouse_target ( w, type, rx, ry );
}
}
if ( target != NULL ) {
*x = rx;
*y = ry;
return target;
}
return NULL;
}
static gboolean listview_trigger_action ( widget *wid, MouseBindingListviewAction action, G_GNUC_UNUSED gint x, G_GNUC_UNUSED gint y, G_GNUC_UNUSED void *user_data )
{
listview *lv = (listview *) wid;

View File

@ -395,6 +395,15 @@ int widget_get_y_pos ( widget *widget )
return 0;
}
void widget_xy_to_relative ( widget *widget, gint *x, gint *y )
{
*x -= widget->x;
*y -= widget->y;
if ( widget->parent != NULL ) {
widget_xy_to_relative ( widget->parent, x, y );
}
}
void widget_update ( widget *widget )
{
// When (desired )size of widget changes.
@ -426,7 +435,7 @@ gboolean widget_need_redraw ( widget *wid )
return FALSE;
}
widget *widget_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
widget *widget_find_mouse_target ( widget *wid, WidgetType type, gint x, gint y )
{
if ( !wid ) {
return NULL;