]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkruler.c
Fixes #136082 and #135265, patch by Morten Welinder.
[~andy/gtk] / gtk / gtkruler.c
index c1c997f481c1422d3a2e6cc97e87a0595ab5be67..3ae8d54d1a9489cffb3992426a15a6a216d9229a 100644 (file)
@@ -2,22 +2,39 @@
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
+ * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include "gtkruler.h"
 
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include <config.h>
+#include "gtkruler.h"
+#include "gtkintl.h"
+
+enum {
+  PROP_0,
+  PROP_LOWER,
+  PROP_UPPER,
+  PROP_POSITION,
+  PROP_MAX_SIZE
+};
 
 static void gtk_ruler_class_init    (GtkRulerClass  *klass);
 static void gtk_ruler_init          (GtkRuler       *ruler);
@@ -28,11 +45,18 @@ static void gtk_ruler_size_allocate (GtkWidget      *widget,
 static gint gtk_ruler_expose        (GtkWidget      *widget,
                                     GdkEventExpose *event);
 static void gtk_ruler_make_pixmap   (GtkRuler       *ruler);
-
+static void gtk_ruler_set_property  (GObject        *object,
+                                    guint            prop_id,
+                                    const GValue   *value,
+                                    GParamSpec     *pspec);
+static void gtk_ruler_get_property  (GObject        *object,
+                                    guint           prop_id,
+                                    GValue         *value,
+                                    GParamSpec     *pspec);
 
 static GtkWidgetClass *parent_class;
 
-static GtkRulerMetric ruler_metrics[] =
+static const GtkRulerMetric ruler_metrics[] =
 {
   {"Pixels", "Pi", 1.0, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }},
   {"Inches", "In", 72.0, { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 }, { 1, 2, 4, 8, 16 }},
@@ -40,25 +64,28 @@ static GtkRulerMetric ruler_metrics[] =
 };
 
 
-guint
-gtk_ruler_get_type ()
+GType
+gtk_ruler_get_type (void)
 {
-  static guint ruler_type = 0;
+  static GType ruler_type = 0;
 
   if (!ruler_type)
     {
-      GtkTypeInfo ruler_info =
+      static const GTypeInfo ruler_info =
       {
-       "GtkRuler",
-       sizeof (GtkRuler),
        sizeof (GtkRulerClass),
-       (GtkClassInitFunc) gtk_ruler_class_init,
-       (GtkObjectInitFunc) gtk_ruler_init,
-       (GtkArgSetFunc) NULL,
-        (GtkArgGetFunc) NULL,
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_ruler_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkRuler),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_ruler_init,
       };
 
-      ruler_type = gtk_type_unique (gtk_widget_get_type (), &ruler_info);
+      ruler_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkRuler",
+                                          &ruler_info, 0);
     }
 
   return ruler_type;
@@ -67,13 +94,16 @@ gtk_ruler_get_type ()
 static void
 gtk_ruler_class_init (GtkRulerClass *class)
 {
-  GtkObjectClass *object_class;
+  GObjectClass   *gobject_class;
   GtkWidgetClass *widget_class;
 
-  object_class = (GtkObjectClass*) class;
+  gobject_class = G_OBJECT_CLASS (class);
   widget_class = (GtkWidgetClass*) class;
 
-  parent_class = gtk_type_class (gtk_widget_get_type ());
+  parent_class = g_type_class_peek_parent (class);
+  
+  gobject_class->set_property = gtk_ruler_set_property;
+  gobject_class->get_property = gtk_ruler_get_property;
 
   widget_class->realize = gtk_ruler_realize;
   widget_class->unrealize = gtk_ruler_unrealize;
@@ -82,6 +112,46 @@ gtk_ruler_class_init (GtkRulerClass *class)
 
   class->draw_ticks = NULL;
   class->draw_pos = NULL;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_LOWER,
+                                   g_param_spec_double ("lower",
+                                                       P_("Lower"),
+                                                       P_("Lower limit of ruler"),
+                                                       -G_MAXDOUBLE,
+                                                       G_MAXDOUBLE,
+                                                       0.0,
+                                                       G_PARAM_READWRITE));  
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_UPPER,
+                                   g_param_spec_double ("upper",
+                                                       P_("Upper"),
+                                                       P_("Upper limit of ruler"),
+                                                       -G_MAXDOUBLE,
+                                                       G_MAXDOUBLE,
+                                                       0.0,
+                                                       G_PARAM_READWRITE));  
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_POSITION,
+                                   g_param_spec_double ("position",
+                                                       P_("Position"),
+                                                       P_("Position of mark on the ruler"),
+                                                       -G_MAXDOUBLE,
+                                                       G_MAXDOUBLE,
+                                                       0.0,
+                                                       G_PARAM_READWRITE));  
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MAX_SIZE,
+                                   g_param_spec_double ("max_size",
+                                                       P_("Max Size"),
+                                                       P_("Maximum size of the ruler"),
+                                                       -G_MAXDOUBLE,
+                                                       G_MAXDOUBLE,
+                                                       0.0,
+                                                       G_PARAM_READWRITE));  
 }
 
 static void
