]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcurve.c
Silently return NULL if the widget is not realized. (#316023, Guillaume
[~andy/gtk] / gtk / gtkcurve.c
index 169c885bbf061f016712dfda58b5b908030af39a..c96c3658d9a70268a51b0f5357e93a9e0ba418ee 100644 (file)
@@ -2,20 +2,29 @@
  * Copyright (C) 1997 David Mosberger
  *
  * 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.
  */
+
+/*
+ * 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 <stdlib.h>
 #include <string.h>
 #include <math.h>
 #include "gtkcurve.h"
 #include "gtkdrawingarea.h"
 #include "gtkmain.h"
+#include "gtkmarshalers.h"
 #include "gtkradiobutton.h"
-#include "gtksignal.h"
 #include "gtktable.h"
+#include "gtkprivate.h"
+#include "gtkintl.h"
+#include "gtkalias.h"
 
 #define RADIUS         3       /* radius of the control points */
 #define MIN_DISTANCE   8       /* min distance between control points */
                         GDK_BUTTON_RELEASE_MASK |      \
                         GDK_BUTTON1_MOTION_MASK)
 
+enum {
+  PROP_0,
+  PROP_CURVE_TYPE,
+  PROP_MIN_X,
+  PROP_MAX_X,
+  PROP_MIN_Y,
+  PROP_MAX_Y
+};
+
 static GtkDrawingAreaClass *parent_class = NULL;
 static guint curve_type_changed_signal = 0;
 
@@ -45,31 +66,42 @@ static guint curve_type_changed_signal = 0;
 /* forward declarations: */
 static void gtk_curve_class_init   (GtkCurveClass *class);
 static void gtk_curve_init         (GtkCurve      *curve);
-static void gtk_curve_finalize     (GtkObject     *object);
+static void gtk_curve_get_property  (GObject              *object,
+                                    guint                 param_id,
+                                    GValue               *value,
+                                    GParamSpec           *pspec);
+static void gtk_curve_set_property  (GObject              *object,
+                                    guint                 param_id,
+                                    const GValue         *value,
+                                    GParamSpec           *pspec);
+static void gtk_curve_finalize     (GObject       *object);
 static gint gtk_curve_graph_events (GtkWidget     *widget, 
                                    GdkEvent      *event, 
                                    GtkCurve      *c);
 static void gtk_curve_size_graph   (GtkCurve      *curve);
 
-guint
+GType
 gtk_curve_get_type (void)
 {
-  static guint curve_type = 0;
+  static GType curve_type = 0;
 
   if (!curve_type)
     {
-      GtkTypeInfo curve_info =
+      static const GTypeInfo curve_info =
       {
-       "GtkCurve",
-       sizeof (GtkCurve),
        sizeof (GtkCurveClass),
-       (GtkClassInitFunc) gtk_curve_class_init,
-       (GtkObjectInitFunc) gtk_curve_init,
-       (GtkArgSetFunc) NULL,
-        (GtkArgGetFunc) NULL,
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_curve_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkCurve),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_curve_init,
       };
 
-      curve_type = gtk_type_unique (gtk_drawing_area_get_type (), &curve_info);
+      curve_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, I_("GtkCurve"),
+                                          &curve_info, 0);
     }
   return curve_type;
 }
