[gtk+] Add has-origin property for GtkScale



commit 40423df23428109c75119d7291f876785f0db73f
Author: Andrea Cimitan <andrea cimitan gmail com>
Date:   Wed Dec 14 17:16:09 2011 +0100

    Add has-origin property for GtkScale
    
    If the scale has an origin (it will have one by default), GtkRange will
    render the two sides before/after the current value with different style
    classes, making it possible for themes to use different colors and
    properties for the two areas.
    This was possible in GTK 2 with style details, but got lost during the
    road to 3.0.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=665140

 docs/reference/gtk/gtk3-sections.txt |    2 +
 gtk/gtk.symbols                      |    2 +
 gtk/gtkrange.c                       |  120 +++++++++++++++++++++++++--------
 gtk/gtkrange.h                       |    4 +-
 gtk/gtkscale.c                       |   71 ++++++++++++++++++++-
 gtk/gtkscale.h                       |    3 +
 6 files changed, 171 insertions(+), 31 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 95b5557..4c3c8c0 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -2820,9 +2820,11 @@ gtk_scale_new
 gtk_scale_new_with_range
 gtk_scale_set_digits
 gtk_scale_set_draw_value
+gtk_scale_set_has_origin
 gtk_scale_set_value_pos
 gtk_scale_get_digits
 gtk_scale_get_draw_value
+gtk_scale_get_has_origin
 gtk_scale_get_value_pos
 gtk_scale_get_layout
 gtk_scale_get_layout_offsets
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index b310ae4..8263bcc 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -2300,6 +2300,7 @@ gtk_scale_button_set_value
 gtk_scale_clear_marks
 gtk_scale_get_digits
 gtk_scale_get_draw_value
+gtk_scale_get_has_origin
 gtk_scale_get_layout
 gtk_scale_get_layout_offsets
 gtk_scale_get_type
@@ -2308,6 +2309,7 @@ gtk_scale_new
 gtk_scale_new_with_range
 gtk_scale_set_digits
 gtk_scale_set_draw_value
+gtk_scale_set_has_origin
 gtk_scale_set_value_pos
 gtk_scrollable_get_hadjustment
 gtk_scrollable_get_hscroll_policy
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index ca7390f..f0cda5f 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -137,6 +137,9 @@ struct _GtkRangePrivate
   guint lower_sensitive        : 1;
   guint upper_sensitive        : 1;
 
+  /* The range has an origin, should be drawn differently. Used by GtkScale */
+  guint has_origin             : 1;
+
   /* Fill level */
   guint show_fill_level        : 1;
   guint restrict_to_fill_level : 1;
@@ -736,6 +739,7 @@ gtk_range_init (GtkRange *range)
   priv->upper_sensitivity = GTK_SENSITIVITY_AUTO;
   priv->lower_sensitive = TRUE;
   priv->upper_sensitive = TRUE;
+  priv->has_origin = FALSE;
   priv->show_fill_level = FALSE;
   priv->restrict_to_fill_level = TRUE;
   priv->fill_level = G_MAXDOUBLE;