@@ -100,56 +170,182 @@ gtk_ruler_init (GtkRuler *ruler)
   gtk_ruler_set_metric (ruler, GTK_PIXELS);
 }
 
+static void
+gtk_ruler_set_property (GObject      *object,
+                       guint         prop_id,
+                       const GValue *value,
+                       GParamSpec   *pspec)
+{
+  GtkRuler *ruler = GTK_RULER (object);
+
+  switch (prop_id)
+    {
+    case PROP_LOWER:
+      gtk_ruler_set_range (ruler, g_value_get_double (value), ruler->upper,
+                          ruler->position, ruler->max_size);
+      break;
+    case PROP_UPPER:
+      gtk_ruler_set_range (ruler, ruler->lower, g_value_get_double (value),
+                          ruler->position, ruler->max_size);
+      break;
+    case PROP_POSITION:
+      gtk_ruler_set_range (ruler, ruler->lower, ruler->upper,
+                          g_value_get_double (value), ruler->max_size);
+      break;
+    case PROP_MAX_SIZE:
+      gtk_ruler_set_range (ruler, ruler->lower, ruler->upper,
+                          ruler->position,  g_value_get_double (value));
+      break;
+    }
+}
+
+static void
+gtk_ruler_get_property (GObject      *object,
+                       guint         prop_id,
+                       GValue       *value,
+                       GParamSpec   *pspec)
+{
+  GtkRuler *ruler = GTK_RULER (object);
+  
+  switch (prop_id)
+    {
+    case PROP_LOWER:
+      g_value_set_double (value, ruler->lower);
+      break;
+    case PROP_UPPER:
+      g_value_set_double (value, ruler->upper);
+      break;
+    case PROP_POSITION:
+      g_value_set_double (value, ruler->position);
+      break;
+    case PROP_MAX_SIZE:
+      g_value_set_double (value, ruler->max_size);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
 void
 gtk_ruler_set_metric (GtkRuler      *ruler,
                      GtkMetricType  metric)
 {
-  g_return_if_fail (ruler != NULL);
   g_return_if_fail (GTK_IS_RULER (ruler));
 
-  ruler->metric = &ruler_metrics[metric];
+  ruler->metric = (GtkRulerMetric *) &ruler_metrics[metric];
 
   if (GTK_WIDGET_DRAWABLE (ruler))
     gtk_widget_queue_draw (GTK_WIDGET (ruler));
 }
 
+/**
+ * gtk_ruler_get_metric:
+ * @ruler: a #GtkRuler
+ *
+ * Gets the units used for a #GtkRuler. See gtk_ruler_set_metric().
+ *
+ * Return value: the units currently used for @ruler
+ **/
+GtkMetricType
+gtk_ruler_get_metric (GtkRuler *ruler)
+{
+  gint i;
+
+  g_return_val_if_fail (GTK_IS_RULER (ruler), 0);
+
+  for (i = 0; i < G_N_ELEMENTS (ruler_metrics); i++)
+    if (ruler->metric == &ruler_metrics[i])
+      return i;
+
+  g_assert_not_reached ();
+
+  return 0;
+}
+
 void
 gtk_ruler_set_range (GtkRuler *ruler,
-                    gfloat    lower,
-                    gfloat    upper,
-                    gfloat    position,
-                    gfloat    max_size)
+                    gdouble   lower,
+                    gdouble   upper,
+                    gdouble   position,
+                    gdouble   max_size)
 {
-  g_return_if_fail (ruler != NULL);
   g_return_if_fail (GTK_IS_RULER (ruler));
 
-  ruler->lower = lower;
-  ruler->upper = upper;
-  ruler->position = position;
-  ruler->max_size = max_size;
+  g_object_freeze_notify (G_OBJECT (ruler));
+  if (ruler->lower != lower)
+    {
+      ruler->lower = lower;
+      g_object_notify (G_OBJECT (ruler), "lower");
+    }
+  if (ruler->upper != upper)
+    {
+      ruler->upper = upper;
+      g_object_notify (G_OBJECT (ruler), "upper");
+    }
+  if (ruler->position != position)
+    {
+      ruler->position = position;
+      g_object_notify (G_OBJECT (ruler), "position");
+    }
+  if (ruler->max_size != max_size)
+    {
+      ruler->max_size = max_size;
+      g_object_notify (G_OBJECT (ruler), "max_size");
+    }
+  g_object_thaw_notify (G_OBJECT (ruler));
 
   if (GTK_WIDGET_DRAWABLE (ruler))
     gtk_widget_queue_draw (GTK_WIDGET (ruler));
 }
 
+/**
+ * gtk_ruler_get_range:
+ * @ruler: a #GtkRuler
+ * @lower: location to store lower limit of the ruler, or %NULL
+ * @upper: location to store upper limit of the ruler, or %NULL
+ * @position: location to store the current position of the mark on the ruler, or %NULL
+ * @max_size: location to store the maximum size of the ruler used when calculating
+ *            the space to leave for the text, or %NULL.
+ *
+ * Retrieves values indicating the range and current position of a #GtkRuler.
+ * See gtk_ruler_set_range().
+ **/
+void
+gtk_ruler_get_range (GtkRuler *ruler,
+                    gdouble  *lower,
+                    gdouble  *upper,
+                    gdouble  *position,
+                    gdouble  *max_size)
+{
+  g_return_if_fail (GTK_IS_RULER (ruler));
+
+  if (lower)
+    *lower = ruler->lower;
+  if (upper)
+    *upper = ruler->upper;
+  if (position)
+    *position = ruler->position;
+  if (max_size)
+    *max_size = ruler->max_size;
+}
+
 void
 gtk_ruler_draw_ticks (GtkRuler *ruler)
 {
-  g_return_if_fail (ruler != NULL);
   g_return_if_fail (GTK_IS_RULER (ruler));
 
-  if (GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_ticks)
-    (* GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_ticks) (ruler);
+  if (GTK_RULER_GET_CLASS (ruler)->draw_ticks)
+    GTK_RULER_GET_CLASS (ruler)->draw_ticks (ruler);
 }
 
 void
 gtk_ruler_draw_pos (GtkRuler *ruler)
 {
-  g_return_if_fail (ruler != NULL);
   g_return_if_fail (GTK_IS_RULER (ruler));
 
-  if (GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_pos)
-    (* GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_pos) (ruler);
+  if (GTK_RULER_GET_CLASS (ruler)->draw_pos)
+     GTK_RULER_GET_CLASS (ruler)->draw_pos (ruler);
 }
 
 
@@ -160,9 +356,6 @@ gtk_ruler_realize (GtkWidget *widget)
   GdkWindowAttr attributes;
   gint attributes_mask;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_RULER (widget));