@@ -77,19 +109,68 @@ gtk_curve_get_type (void)
 static void
 gtk_curve_class_init (GtkCurveClass *class)
 {
-  GtkObjectClass *object_class;
-
-  parent_class = gtk_type_class (gtk_drawing_area_get_type ());
-
-  object_class = (GtkObjectClass *) class;
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  
+  parent_class = g_type_class_peek_parent (class);
+  
+  gobject_class->finalize = gtk_curve_finalize;
+
+  gobject_class->set_property = gtk_curve_set_property;
+  gobject_class->get_property = gtk_curve_get_property;
+  
+  g_object_class_install_property (gobject_class,
+                                  PROP_CURVE_TYPE,
+                                  g_param_spec_enum ("curve-type",
+                                                     P_("Curve type"),
+                                                     P_("Is this curve linear, spline interpolated, or free-form"),
+                                                     GTK_TYPE_CURVE_TYPE,
+                                                     GTK_CURVE_TYPE_LINEAR,
+                                                     GTK_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                  PROP_MIN_X,
+                                  g_param_spec_float ("min-x",
+                                                      P_("Minimum X"),
+                                                      P_("Minimum possible value for X"),
+                                                      -G_MAXFLOAT,
+                                                      G_MAXFLOAT,
+                                                      0.0,
+                                                      GTK_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                  PROP_MAX_X,
+                                  g_param_spec_float ("max-x",
+                                                      P_("Maximum X"),
+                                                      P_("Maximum possible X value"),
+                                                      -G_MAXFLOAT,
+                                                      G_MAXFLOAT,
+                                                       1.0,
+                                                      GTK_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                  PROP_MIN_Y,
+                                  g_param_spec_float ("min-y",
+                                                      P_("Minimum Y"),
+                                                      P_("Minimum possible value for Y"),
+                                                       -G_MAXFLOAT,
+                                                      G_MAXFLOAT,
+                                                      0.0,
+                                                      GTK_PARAM_READWRITE));  
+  g_object_class_install_property (gobject_class,
+                                  PROP_MAX_Y,
+                                  g_param_spec_float ("max-y",
+                                                      P_("Maximum Y"),
+                                                      P_("Maximum possible value for Y"),
+                                                      -G_MAXFLOAT,
+                                                      G_MAXFLOAT,
+                                                      1.0,
+                                                      GTK_PARAM_READWRITE));
 
   curve_type_changed_signal =
-    gtk_signal_new ("curve_type_changed", GTK_RUN_FIRST, object_class->type,
-                   GTK_SIGNAL_OFFSET (GtkCurveClass, curve_type_changed),
-                   gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
-  gtk_object_class_add_signals (object_class, &curve_type_changed_signal, 1);
-
-  object_class->finalize = gtk_curve_finalize;
+    g_signal_new (I_("curve_type_changed"),
+                  G_OBJECT_CLASS_TYPE (gobject_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GtkCurveClass, curve_type_changed),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 }
 
 static void
@@ -104,7 +185,7 @@ gtk_curve_init (GtkCurve *curve)
   curve->grab_point = -1;
 
   curve->num_points = 0;
-  curve->point = 0;
+  curve->point = NULL;
 
   curve->num_ctlpoints = 0;
   curve->ctlpoint = NULL;
@@ -116,11 +197,77 @@ gtk_curve_init (GtkCurve *curve)
 
   old_mask = gtk_widget_get_events (GTK_WIDGET (curve));
   gtk_widget_set_events (GTK_WIDGET (curve), old_mask | GRAPH_MASK);
-  gtk_signal_connect (GTK_OBJECT (curve), "event",
-                     (GtkSignalFunc) gtk_curve_graph_events, curve);
+  g_signal_connect (curve, "event",
+                   G_CALLBACK (gtk_curve_graph_events), curve);
   gtk_curve_size_graph (curve);
 }
 
+static void
+gtk_curve_set_property (GObject              *object,
+                       guint                 prop_id,
+                       const GValue         *value,
+                       GParamSpec           *pspec)
+{
+  GtkCurve *curve = GTK_CURVE (object);
+  
+  switch (prop_id)
+    {
+    case PROP_CURVE_TYPE:
+      gtk_curve_set_curve_type (curve, g_value_get_enum (value));
+      break;
+    case PROP_MIN_X:
+      gtk_curve_set_range (curve, g_value_get_float (value), curve->max_x,
+                          curve->min_y, curve->max_y);
+      break;
+    case PROP_MAX_X:
+      gtk_curve_set_range (curve, curve->min_x, g_value_get_float (value),
+                          curve->min_y, curve->max_y);
+      break;   
+    case PROP_MIN_Y:
+      gtk_curve_set_range (curve, curve->min_x, curve->max_x,
+                          g_value_get_float (value), curve->max_y);
+      break;
+    case PROP_MAX_Y:
+      gtk_curve_set_range (curve, curve->min_x, curve->max_x,
+                          curve->min_y, g_value_get_float (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_curve_get_property (GObject              *object,
+                       guint                 prop_id,
+                       GValue               *value,
+                       GParamSpec           *pspec)
+{
+  GtkCurve *curve = GTK_CURVE (object);
+
+  switch (prop_id)
+    {
+    case PROP_CURVE_TYPE:
+      g_value_set_enum (value, curve->curve_type);
+      break;
+    case PROP_MIN_X:
+      g_value_set_float (value, curve->min_x);
+      break;
+    case PROP_MAX_X:
+      g_value_set_float (value, curve->max_x);
+      break;
+    case PROP_MIN_Y:
+      g_value_set_float (value, curve->min_y);
+      break;
+    case PROP_MAX_Y:
+      g_value_set_float (value, curve->max_y);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
 static int
 project (gfloat value, gfloat min, gfloat max, int norm)
 {
@@ -238,9 +385,9 @@ gtk_curve_draw (GtkCurve *c, gint width, gint height)
   style = GTK_WIDGET (c)->style;
 
   /* clear the pixmap: */
-  gdk_draw_rectangle (c->pixmap, style->bg_gc[state], TRUE,
+  gtk_paint_flat_box (style, c->pixmap, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+                     NULL, GTK_WIDGET (c), "curve_bg",
                      0, 0, width + RADIUS * 2, height + RADIUS * 2);
-
   /* draw the grid lines: (XXX make more meaningful) */
   for (i = 0; i < 5; i++)
     {
@@ -271,8 +418,8 @@ gtk_curve_draw (GtkCurve *c, gint width, gint height)
        gdk_draw_arc (c->pixmap, style->fg_gc[state], TRUE, x, y,
                      RADIUS * 2, RADIUS*2, 0, 360*64);
       }
-  gdk_draw_pixmap (GTK_WIDGET (c)->window, style->fg_gc[state], c->pixmap,
-                  0, 0, 0, 0, width + RADIUS * 2, height + RADIUS * 2);
+  gdk_draw_drawable (GTK_WIDGET (c)->window, style->fg_gc[state], c->pixmap,
+                    0, 0, 0, 0, width + RADIUS * 2, height + RADIUS * 2);
 }
 
 static gint
@@ -289,6 +436,7 @@ gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c)
   gfloat rx, ry, min_x;
   guint distance;
   gint x1, x2, y1, y2;
+  gint retval = FALSE;
 
   w = GTK_WIDGET (c);
   width = w->allocation.width - RADIUS * 2;
@@ -319,8 +467,8 @@ gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c)
     {
     case GDK_CONFIGURE:
       if (c->pixmap)
-       gdk_pixmap_unref (c->pixmap);
-      c->pixmap = 0;
+       g_object_unref (c->pixmap);
+      c->pixmap = NULL;
       /* fall through */
     case GDK_EXPOSE:
       if (!c->pixmap)
@@ -375,6 +523,7 @@ gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c)
          break;
        }
       gtk_curve_draw (c, width, height);
+      retval = TRUE;
       break;
 
     case GDK_BUTTON_RELEASE:
@@ -410,6 +559,7 @@ gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c)
        }
       new_type = GDK_FLEUR;
       c->grab_point = -1;
+      retval = TRUE;
       break;
 
     case GDK_MOTION_NOTIFY:
@@ -504,16 +654,19 @@ gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c)
 
          c->cursor_type = new_type;
 
-         cursor = gdk_cursor_new (c->cursor_type);
+         cursor = gdk_cursor_new_for_display (gtk_widget_get_display (w),
+                                             c->cursor_type);
          gdk_window_set_cursor (w->window, cursor);
-         gdk_cursor_destroy (cursor);
+         gdk_cursor_unref (cursor);
        }
+      retval = TRUE;
       break;
 
     default:
       break;
     }
-  return FALSE;
+
+  return retval;
 }
 
 void
@@ -526,8 +679,8 @@ gtk_curve_set_curve_type (GtkCurve *c, GtkCurveType new_type)
     {
       gint width, height;
 
-      width  = GTK_WIDGET(c)->allocation.width - RADIUS * 2;
-      height = GTK_WIDGET(c)->allocation.height - RADIUS * 2;
+      width  = GTK_WIDGET (c)->allocation.width - RADIUS * 2;
+      height = GTK_WIDGET (c)->allocation.height - RADIUS * 2;
 
       if (new_type == GTK_CURVE_TYPE_FREE)
        {
@@ -561,7 +714,8 @@ gtk_curve_set_curve_type (GtkCurve *c, GtkCurveType new_type)
          c->curve_type = new_type;
          gtk_curve_interpolate (c, width, height);
        }
-      gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+      g_signal_emit (c, curve_type_changed_signal, 0);
+      g_object_notify (G_OBJECT (c), "curve_type");
       gtk_curve_draw (c, width, height);
     }
 }
@@ -571,22 +725,24 @@ gtk_curve_size_graph (GtkCurve *curve)
 {
   gint width, height;
   gfloat aspect;
+  GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (curve)); 
 
   width  = (curve->max_x - curve->min_x) + 1;
   height = (curve->max_y - curve->min_y) + 1;
   aspect = width / (gfloat) height;
-  if (width > gdk_screen_width () / 4)
-    width  = gdk_screen_width () / 4;
-  if (height > gdk_screen_height () / 4)
-    height = gdk_screen_height () / 4;
+  if (width > gdk_screen_get_width (screen) / 4)
+    width  = gdk_screen_get_width (screen) / 4;
+  if (height > gdk_screen_get_height (screen) / 4)
+    height = gdk_screen_get_height (screen) / 4;
 
   if (aspect < 1.0)
     width  = height * aspect;
   else
     height = width / aspect;
 
-  gtk_drawing_area_size (GTK_DRAWING_AREA (curve),
-                        width + RADIUS * 2, height + RADIUS * 2);
+  gtk_widget_set_size_request (GTK_WIDGET (curve),
+                              width + RADIUS * 2,
+                              height + RADIUS * 2);
 }
 
 static void
