[gimp/gimp-2-10] app: add compact style for spin scales



commit 8591b5b33f69fcf340a0c2d57a3d638f4c9fab40
Author: Ell <ell_se yahoo com>
Date:   Mon Jan 6 22:44:44 2020 +0200

    app: add compact style for spin scales
    
    Add a boolean "compact" style property for GimpSpinScale.  When
    TRUE, the widget uses a narrower layout, and the different upper/
    lower-half behavior is gone.  Instead, the behavior depends on the
    mouse button used: left-click is used for absolute adjustment
    (similar to the upper-half behavior), middle-click is used for
    relative adjustment (similar to the lower-half behavior), and right
    click is used for manual value entry (similar for clicking on the
    text area).
    
    Add a new "Compact sliders" toggle to the Interface prefernces, to
    control the spin-scale style.  Apply the style globally through the
    themerc file, and update it when the option changes.
    
    Use the compact style by default, because otherwise no one would
    find it.  Theming in GTK3 works differently, and spin scales in
    master need more work regardless, so this stays in 2.10 for now.

 app/config/gimpguiconfig.c       | 14 ++++++
 app/config/gimpguiconfig.h       |  1 +
 app/config/gimprc-blurbs.h       |  5 +++
 app/dialogs/preferences-dialog.c |  7 +++
 app/gui/themes.c                 | 40 ++++++++++++++---
 app/widgets/gimpspinscale.c      | 96 ++++++++++++++++++++++++++++++----------
 6 files changed, 134 insertions(+), 29 deletions(-)
---
diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c
index 4250235c9d..c74fbe1122 100644
--- a/app/config/gimpguiconfig.c
+++ b/app/config/gimpguiconfig.c
@@ -64,6 +64,7 @@ enum
   PROP_RESTORE_SESSION,
   PROP_RESTORE_MONITOR,
   PROP_SAVE_TOOL_OPTIONS,
+  PROP_COMPACT_SLIDERS,
   PROP_SHOW_TOOLTIPS,
   PROP_TEAROFF_MENUS,
   PROP_CAN_CHANGE_ACCELS,
@@ -236,6 +237,13 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
                             TRUE,
                             GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_COMPACT_SLIDERS,
+                            "compact-sliders",
+                            "Compact sliders",
+                            COMPACT_SLIDERS_BLURB,
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_TOOLTIPS,
                             "show-tooltips",
                             "Show tooltips",
@@ -625,6 +633,9 @@ gimp_gui_config_set_property (GObject      *object,
     case PROP_SAVE_TOOL_OPTIONS:
       gui_config->save_tool_options = g_value_get_boolean (value);
       break;
+    case PROP_COMPACT_SLIDERS:
+      gui_config->compact_sliders = g_value_get_boolean (value);
+      break;
     case PROP_SHOW_TOOLTIPS:
       gui_config->show_tooltips = g_value_get_boolean (value);
       break;
@@ -816,6 +827,9 @@ gimp_gui_config_get_property (GObject    *object,
     case PROP_SAVE_TOOL_OPTIONS:
       g_value_set_boolean (value, gui_config->save_tool_options);
       break;
+    case PROP_COMPACT_SLIDERS:
+      g_value_set_boolean (value, gui_config->compact_sliders);
+      break;
     case PROP_SHOW_TOOLTIPS:
       g_value_set_boolean (value, gui_config->show_tooltips);
       break;
diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h
index d09e594aaa..d1142982db 100644
--- a/app/config/gimpguiconfig.h
+++ b/app/config/gimpguiconfig.h
@@ -53,6 +53,7 @@ struct _GimpGuiConfig
   gboolean             restore_session;
   gboolean             restore_monitor;
   gboolean             save_tool_options;
+  gboolean             compact_sliders;
   gboolean             show_tooltips;
   gboolean             tearoff_menus;
   gboolean             can_change_accels;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index f827bffbf6..43d70407ce 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -49,6 +49,11 @@ _("How to handle embedded color profiles when opening a file.")
 #define COLOR_PROFILE_PATH_BLURB \
 _("Sets the default folder path for all color profile file dialogs.")
 
+#define COMPACT_SLIDERS_BLURB \
+_("Use compact style for sliders. In this mode, left-click is used for " \
+  "absolute adjustment, middle-click is used for relative adjustment, and " \
+  "right-click is used for manual entry.")
+
 #define CURSOR_MODE_BLURB \
 _("Sets the type of mouse pointers to use.")
 
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index db0bddd42a..f6d69e71a9 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -1812,6 +1812,13 @@ prefs_dialog_new (Gimp       *gimp,
   prefs_language_combo_box_add (object, "language", GTK_BOX (vbox2));
 #endif
 
+  /*  Style  */
+  vbox2 = prefs_frame_new (_("Style"), GTK_CONTAINER (vbox), FALSE);
+
+  button = prefs_check_button_add (object, "compact-sliders",
+                                   _("Use co_mpact sliders"),
+                                   GTK_BOX (vbox2));
+
   /*  Previews  */
   vbox2 = prefs_frame_new (_("Previews"), GTK_CONTAINER (vbox), FALSE);
 
diff --git a/app/gui/themes.c b/app/gui/themes.c
index d17d50eca8..0307094ef3 100644
--- a/app/gui/themes.c
+++ b/app/gui/themes.c
@@ -41,8 +41,11 @@
 
 /*  local function prototypes  */
 
+static void   themes_write_style         (GimpGuiConfig          *config,
+                                          GOutputStream          *output,
+                                          GError                **error);
 static void   themes_apply_theme         (Gimp                   *gimp,
-                                          const gchar            *theme_name);
+                                          GimpGuiConfig          *config);
 static void   themes_list_themes_foreach (gpointer                key,
                                           gpointer                value,
                                           gpointer                data);
@@ -143,7 +146,7 @@ themes_init (Gimp *gimp)
       g_list_free_full (path, (GDestroyNotify) g_object_unref);
     }
 
-  themes_apply_theme (gimp, config->theme);
+  themes_apply_theme (gimp, config);
 
   themerc = gimp_personal_rc_file ("themerc");
   gtk_rc_parse (themerc);
@@ -154,6 +157,9 @@ themes_init (Gimp *gimp)
   g_signal_connect (config, "notify::theme",
                     G_CALLBACK (themes_theme_change_notify),
                     gimp);
+  g_signal_connect (config, "notify::compact-sliders",
+                    G_CALLBACK (themes_theme_change_notify),
+                    gimp);
 }
 
 void
