[gimp] Bug 770689 - Custom transparency controller for dark...



commit 423ce6fca3eaa6b7032f095ba07c8f7a412a0f16
Author: Massimo Valentini <mvalentini src gnome org>
Date:   Wed Dec 13 16:01:48 2017 +0100

    Bug 770689 - Custom transparency controller for dark...
    
    ...outside area of Crop Tool -> Highlight option
    
    Add "highlight-opacity" property and turn the controlling GUI into an
    expanding toggle that reveals an opacity slider.

 app/display/gimpcanvas-style.c         |    2 +-
 app/display/gimpcanvaspassepartout.c   |  102 ++++++++++++++++++++++++++++---
 app/display/gimpdisplayshell.c         |    5 +-
 app/display/gimpdisplayshell.h         |    3 +-
 app/display/gimptoolrectangle.c        |   19 +++++-
 app/tools/gimpcropoptions.c            |    8 +++
 app/tools/gimpcroptool.c               |    3 +-
 app/tools/gimprectangleoptions.c       |   22 ++++++-
 app/tools/gimprectangleoptions.h       |    2 +
 app/tools/gimprectangleselectoptions.c |    8 +++
 app/tools/gimprectangleselecttool.c    |    3 +-
 11 files changed, 156 insertions(+), 21 deletions(-)
---
diff --git a/app/display/gimpcanvas-style.c b/app/display/gimpcanvas-style.c
index ff6f044..81a462d 100644
--- a/app/display/gimpcanvas-style.c
+++ b/app/display/gimpcanvas-style.c
@@ -83,7 +83,7 @@ static const GimpRGB vectors_active_fg   = { 1.0, 0.0, 0.0, 0.8 };
 static const GimpRGB outline_bg          = { 1.0, 1.0, 1.0, 0.6 };
 static const GimpRGB outline_fg          = { 0.0, 0.0, 0.0, 0.8 };
 
-static const GimpRGB passe_partout       = { 0.0, 0.0, 0.0, 0.5 };
+static const GimpRGB passe_partout       = { 0.0, 0.0, 0.0, 1.0 };
 
 static const GimpRGB tool_bg             = { 0.0, 0.0, 0.0, 0.4 };
 static const GimpRGB tool_fg             = { 1.0, 1.0, 1.0, 0.8 };
diff --git a/app/display/gimpcanvaspassepartout.c b/app/display/gimpcanvaspassepartout.c
index cfa0b94..f7087b1 100644
--- a/app/display/gimpcanvaspassepartout.c
+++ b/app/display/gimpcanvaspassepartout.c
@@ -31,13 +31,41 @@
 #include "gimpdisplayshell-scale.h"
 
 
+enum
+{
+  PROP_0,
+  PROP_OPACITY,
+};
+
+
+typedef struct _GimpCanvasPassePartoutPrivate GimpCanvasPassePartoutPrivate;
+
+struct _GimpCanvasPassePartoutPrivate
+{
+  gdouble opacity;
+};
+
+#define GET_PRIVATE(item) \
+        G_TYPE_INSTANCE_GET_PRIVATE (item, \
+                                     GIMP_TYPE_CANVAS_PASSE_PARTOUT, \
+                                     GimpCanvasPassePartoutPrivate)
+
+
 /*  local function prototypes  */
 
