app: new gimp_widget_blink_rect().

Also change signature of gimp_highlight_widget().
These functions allow to highlight or blink specific widget areas only
when needed.
This commit is contained in:
Jehan
2021-02-09 11:50:23 +01:00
parent b356ea6aac
commit 33e2d18a59
3 changed files with 99 additions and 14 deletions

View File

@ -379,7 +379,7 @@ gimp_toolbox_drag_leave (GtkWidget *widget,
guint time, guint time,
GimpToolbox *toolbox) GimpToolbox *toolbox)
{ {
gimp_highlight_widget (widget, FALSE); gimp_highlight_widget (widget, FALSE, NULL);
} }
static gboolean static gboolean
@ -399,7 +399,7 @@ gimp_toolbox_drag_motion (GtkWidget *widget,
time)) time))
{ {
gdk_drag_status (context, 0, time); gdk_drag_status (context, 0, time);
gimp_highlight_widget (widget, FALSE); gimp_highlight_widget (widget, FALSE, NULL);
return FALSE; return FALSE;
} }
@ -407,7 +407,7 @@ gimp_toolbox_drag_motion (GtkWidget *widget,
handle = (gtk_drag_dest_find_target (widget, context, NULL) != GDK_NONE); handle = (gtk_drag_dest_find_target (widget, context, NULL) != GDK_NONE);
gdk_drag_status (context, handle ? GDK_ACTION_MOVE : 0, time); gdk_drag_status (context, handle ? GDK_ACTION_MOVE : 0, time);
gimp_highlight_widget (widget, handle); gimp_highlight_widget (widget, handle, NULL);
/* Return TRUE so drag_leave() is called */ /* Return TRUE so drag_leave() is called */
return TRUE; return TRUE;

View File

@ -1224,13 +1224,22 @@ gimp_highlight_widget_draw (GtkWidget *widget,
cairo_t *cr, cairo_t *cr,
gpointer data) gpointer data)
{ {
GdkRectangle *rect = (GdkRectangle *) data;
/* this code is a straight copy of draw_flash() from gtk-inspector's /* this code is a straight copy of draw_flash() from gtk-inspector's
* inspect-button.c * inspect-button.c
*/ */
GtkAllocation alloc; GtkAllocation alloc;
if (GTK_IS_WINDOW (widget)) if (rect)
{
alloc.x = rect->x;
alloc.y = rect->y;
alloc.width = rect->width;
alloc.height = rect->height;
}
else if (GTK_IS_WINDOW (widget))
{ {
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget)); GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
/* We don't want to draw the drag highlight around the /* We don't want to draw the drag highlight around the
@ -1262,16 +1271,24 @@ gimp_highlight_widget_draw (GtkWidget *widget,
* gimp_highlight_widget: * gimp_highlight_widget:
* @widget: * @widget:
* @highlight: * @highlight:
* @rect:
* *
* Turns highlighting for @widget on or off according to * Turns highlighting for @widget on or off according to
* @highlight, in a similar fashion to gtk_drag_highlight() * @highlight, in a similar fashion to gtk_drag_highlight()
* and gtk_drag_unhighlight(). * and gtk_drag_unhighlight().
*
* If @rect is %NULL, highlight the full widget, otherwise highlight the
* specific rectangle in widget coordinates.
* When unhighlighting (i.e. @highlight is %FALSE), the value of @rect
* doesn't matter, as the previously used rectangle will be reused.
**/ **/
void void
gimp_highlight_widget (GtkWidget *widget, gimp_highlight_widget (GtkWidget *widget,
gboolean highlight) gboolean highlight,
GdkRectangle *rect)
{ {
gboolean old_highlight; GdkRectangle *old_rect;
gboolean old_highlight;
g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_IS_WIDGET (widget));
@ -1279,17 +1296,48 @@ gimp_highlight_widget (GtkWidget *widget,
old_highlight = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), old_highlight = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"gimp-widget-highlight")); "gimp-widget-highlight"));
old_rect = g_object_get_data (G_OBJECT (widget), "gimp-widget-highlight-rect");
if (highlight && old_highlight && ! gdk_rectangle_equal (rect, old_rect))
{
/* Highlight area changed. */
gimp_highlight_widget (widget, FALSE, NULL);
old_highlight = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"gimp-widget-highlight"));
old_rect = g_object_get_data (G_OBJECT (widget), "gimp-widget-highlight-rect");
}
if (highlight != old_highlight) if (highlight != old_highlight)
{ {
if (highlight) if (highlight)
{ {
GdkRectangle *new_rect = NULL;
if (rect)
{
new_rect = g_new0 (GdkRectangle, 1);
*new_rect = *rect;
g_object_set_data_full (G_OBJECT (widget),
"gimp-widget-highlight-rect",
new_rect,
(GDestroyNotify) g_free);
}
g_signal_connect_after (widget, "draw", g_signal_connect_after (widget, "draw",
G_CALLBACK (gimp_highlight_widget_draw), G_CALLBACK (gimp_highlight_widget_draw),
NULL); new_rect);
} }
else else
{ {
if (old_rect)
{
g_signal_handlers_disconnect_by_func (widget,
gimp_highlight_widget_draw,
old_rect);
g_object_set_data (G_OBJECT (widget),
"gimp-widget-highlight-rect",
NULL);
}
g_signal_handlers_disconnect_by_func (widget, g_signal_handlers_disconnect_by_func (widget,
gimp_highlight_widget_draw, gimp_highlight_widget_draw,
NULL); NULL);
@ -1305,8 +1353,9 @@ gimp_highlight_widget (GtkWidget *widget,
typedef struct typedef struct
{ {
gint timeout_id; gint timeout_id;
gint counter; gint counter;
GdkRectangle *rect;
} WidgetBlink; } WidgetBlink;
static WidgetBlink * static WidgetBlink *
@ -1318,6 +1367,7 @@ widget_blink_new (void)
blink->timeout_id = 0; blink->timeout_id = 0;
blink->counter = 0; blink->counter = 0;
blink->rect = NULL;
return blink; return blink;
} }
@ -1331,6 +1381,9 @@ widget_blink_free (WidgetBlink *blink)
blink->timeout_id = 0; blink->timeout_id = 0;
} }
if (blink->rect)
g_slice_free (GdkRectangle, blink->rect);
g_slice_free (WidgetBlink, blink); g_slice_free (WidgetBlink, blink);
} }
@ -1341,7 +1394,7 @@ gimp_widget_blink_timeout (GtkWidget *widget)
blink = g_object_get_data (G_OBJECT (widget), "gimp-widget-blink"); blink = g_object_get_data (G_OBJECT (widget), "gimp-widget-blink");
gimp_highlight_widget (widget, blink->counter % 2 == 1); gimp_highlight_widget (widget, blink->counter % 2 == 1, blink->rect);
blink->counter++; blink->counter++;
if (blink->counter == 3) if (blink->counter == 3)
@ -1374,7 +1427,34 @@ gimp_widget_blink (GtkWidget *widget)
(GSourceFunc) gimp_widget_blink_timeout, (GSourceFunc) gimp_widget_blink_timeout,
widget); widget);
gimp_highlight_widget (widget, TRUE); gimp_highlight_widget (widget, TRUE, NULL);
while ((widget = gtk_widget_get_parent (widget)))
gimp_widget_blink_cancel (widget);
}
void
gimp_widget_blink_rect (GtkWidget *widget,
GdkRectangle *rect)
{
WidgetBlink *blink;
g_return_if_fail (GTK_IS_WIDGET (widget));
gimp_widget_blink_cancel (widget);
blink = widget_blink_new ();
blink->rect = g_slice_new (GdkRectangle);
*(blink->rect) = *rect;
g_object_set_data_full (G_OBJECT (widget), "gimp-widget-blink", blink,
(GDestroyNotify) widget_blink_free);
blink->timeout_id = g_timeout_add (150,
(GSourceFunc) gimp_widget_blink_timeout,
widget);
gimp_highlight_widget (widget, TRUE, blink->rect);
while ((widget = gtk_widget_get_parent (widget))) while ((widget = gtk_widget_get_parent (widget)))
gimp_widget_blink_cancel (widget); gimp_widget_blink_cancel (widget);
@ -1387,7 +1467,7 @@ gimp_widget_blink_cancel (GtkWidget *widget)
if (g_object_get_data (G_OBJECT (widget), "gimp-widget-blink")) if (g_object_get_data (G_OBJECT (widget), "gimp-widget-blink"))
{ {
gimp_highlight_widget (widget, FALSE); gimp_highlight_widget (widget, FALSE, NULL);
g_object_set_data (G_OBJECT (widget), "gimp-widget-blink", NULL); g_object_set_data (G_OBJECT (widget), "gimp-widget-blink", NULL);
} }

View File

@ -85,10 +85,15 @@ void gimp_pango_layout_set_scale (PangoLayout *layout
double scale); double scale);
void gimp_pango_layout_set_weight (PangoLayout *layout, void gimp_pango_layout_set_weight (PangoLayout *layout,
PangoWeight weight); PangoWeight weight);
void gimp_highlight_widget (GtkWidget *widget, void gimp_highlight_widget (GtkWidget *widget,
gboolean highlight); gboolean highlight,
GdkRectangle *rect);
void gimp_widget_blink_rect (GtkWidget *widget,
GdkRectangle *rect);
void gimp_widget_blink (GtkWidget *widget); void gimp_widget_blink (GtkWidget *widget);
void gimp_widget_blink_cancel (GtkWidget *widget); void gimp_widget_blink_cancel (GtkWidget *widget);
GtkWidget * gimp_dock_with_window_new (GimpDialogFactory *factory, GtkWidget * gimp_dock_with_window_new (GimpDialogFactory *factory,
GdkMonitor *monitor, GdkMonitor *monitor,
gboolean toolbox); gboolean toolbox);