[gimp] app: new gimp_widget_blink_rect().



commit 33e2d18a59e03f6ee500d1c07b09291ee1aade9f
Author: Jehan <jehan girinstud io>
Date:   Tue Feb 9 11:50:23 2021 +0100

    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.

 app/widgets/gimptoolbox.c       |   6 +--
 app/widgets/gimpwidgets-utils.c | 100 ++++++++++++++++++++++++++++++++++++----
 app/widgets/gimpwidgets-utils.h |   7 ++-
 3 files changed, 99 insertions(+), 14 deletions(-)
---
diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c
index a0e68c7292..d752a196e3 100644
--- a/app/widgets/gimptoolbox.c
+++ b/app/widgets/gimptoolbox.c
@@ -379,7 +379,7 @@ gimp_toolbox_drag_leave (GtkWidget      *widget,
                          guint           time,
                          GimpToolbox    *toolbox)
 {
-  gimp_highlight_widget (widget, FALSE);
+  gimp_highlight_widget (widget, FALSE, NULL);
 }
 
 static gboolean
@@ -399,7 +399,7 @@ gimp_toolbox_drag_motion (GtkWidget      *widget,
                                        time))
     {
       gdk_drag_status (context, 0, time);
-      gimp_highlight_widget (widget, FALSE);
+      gimp_highlight_widget (widget, FALSE, NULL);
 
       return FALSE;
     }
@@ -407,7 +407,7 @@ gimp_toolbox_drag_motion (GtkWidget      *widget,
   handle = (gtk_drag_dest_find_target (widget, context, NULL) != GDK_NONE);
 
   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;
diff --git a/app/widgets/gimpwidgets-utils.c b/app/widgets/gimpwidgets-utils.c
index df67408358..5c18cd4c47 100644
--- a/app/widgets/gimpwidgets-utils.c
+++ b/app/widgets/gimpwidgets-utils.c
@@ -1224,13 +1224,22 @@ gimp_highlight_widget_draw (GtkWidget *widget,
                             cairo_t   *cr,
                             gpointer   data)
 {
+  GdkRectangle *rect = (GdkRectangle *) data;
+
   /* this code is a straight copy of draw_flash() from gtk-inspector's
    * inspect-button.c
    */
 
   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));
       /* We don't want to draw the drag highlight around the
@@ -1262,16 +1271,24 @@ gimp_highlight_widget_draw (GtkWidget *widget,
  * gimp_highlight_widget:
  * @widget:
  * @highlight:
+ * @rect:
  *
  * Turns highlighting for @widget on or off according to
  * @highlight, in a similar fashion to gtk_drag_highlight()
  * 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
-gimp_highlight_widget (GtkWidget *widget,
-                       gboolean   highlight)
+gimp_highlight_widget (GtkWidget    *widget,
+                       gboolean      highlight,
+                       GdkRectangle *rect)
 {
-  gboolean old_highlight;
+  GdkRectangle *old_rect;
+  gboolean      old_highlight;
 
   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),
                                                       "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)
         {
+          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_CALLBACK (gimp_highlight_widget_draw),
-                                  NULL);
+                                  new_rect);
         }
       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,
                                                 gimp_highlight_widget_draw,
                                                 NULL);
@@ -1305,8 +1353,9 @@ gimp_highlight_widget (GtkWidget *widget,
 
 typedef struct
 {
-  gint timeout_id;
-  gint counter;
+  gint          timeout_id;
+  gint          counter;
+  GdkRectangle *rect;
 } WidgetBlink;
 
 static WidgetBlink *
@@ -1318,6 +1367,7 @@ widget_blink_new (void)
 
   blink->timeout_id = 0;
   blink->counter    = 0;
+  blink->rect       = NULL;
 
   return blink;
 }
@@ -1331,6 +1381,9 @@ widget_blink_free (WidgetBlink *blink)
       blink->timeout_id = 0;
     }
 
+  if (blink->rect)
+    g_slice_free (GdkRectangle, blink->rect);
+
   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");
 
-  gimp_highlight_widget (widget, blink->counter % 2 == 1);
+  gimp_highlight_widget (widget, blink->counter % 2 == 1, blink->rect);
   blink->counter++;
 
   if (blink->counter == 3)
@@ -1374,7 +1427,34 @@ gimp_widget_blink (GtkWidget *widget)
                                      (GSourceFunc) gimp_widget_blink_timeout,
                                      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)))
     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"))
     {
-      gimp_highlight_widget (widget, FALSE);
+      gimp_highlight_widget (widget, FALSE, NULL);
 
       g_object_set_data (G_OBJECT (widget), "gimp-widget-blink", NULL);
     }
diff --git a/app/widgets/gimpwidgets-utils.h b/app/widgets/gimpwidgets-utils.h
index 0925dc431f..6d1392fbc2 100644
--- a/app/widgets/gimpwidgets-utils.h
+++ b/app/widgets/gimpwidgets-utils.h
@@ -85,10 +85,15 @@ void              gimp_pango_layout_set_scale      (PangoLayout          *layout
                                                     double                scale);
 void              gimp_pango_layout_set_weight     (PangoLayout          *layout,
                                                     PangoWeight           weight);
+
 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_cancel         (GtkWidget             *widget);
+
 GtkWidget       * gimp_dock_with_window_new        (GimpDialogFactory    *factory,
                                                     GdkMonitor           *monitor,
                                                     gboolean              toolbox);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]