@@ -631,7 +787,10 @@ gtk_curve_reset (GtkCurve *c)
   gtk_curve_reset_vector (c);
 
   if (old_type != GTK_CURVE_TYPE_SPLINE)
-    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+    {
+       g_signal_emit (c, curve_type_changed_signal, 0);
+       g_object_notify (G_OBJECT (c), "curve_type");
+    }
 }
 
 void
@@ -662,19 +821,36 @@ gtk_curve_set_gamma (GtkCurve *c, gfloat gamma)
     }
 
   if (old_type != GTK_CURVE_TYPE_FREE)
-    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+    g_signal_emit (c, curve_type_changed_signal, 0);
 
   gtk_curve_draw (c, c->num_points, c->height);
 }
 
 void
 gtk_curve_set_range (GtkCurve *curve,
-                    gfloat min_x, gfloat max_x, gfloat min_y, gfloat max_y)
+                    gfloat    min_x,
+                     gfloat    max_x,
+                     gfloat    min_y,
+                     gfloat    max_y)
 {
-  curve->min_x = min_x;
-  curve->max_x = max_x;
-  curve->min_y = min_y;
-  curve->max_y = max_y;
+  g_object_freeze_notify (G_OBJECT (curve));
+  if (curve->min_x != min_x) {
+     curve->min_x = min_x;
+     g_object_notify (G_OBJECT (curve), "min_x");
+  }
+  if (curve->max_x != max_x) {
+     curve->max_x = max_x;
+     g_object_notify (G_OBJECT (curve), "max_x");
+  }
+  if (curve->min_y != min_y) {
+     curve->min_y = min_y;
+     g_object_notify (G_OBJECT (curve), "min_y");
+  }
+  if (curve->max_y != max_y) {
+     curve->max_y = max_y;
+     g_object_notify (G_OBJECT (curve), "max_y");
+  }
+  g_object_thaw_notify (G_OBJECT (curve));
 
   gtk_curve_size_graph (curve);
   gtk_curve_reset_vector (curve);
@@ -686,6 +862,7 @@ gtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[])
   GtkCurveType old_type;
   gfloat rx, dx, ry;
   gint i, height;