-static void             gimp_canvas_passe_partout_draw        (GimpCanvasItem *item,
-                                                               cairo_t        *cr);
-static cairo_region_t * gimp_canvas_passe_partout_get_extents (GimpCanvasItem *item);
-static void             gimp_canvas_passe_partout_fill        (GimpCanvasItem *item,
-                                                               cairo_t        *cr);
+static void             gimp_canvas_passe_partout_set_property (GObject        *object,
+                                                                guint           property_id,
+                                                                const GValue   *value,
+                                                                GParamSpec     *pspec);
+static void             gimp_canvas_passe_partout_get_property (GObject        *object,
+                                                                guint           property_id,
+                                                                GValue         *value,
+                                                                GParamSpec     *pspec);
+static void             gimp_canvas_passe_partout_draw         (GimpCanvasItem *item,
+                                                                cairo_t        *cr);
+static cairo_region_t * gimp_canvas_passe_partout_get_extents  (GimpCanvasItem *item);
+static void             gimp_canvas_passe_partout_fill         (GimpCanvasItem *item,
+                                                                cairo_t        *cr);
 
 
 G_DEFINE_TYPE (GimpCanvasPassePartout, gimp_canvas_passe_partout,
@@ -49,11 +77,23 @@ G_DEFINE_TYPE (GimpCanvasPassePartout, gimp_canvas_passe_partout,
 static void
 gimp_canvas_passe_partout_class_init (GimpCanvasPassePartoutClass *klass)
 {
-  GimpCanvasItemClass *item_class = GIMP_CANVAS_ITEM_CLASS (klass);
+  GObjectClass        *object_class = G_OBJECT_CLASS (klass);
+  GimpCanvasItemClass *item_class   = GIMP_CANVAS_ITEM_CLASS (klass);
+
+  object_class->set_property = gimp_canvas_passe_partout_set_property;
+  object_class->get_property = gimp_canvas_passe_partout_get_property;
+
+  item_class->draw           = gimp_canvas_passe_partout_draw;
+  item_class->get_extents    = gimp_canvas_passe_partout_get_extents;
+  item_class->fill           = gimp_canvas_passe_partout_fill;
 
-  item_class->draw        = gimp_canvas_passe_partout_draw;
-  item_class->get_extents = gimp_canvas_passe_partout_get_extents;
-  item_class->fill        = gimp_canvas_passe_partout_fill;
+  g_object_class_install_property (object_class, PROP_OPACITY,
+                                   g_param_spec_double ("opacity", NULL, NULL,
+                                                        0.0,
+                                                        1.0, 0.5,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_type_class_add_private (klass, sizeof (GimpCanvasPassePartoutPrivate));
 }
 
 static void
@@ -62,6 +102,46 @@ gimp_canvas_passe_partout_init (GimpCanvasPassePartout *passe_partout)
 }
 
 static void
+gimp_canvas_passe_partout_set_property (GObject      *object,
+                                        guint         property_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+  GimpCanvasPassePartoutPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case PROP_OPACITY:
+      priv->opacity = g_value_get_double (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_canvas_passe_partout_get_property (GObject    *object,
+                                        guint       property_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  GimpCanvasPassePartoutPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case PROP_OPACITY:
+      g_value_set_double (value, priv->opacity);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
 gimp_canvas_passe_partout_draw (GimpCanvasItem *item,
                                 cairo_t        *cr)
 {
@@ -101,11 +181,13 @@ static void
 gimp_canvas_passe_partout_fill (GimpCanvasItem *item,
                                 cairo_t        *cr)
 {
+  GimpCanvasPassePartoutPrivate *priv = GET_PRIVATE (item);
+
   cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
   cairo_clip (cr);
 
   gimp_canvas_set_passe_partout_style (gimp_canvas_item_get_canvas (item), cr);
-  cairo_paint (cr);
+  cairo_paint_with_alpha (cr, priv->opacity);
 }
 
 GimpCanvasItem *
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 24b96b2..b0acf8b 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -1881,6 +1881,7 @@ gimp_display_shell_resume (GimpDisplayShell *shell)
  * gimp_display_shell_set_highlight:
  * @shell:     a #GimpDisplayShell
  * @highlight: a rectangle in image coordinates that should be brought out
+ * @opacity:   how much to hide the unselected area
  *
  * This function sets an area of the image that should be
  * accentuated. The actual implementation is to dim all pixels outside
@@ -1888,7 +1889,8 @@ gimp_display_shell_resume (GimpDisplayShell *shell)
  **/
 void
 gimp_display_shell_set_highlight (GimpDisplayShell   *shell,
-                                  const GdkRectangle *highlight)
+                                  const GdkRectangle *highlight,
+                                  gdouble             opacity)
 {
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
 
@@ -1901,6 +1903,7 @@ gimp_display_shell_set_highlight (GimpDisplayShell   *shell,
                                  highlight->y,
                                  highlight->width,
                                  highlight->height);
+      g_object_set (shell->passe_partout, "opacity", opacity, NULL);
 
       gimp_canvas_item_set_visible (shell->passe_partout, TRUE);
 
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 9c5cb19..5f93f25 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -294,7 +294,8 @@ void              gimp_display_shell_pause         (GimpDisplayShell   *shell);
 void              gimp_display_shell_resume        (GimpDisplayShell   *shell);
 
 void              gimp_display_shell_set_highlight (GimpDisplayShell   *shell,
-                                                    const GdkRectangle *highlight);
+                                                    const GdkRectangle *highlight,
+                                                    double              opacity);
 void              gimp_display_shell_set_mask      (GimpDisplayShell   *shell,
                                                     GeglBuffer         *mask,
                                                     gint                offset_x,
diff --git a/app/display/gimptoolrectangle.c b/app/display/gimptoolrectangle.c
index 160ed1e..6964b41 100644
--- a/app/display/gimptoolrectangle.c
+++ b/app/display/gimptoolrectangle.c
@@ -82,6 +82,7 @@ enum
   PROP_STATUS_TITLE,
 
   PROP_HIGHLIGHT,
+  PROP_HIGHLIGHT_OPACITY,
   PROP_GUIDE,
   PROP_X,
   PROP_Y,
@@ -239,6 +240,7 @@ struct _GimpToolRectanglePrivate
   /* The following values are externally synced with GimpRectangleOptions */
 
   gboolean                highlight;
+  gdouble                 highlight_opacity;
   GimpGuidesType          guide;
 
   gdouble                 x;
@@ -561,6 +563,13 @@ gimp_tool_rectangle_class_init (GimpToolRectangleClass *klass)
                                                          GIMP_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
 
+  g_object_class_install_property (object_class, PROP_HIGHLIGHT_OPACITY,
+                                   g_param_spec_double ("highlight-opacity",
+                                                        NULL, NULL,
+                                                        0.0, 1.0, 0.5,
+                                                        GIMP_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
+
   g_object_class_install_property (object_class, PROP_GUIDE,
                                    g_param_spec_enum ("guide",
                                                       NULL, NULL,
@@ -869,6 +878,9 @@ gimp_tool_rectangle_set_property (GObject      *object,
     case PROP_HIGHLIGHT:
       private->highlight = g_value_get_boolean (value);
       break;
+    case PROP_HIGHLIGHT_OPACITY:
+      private->highlight_opacity = g_value_get_double (value);
+      break;
     case PROP_GUIDE:
       private->guide = g_value_get_enum (value);
       break;
@@ -975,6 +987,9 @@ gimp_tool_rectangle_get_property (GObject    *object,
     case PROP_HIGHLIGHT:
       g_value_set_boolean (value, private->highlight);
       break;
+    case PROP_HIGHLIGHT_OPACITY:
+      g_value_set_double (value, private->highlight_opacity);
+      break;
     case PROP_GUIDE:
       g_value_set_enum (value, private->guide);
       break;
@@ -1367,11 +1382,11 @@ gimp_tool_rectangle_changed (GimpToolWidget *widget)
       rect.width  = x2 - x1;
       rect.height = y2 - y1;
 
-      gimp_display_shell_set_highlight (shell, &rect);
+      gimp_display_shell_set_highlight (shell, &rect, private->highlight_opacity);
     }
   else
     {
-      gimp_display_shell_set_highlight (shell, NULL);
+      gimp_display_shell_set_highlight (shell, NULL, 0.0);
     }
 }
 
diff --git a/app/tools/gimpcropoptions.c b/app/tools/gimpcropoptions.c
index 9e557b0..f313801 100644
--- a/app/tools/gimpcropoptions.c
+++ b/app/tools/gimpcropoptions.c
@@ -80,6 +80,14 @@ gimp_crop_options_class_init (GimpCropOptionsClass *klass)
                             TRUE,
                             GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_DOUBLE (object_class,
+                           GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT_OPACITY,
+                           "highlight-opacity",
+                           _("Highlight opacity"),
+                           _("How much to dim everything outside selection"),
+                           0.0, 1.0, 0.5,
+                           GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LAYER_ONLY,
                             "layer-only",
                             _("Current layer only"),
diff --git a/app/tools/gimpcroptool.c b/app/tools/gimpcroptool.c
index dd5ea3b..ccbb261 100644
--- a/app/tools/gimpcroptool.c
+++ b/app/tools/gimpcroptool.c
@@ -335,6 +335,7 @@ gimp_crop_tool_start (GimpCropTool *crop_tool,
   static const gchar *properties[] =
   {
     "highlight",
+    "highlight-opacity",
     "guide",
     "x",
     "y",
@@ -474,7 +475,7 @@ gimp_crop_tool_halt (GimpCropTool *crop_tool)
     {
       GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
 
-      gimp_display_shell_set_highlight (shell, NULL);
+      gimp_display_shell_set_highlight (shell, NULL, 0.0);
 
       gimp_rectangle_options_disconnect (GIMP_RECTANGLE_OPTIONS (options),
                                          G_CALLBACK (gimp_crop_tool_auto_shrink),
diff --git a/app/tools/gimprectangleoptions.c b/app/tools/gimprectangleoptions.c
index a07a112..120bd3f 100644
--- a/app/tools/gimprectangleoptions.c
+++ b/app/tools/gimprectangleoptions.c
@@ -491,6 +491,9 @@ gimp_rectangle_options_set_property (GObject      *object,
     case GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT:
       private->highlight = g_value_get_boolean (value);
       break;
+    case GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT_OPACITY:
+      private->highlight_opacity = g_value_get_double (value);
+      break;
     case GIMP_RECTANGLE_OPTIONS_PROP_GUIDE:
       private->guide = g_value_get_enum (value);
       break;
@@ -595,6 +598,9 @@ gimp_rectangle_options_get_property (GObject      *object,
     case GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT:
       g_value_set_boolean (value, private->highlight);
       break;
+    case GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT_OPACITY:
+      g_value_set_double (value, private->highlight_opacity);
+      break;
     case GIMP_RECTANGLE_OPTIONS_PROP_GUIDE:
       g_value_set_enum (value, private->guide);
       break;
@@ -1036,10 +1042,18 @@ gimp_rectangle_options_gui (GimpToolOptions *tool_options)
   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
   gtk_widget_show (frame);
 
-  /*  Highlight  */
-  button = gimp_prop_check_button_new (config, "highlight", NULL);
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  gtk_widget_show (button);
+  /*  the Highlight frame  */
+  {
+    GtkWidget *scale;
+
+    scale = gimp_prop_spin_scale_new (config, "highlight-opacity", NULL,
+                                      0.01, 0.1, 2);
+
+    frame = gimp_prop_expanding_frame_new (config, "highlight", NULL,
+                                           scale, NULL);
+    gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+    gtk_widget_show (frame);
+  }
 
   /*  Guide  */
   combo = gimp_prop_enum_combo_box_new (config, "guide",
diff --git a/app/tools/gimprectangleoptions.h b/app/tools/gimprectangleoptions.h
index e74b458..f2a37fb 100644
--- a/app/tools/gimprectangleoptions.h
+++ b/app/tools/gimprectangleoptions.h
@@ -26,6 +26,7 @@ typedef enum
   GIMP_RECTANGLE_OPTIONS_PROP_AUTO_SHRINK,
   GIMP_RECTANGLE_OPTIONS_PROP_SHRINK_MERGED,
   GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT,
+  GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT_OPACITY,
   GIMP_RECTANGLE_OPTIONS_PROP_GUIDE,
 
   GIMP_RECTANGLE_OPTIONS_PROP_X,
@@ -80,6 +81,7 @@ struct _GimpRectangleOptionsPrivate
   gboolean                shrink_merged;
 
   gboolean                highlight;
+  gdouble                 highlight_opacity;
   GimpGuidesType          guide;
 
   gdouble                 x;
diff --git a/app/tools/gimprectangleselectoptions.c b/app/tools/gimprectangleselectoptions.c
index 07e4cf6..3c6c33d 100644
--- a/app/tools/gimprectangleselectoptions.c
+++ b/app/tools/gimprectangleselectoptions.c
@@ -80,6 +80,14 @@ gimp_rectangle_select_options_class_init (GimpRectangleSelectOptionsClass *klass
                             FALSE,
                             GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_DOUBLE (object_class,
+                           GIMP_RECTANGLE_OPTIONS_PROP_HIGHLIGHT_OPACITY,
+                           "highlight-opacity",
+                           _("Highlight opacity"),
+                           _("How much to dim everything outside selection"),
+                           0.0, 1.0, 0.5,
+                           GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ROUND_CORNERS,
                             "round-corners",
                             _("Rounded corners"),
diff --git a/app/tools/gimprectangleselecttool.c b/app/tools/gimprectangleselecttool.c
index d23e33e..993affb 100644
--- a/app/tools/gimprectangleselecttool.c
+++ b/app/tools/gimprectangleselecttool.c
@@ -688,6 +688,7 @@ gimp_rectangle_select_tool_start (GimpRectangleSelectTool *rect_tool,
   static const gchar *properties[] =
   {
     "highlight",
+    "highlight-opacity",
     "guide",
     "round-corners",
     "corner-radius",
@@ -878,7 +879,7 @@ gimp_rectangle_select_tool_halt (GimpRectangleSelectTool *rect_tool)
     {
       GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
 
-      gimp_display_shell_set_highlight (shell, NULL);
+      gimp_display_shell_set_highlight (shell, NULL, 0.0);
 
       gimp_rectangle_options_disconnect (GIMP_RECTANGLE_OPTIONS (options),
                                          G_CALLBACK (gimp_rectangle_select_tool_auto_shrink),


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