-
   ruler = GTK_RULER (widget);
   GTK_WIDGET_SET_FLAGS (ruler, GTK_REALIZED);
 
@@ -193,17 +386,12 @@ gtk_ruler_realize (GtkWidget *widget)
 static void
 gtk_ruler_unrealize (GtkWidget *widget)
 {
-  GtkRuler *ruler;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_RULER (widget));
-
-  ruler = GTK_RULER (widget);
+  GtkRuler *ruler = GTK_RULER (widget);
 
   if (ruler->backing_store)
-    gdk_pixmap_unref (ruler->backing_store);
+    g_object_unref (ruler->backing_store);
   if (ruler->non_gr_exp_gc)
-    gdk_gc_destroy (ruler->non_gr_exp_gc);
+    g_object_unref (ruler->non_gr_exp_gc);
 
   ruler->backing_store = NULL;
   ruler->non_gr_exp_gc = NULL;
@@ -216,12 +404,8 @@ static void
 gtk_ruler_size_allocate (GtkWidget     *widget,
                         GtkAllocation *allocation)
 {
-  GtkRuler *ruler;
+  GtkRuler *ruler = GTK_RULER (widget);
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_RULER (widget));
-
-  ruler = GTK_RULER (widget);
   widget->allocation = *allocation;
 
   if (GTK_WIDGET_REALIZED (widget))
@@ -240,34 +424,19 @@ gtk_ruler_expose (GtkWidget      *widget,
 {
   GtkRuler *ruler;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_RULER (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       ruler = GTK_RULER (widget);
 
-      gdk_draw_rectangle (ruler->backing_store,
-                         widget->style->bg_gc[GTK_STATE_NORMAL],
-                         TRUE, 0, 0,
-                         widget->allocation.width,
-                         widget->allocation.height);
-
       gtk_ruler_draw_ticks (ruler);
-
-      gtk_draw_shadow (widget->style, ruler->backing_store,
-                      GTK_STATE_NORMAL, GTK_SHADOW_OUT, 0, 0,
-                      widget->allocation.width,
-                      widget->allocation.height);
-
-      gdk_draw_pixmap (widget->window,
-                      ruler->non_gr_exp_gc,
-                      ruler->backing_store,
-                      0, 0, 0, 0,
-                      widget->allocation.width,
-                      widget->allocation.height);
-
+      
+      gdk_draw_drawable (widget->window,
+                        ruler->non_gr_exp_gc,
+                        ruler->backing_store,
+                        0, 0, 0, 0,
+                        widget->allocation.width,
+                        widget->allocation.height);
+      
       gtk_ruler_draw_pos (ruler);
     }
 
@@ -285,12 +454,12 @@ gtk_ruler_make_pixmap (GtkRuler *ruler)
 
   if (ruler->backing_store)
     {
-      gdk_window_get_size (ruler->backing_store, &width, &height);
+      gdk_drawable_get_size (ruler->backing_store, &width, &height);
       if ((width == widget->allocation.width) &&
          (height == widget->allocation.height))
        return;
 
-      gdk_pixmap_unref (ruler->backing_store);
+      g_object_unref (ruler->backing_store);
     }
 
   ruler->backing_store = gdk_pixmap_new (widget->window,