@@ -2109,37 +2113,82 @@ gtk_range_draw (GtkWidget *widget,
 
       if (draw_trough)
         {
-          gint trough_change_pos_x = width;
-          gint trough_change_pos_y = height;
-
-          if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-            trough_change_pos_x = (priv->slider.x +
-                                   priv->slider.width / 2 -
-                                   x);
-          else
-            trough_change_pos_y = (priv->slider.y +
-                                   priv->slider.height / 2 -
-                                   y);
-
-          /* FIXME: was trough-upper and trough-lower really used,
-           * in that case, it should still be exposed somehow.
-           */
-          gtk_render_background (context, cr, x, y,
-                                 trough_change_pos_x,
-                                 trough_change_pos_y);
+          if (!priv->has_origin)
+            {
+              gtk_render_background (context, cr,
+                                     x, y, width, height);
 
-          if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-            trough_change_pos_y = 0;
+              gtk_render_frame (context, cr,
+                                x, y, width, height);
+            }
           else
-            trough_change_pos_x = 0;
-
-          gtk_render_background (context, cr,
-                                 x + trough_change_pos_x, y + trough_change_pos_y,
-                                 width - trough_change_pos_x,
-                                 height - trough_change_pos_y);
-
-          gtk_render_frame (context, cr,
-                            x, y, width, height);
+            {
+              gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+
+              gint trough_change_pos_x = width;
+              gint trough_change_pos_y = height;
+
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                trough_change_pos_x = (priv->slider.x +
+                                       priv->slider.width / 2 -
+                                       x);
+              else
+                trough_change_pos_y = (priv->slider.y +
+                                       priv->slider.height / 2 -
+                                       y);
+
+              gtk_style_context_save (context);
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                {
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
+
+                  if (!is_rtl)
+                    gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+                }
+              else
+                gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
+
+              gtk_render_background (context, cr, x, y,
+                                     trough_change_pos_x,
+                                     trough_change_pos_y);
+
+              gtk_render_frame (context, cr, x, y,
+                                trough_change_pos_x,
+                                trough_change_pos_y);
+
+              gtk_style_context_restore (context);
+
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                trough_change_pos_y = 0;
+              else
+                trough_change_pos_x = 0;
+
+              gtk_style_context_save (context);
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                {
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
+
+                  if (is_rtl)
+                    gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+                }
+              else
+                {
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+                }
+
+              gtk_render_background (context, cr,
+                                     x + trough_change_pos_x, y + trough_change_pos_y,
+                                     width - trough_change_pos_x,
+                                     height - trough_change_pos_y);
+
+              gtk_render_frame (context, cr,
+                                x + trough_change_pos_x, y + trough_change_pos_y,
+                                width - trough_change_pos_x,
+                                height - trough_change_pos_y);
+
+              gtk_style_context_restore (context);
+            }
         }
       else
         {
@@ -4063,6 +4112,19 @@ gtk_range_remove_step_timer (GtkRange *range)
 }
 
 void
+_gtk_range_set_has_origin (GtkRange *range,
+                           gboolean  has_origin)
+{
+  range->priv->has_origin = has_origin;
+}
+
+gboolean
+_gtk_range_get_has_origin (GtkRange *range)
+{
+  return range->priv->has_origin;
+}
+
+void
 _gtk_range_set_stop_values (GtkRange *range,
                             gdouble  *values,
                             gint      n_values)
diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h
index 7c01ab2..5fa54e1 100644
--- a/gtk/gtkrange.h
+++ b/gtk/gtkrange.h
@@ -150,7 +150,9 @@ gint                gtk_range_get_round_digits              (GtkRange      *rang
 /* internal API */
 gdouble            _gtk_range_get_wheel_delta              (GtkRange      *range,
                                                             GdkScrollDirection direction);
-
+void               _gtk_range_set_has_origin               (GtkRange      *range,
+                                                            gboolean       has_origin);
+gboolean           _gtk_range_get_has_origin               (GtkRange      *range);
 void               _gtk_range_set_stop_values              (GtkRange      *range,
                                                             gdouble       *values,
                                                             gint           n_values);
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
index 3266f2e..4bf3d40 100644
--- a/gtk/gtkscale.c
+++ b/gtk/gtkscale.c
@@ -104,6 +104,7 @@ enum {
   PROP_0,
   PROP_DIGITS,
   PROP_DRAW_VALUE,
+  PROP_HAS_ORIGIN,
   PROP_VALUE_POS
 };
 
@@ -248,7 +249,15 @@ gtk_scale_class_init (GtkScaleClass *class)
 							 P_("Whether the current value is displayed as a string next to the slider"),
 							 TRUE,
 							 GTK_PARAM_READWRITE));