+  GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (c));
 
   old_type = c->curve_type;
   c->curve_type = GTK_CURVE_TYPE_FREE;
@@ -695,8 +872,8 @@ gtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[])
   else
     {
       height = (c->max_y - c->min_y);
-      if (height > gdk_screen_height () / 4)
-       height = gdk_screen_height () / 4;
+      if (height > gdk_screen_get_height (screen) / 4)
+       height = gdk_screen_get_height (screen) / 4;
 
       c->height = height;
       c->num_points = veclen;
@@ -715,7 +892,10 @@ gtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[])
        RADIUS + height - project (ry, c->min_y, c->max_y, height);
     }
   if (old_type != GTK_CURVE_TYPE_FREE)
-    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+    {
+       g_signal_emit (c, curve_type_changed_signal, 0);
+       g_object_notify (G_OBJECT (c), "curve_type");
+    }
 
   gtk_curve_draw (c, c->num_points, height);
 }
@@ -840,24 +1020,26 @@ gtk_curve_get_vector (GtkCurve *c, int veclen, gfloat vector[])
 GtkWidget*
 gtk_curve_new (void)
 {
-  return gtk_type_new (gtk_curve_get_type ());
+  return g_object_new (GTK_TYPE_CURVE, NULL);
 }
 
 static void
-gtk_curve_finalize (GtkObject *object)
+gtk_curve_finalize (GObject *object)
 {
   GtkCurve *curve;
 
-  g_return_if_fail (object != NULL);
   g_return_if_fail (GTK_IS_CURVE (object));
 
   curve = GTK_CURVE (object);
   if (curve->pixmap)
-    gdk_pixmap_unref (curve->pixmap);
+    g_object_unref (curve->pixmap);
   if (curve->point)
     g_free (curve->point);
   if (curve->ctlpoint)
     g_free (curve->ctlpoint);
 
-  (*GTK_OBJECT_CLASS (parent_class)->finalize) (object);
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
+
+#define __GTK_CURVE_C__
+#include "gtkaliasdef.c"