@@ -272,8 +278,28 @@ themes_get_theme_file (Gimp        *gimp,
 /*  private functions  */
 
 static void
-themes_apply_theme (Gimp        *gimp,
-                    const gchar *theme_name)
+themes_write_style (GimpGuiConfig  *config,
+                    GOutputStream  *output,
+                    GError        **error)
+{
+  if (! *error)
+    {
+      g_output_stream_printf (
+        output, NULL, NULL, error,
+        "style \"gimp-spin-scale-style\"\n"
+        "{\n"
+        "  GimpSpinScale::compact = %d\n"
+        "}\n"
+        "\n"
+        "class \"GimpSpinScale\" style \"gimp-spin-scale-style\"\n"
+        "\n",
+        config->compact_sliders);
+    }
+}
+
+static void
+themes_apply_theme (Gimp          *gimp,
+                    GimpGuiConfig *config)
 {
   GFile         *themerc;
   GOutputStream *output;
@@ -296,7 +322,7 @@ themes_apply_theme (Gimp        *gimp,
     }
   else
     {
-      GFile  *theme_dir   = themes_get_theme_dir (gimp, theme_name);
+      GFile  *theme_dir   = themes_get_theme_dir (gimp, config->theme);
       GFile  *gtkrc_user;
       GSList *gtkrc_files = NULL;
       GSList *iter;
@@ -336,6 +362,8 @@ themes_apply_theme (Gimp        *gimp,
         "\n",
         gimp_file_get_utf8_name (gtkrc_user));
 
+      themes_write_style (config, output, &error);
+
       for (iter = gtkrc_files; ! error && iter; iter = g_slist_next (iter))
         {
           GFile *file = iter->data;
@@ -419,7 +447,7 @@ themes_theme_change_notify (GimpGuiConfig *config,
                             GParamSpec    *pspec,
                             Gimp          *gimp)
 {
-  themes_apply_theme (gimp, config->theme);
+  themes_apply_theme (gimp, config);
 
   gtk_rc_reparse_all ();
 
diff --git a/app/widgets/gimpspinscale.c b/app/widgets/gimpspinscale.c
index 361d4b9cf5..83acc1cc9f 100644
--- a/app/widgets/gimpspinscale.c
+++ b/app/widgets/gimpspinscale.c
@@ -54,6 +54,8 @@ typedef struct _GimpSpinScalePrivate GimpSpinScalePrivate;
 
 struct _GimpSpinScalePrivate
 {
+  gboolean         compact;
+
   gchar           *label;
   gchar           *label_text;
   gchar           *label_pattern;
@@ -163,6 +165,12 @@ gimp_spin_scale_class_init (GimpSpinScaleClass *klass)
                                    g_param_spec_string ("label", NULL, NULL,
                                                         NULL,
                                                         GIMP_PARAM_READWRITE));
+
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_boolean ("compact",
+                                                                 NULL, NULL,
+                                                                 FALSE,
+                                                                 GIMP_PARAM_READABLE));
 }
 
 static void
@@ -261,17 +269,21 @@ gimp_spin_scale_size_request (GtkWidget      *widget,
   GtkStyle             *style   = gtk_widget_get_style (widget);
   PangoContext         *context = gtk_widget_get_pango_context (widget);
   PangoFontMetrics     *metrics;
-  gint                  height;
 
   GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
 
   metrics = pango_context_get_metrics (context, style->font_desc,
                                        pango_context_get_language (context));
 
-  height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
-                         pango_font_metrics_get_descent (metrics));
+  if (! private->compact)
+    {
+      gint height;
+
+      height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
+                             pango_font_metrics_get_descent (metrics));
 
-  requisition->height += height;
+      requisition->height += height;
+    }
 
   if (private->label)
     {
@@ -299,6 +311,10 @@ gimp_spin_scale_style_set (GtkWidget *widget,
   GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
 
   g_clear_object (&private->layout);
+
+  gtk_widget_style_get (widget,
+                        "compact", &private->compact,
+                        NULL);
 }
 
 static PangoAttrList *
@@ -362,7 +378,8 @@ gimp_spin_scale_expose (GtkWidget      *widget,
   h = gdk_window_get_height (event->window);
 
   /* upper/lower halves highlight */
-  if (event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)) &&
+  if (! private->compact                                              &&
+      event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)) &&
       gtk_widget_get_sensitive (widget)                               &&
       (private->target == TARGET_UPPER || private->target == TARGET_LOWER))
     {
@@ -556,41 +573,61 @@ gimp_spin_scale_expose (GtkWidget      *widget,
 static SpinScaleTarget
 gimp_spin_scale_get_target (GtkWidget *widget,
                             gdouble    x,
-                            gdouble    y)
+                            gdouble    y,
+                            gint       button)
 {
-  GtkAllocation  allocation;
-  PangoRectangle logical;
-  gint           layout_x;
-  gint           layout_y;
+  GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+  GtkAllocation         allocation;
+  PangoRectangle        logical;
+  gint                  layout_x;
+  gint                  layout_y;
 
   gtk_widget_get_allocation (widget, &allocation);
   gtk_entry_get_layout_offsets (GTK_ENTRY (widget), &layout_x, &layout_y);
   pango_layout_get_pixel_extents (gtk_entry_get_layout (GTK_ENTRY (widget)),
                                   NULL, &logical);
 
-  if (x >= layout_x && x < layout_x + logical.width &&
-      y >= layout_y && y < layout_y + logical.height)
+  if (x >= layout_x && x < layout_x + logical.width  &&
+      y >= layout_y && y < layout_y + logical.height &&
+      (! private->compact || gtk_widget_has_focus (widget)))
     {
       return TARGET_NUMBER;
     }
-  else if (y >= allocation.height / 2)
+
+  if (private->compact)
     {
-      return TARGET_LOWER;
-    }
+      switch (button)
+        {
+        default:
+          return TARGET_UPPER;
+
+        case 2:
+          return TARGET_LOWER;
 
-  return TARGET_UPPER;
+        case 3:
+          return TARGET_NUMBER;
+        }
+    }
+   else
+    {
+      if (y >= allocation.height / 2)
+        return TARGET_LOWER;
+      else
+        return TARGET_UPPER;
+    }
 }
 
 static void
 gimp_spin_scale_update_target (GtkWidget *widget,
                                GdkWindow *window,
                                gdouble    x,
-                               gdouble    y)
+                               gdouble    y,
+                               gint       button)
 {
   GimpSpinScalePrivate *private = GET_PRIVATE (widget);
   SpinScaleTarget       target;
 
-  target = gimp_spin_scale_get_target (widget, x, y);
+  target = gimp_spin_scale_get_target (widget, x, y, button);
 
   if (target != private->target)
     {
@@ -742,7 +779,7 @@ gimp_spin_scale_button_press (GtkWidget      *widget,
   if (event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)))
     {
       gimp_spin_scale_update_target (widget, event->window,
-                                     event->x, event->y);
+                                     event->x, event->y, event->button);
 
       gtk_widget_queue_draw (widget);
 
@@ -751,7 +788,8 @@ gimp_spin_scale_button_press (GtkWidget      *widget,
         case TARGET_UPPER:
           private->changing_value = TRUE;
 
-          gtk_widget_grab_focus (widget);
+          if (! private->compact)
+            gtk_widget_grab_focus (widget);
 
           gimp_spin_scale_change_value (widget, event->x);
 
@@ -760,7 +798,8 @@ gimp_spin_scale_button_press (GtkWidget      *widget,
         case TARGET_LOWER:
           private->changing_value = TRUE;
 
-          gtk_widget_grab_focus (widget);
+          if (! private->compact)
+            gtk_widget_grab_focus (widget);
 
           private->relative_change = TRUE;
           private->start_x = event->x;
@@ -772,6 +811,17 @@ gimp_spin_scale_button_press (GtkWidget      *widget,
 
           return TRUE;
 
+        case TARGET_NUMBER:
+          if (private->compact && ! gtk_widget_has_focus (widget))
+            {
+              gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
+
+              gtk_widget_grab_focus (widget);
+
+              return TRUE;
+            }
+          break;
+
         default:
           break;
         }
@@ -807,7 +857,7 @@ gimp_spin_scale_button_release (GtkWidget      *widget,
 
       if (private->hover)
         gimp_spin_scale_update_target (widget, event->window,
-                                       event->x, event->y);
+                                       event->x, event->y, 0);
       else
         gimp_spin_scale_clear_target (widget, event->window);
 
@@ -945,7 +995,7 @@ gimp_spin_scale_motion_notify (GtkWidget      *widget,
       private->hover)
     {
       gimp_spin_scale_update_target (widget, event->window,
-                                     event->x, event->y);
+                                     event->x, event->y, 0);
     }
 
   return FALSE;


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