-  
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_HAS_ORIGIN,
+                                   g_param_spec_boolean ("has-origin",
+                                                         P_("Has Origin"),
+                                                         P_("Whether the scale has an origin"),
+                                                         TRUE,
+                                                         GTK_PARAM_READWRITE));
+
   g_object_class_install_property (gobject_class,
                                    PROP_VALUE_POS,
                                    g_param_spec_enum ("value-pos",
@@ -426,6 +435,8 @@ gtk_scale_init (GtkScale *scale)
 
   gtk_range_set_slider_size_fixed (range, TRUE);
 
+  _gtk_range_set_has_origin (range, TRUE);
+
   priv->draw_value = TRUE;
   priv->value_pos = GTK_POS_TOP;
   priv->digits = 1;
@@ -458,6 +469,9 @@ gtk_scale_set_property (GObject      *object,
     case PROP_DRAW_VALUE:
       gtk_scale_set_draw_value (scale, g_value_get_boolean (value));
       break;
+    case PROP_HAS_ORIGIN:
+      gtk_scale_set_has_origin (scale, g_value_get_boolean (value));
+      break;
     case PROP_VALUE_POS:
       gtk_scale_set_value_pos (scale, g_value_get_enum (value));
       break;
@@ -484,6 +498,9 @@ gtk_scale_get_property (GObject      *object,
     case PROP_DRAW_VALUE:
       g_value_set_boolean (value, priv->draw_value);
       break;
+    case PROP_HAS_ORIGIN:
+      g_value_set_boolean (value, gtk_scale_get_has_origin (scale));
+      break;
     case PROP_VALUE_POS:
       g_value_set_enum (value, priv->value_pos);
       break;
@@ -678,6 +695,58 @@ gtk_scale_get_draw_value (GtkScale *scale)
 }
 
 /**
+ * gtk_scale_set_has_origin:
+ * @scale: a #GtkScale
+ * @has_origin: %TRUE if the scale has an origin
+ * 
+ * If @has_origin is set to %TRUE (the default),
+ * the scale will highlight the part of the scale
+ * between the origin (bottom or left side) of the scale
+ * and the current value.
+ *
+ * Since: 3.4
+ */
+void
+gtk_scale_set_has_origin (GtkScale *scale,
+                          gboolean  has_origin)
+{
+  GtkScalePrivate *priv;
+
+  g_return_if_fail (GTK_IS_SCALE (scale));
+
+  priv = scale->priv;
+
+  has_origin = has_origin != FALSE;
+
+  if (_gtk_range_get_has_origin (GTK_RANGE (scale)) != has_origin)
+    {
+      _gtk_range_set_has_origin (GTK_RANGE (scale), has_origin);
+
+      gtk_widget_queue_draw (GTK_WIDGET (scale));
+
+      g_object_notify (G_OBJECT (scale), "has-origin");
+    }
+}
+
+/**
+ * gtk_scale_get_has_origin:
+ * @scale: a #GtkScale
+ *
+ * Returns whether the scale has an origin.
+ *
+ * Returns: %TRUE if the scale has an origin.
+ * 
+ * Since: 3.4
+ */
+gboolean
+gtk_scale_get_has_origin (GtkScale *scale)
+{
+  g_return_val_if_fail (GTK_IS_SCALE (scale), FALSE);
+
+  return _gtk_range_get_has_origin (GTK_RANGE (scale));
+}
+
+/**
  * gtk_scale_set_value_pos:
  * @scale: a #GtkScale
  * @pos: the position in which the current value is displayed
diff --git a/gtk/gtkscale.h b/gtk/gtkscale.h
index b0fb131..554551e 100644
--- a/gtk/gtkscale.h
+++ b/gtk/gtkscale.h
@@ -90,6 +90,9 @@ gint              gtk_scale_get_digits         (GtkScale        *scale);
 void              gtk_scale_set_draw_value     (GtkScale        *scale,
                                                 gboolean         draw_value);
 gboolean          gtk_scale_get_draw_value     (GtkScale        *scale);
+void              gtk_scale_set_has_origin     (GtkScale        *scale,
+                                                gboolean         has_origin);
+gboolean          gtk_scale_get_has_origin     (GtkScale        *scale);
 void              gtk_scale_set_value_pos      (GtkScale        *scale,
                                                 GtkPositionType  pos);
 GtkPositionType   gtk_scale_get_value_pos      (GtkScale        *scale);



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