]> Pileus Git - ~andy/gtk/blobdiff - examples/gtkdial/gtkdial.c
Replace a lot of idle and timeout calls by the new gdk_threads api.
[~andy/gtk] / examples / gtkdial / gtkdial.c
index db759be5d98a810791c99b7aa1d20f547d6a4e78..5749e92ad85439e4b3d3fd01bb192abbca556f54 100644 (file)
@@ -1,3 +1,4 @@
+
 /* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
@@ -12,8 +13,9 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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 <math.h>
 #include <stdio.h>
 #define SCROLL_DELAY_LENGTH  300
 #define DIAL_DEFAULT_SIZE 100
 
-/* Forward declararations */
+/* Forward declarations */
 
-static void gtk_dial_class_init               (GtkDialClass    *klass);
-static void gtk_dial_init                     (GtkDial         *dial);
+static void gtk_dial_class_init               (GtkDialClass     *klass);
+static void gtk_dial_init                     (GtkDial          *dial);
 static void gtk_dial_destroy                  (GtkObject        *object);
 static void gtk_dial_realize                  (GtkWidget        *widget);
-static void gtk_dial_size_request             (GtkWidget      *widget,
-                                              GtkRequisition *requisition);
-static void gtk_dial_size_allocate            (GtkWidget     *widget,
-                                              GtkAllocation *allocation);
-static gint gtk_dial_expose                   (GtkWidget        *widget,
-                                               GdkEventExpose   *event);
-static gint gtk_dial_button_press             (GtkWidget        *widget,
-                                               GdkEventButton   *event);
-static gint gtk_dial_button_release           (GtkWidget        *widget,
-                                               GdkEventButton   *event);
-static gint gtk_dial_motion_notify            (GtkWidget        *widget,
-                                               GdkEventMotion   *event);
-static gint gtk_dial_timer                    (GtkDial         *dial);
+static void gtk_dial_size_request             (GtkWidget        *widget,
+                                               GtkRequisition   *requisition);
+static void gtk_dial_size_allocate            (GtkWidget        *widget,
+                                               GtkAllocation    *allocation);
+static gboolean gtk_dial_expose               (GtkWidget        *widget,
+                                               GdkEventExpose   *event);
+static gboolean gtk_dial_button_press         (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gboolean gtk_dial_button_release       (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gboolean gtk_dial_motion_notify        (GtkWidget        *widget,
+                                               GdkEventMotion   *event);
+static gboolean gtk_dial_timer                (GtkDial          *dial);
 
 static void gtk_dial_update_mouse             (GtkDial *dial, gint x, gint y);
 static void gtk_dial_update                   (GtkDial *dial);
@@ -56,25 +58,27 @@ static void gtk_dial_adjustment_value_changed (GtkAdjustment    *adjustment,
 
 static GtkWidgetClass *parent_class = NULL;
 
-guint
+GType
 gtk_dial_get_type ()
 {
-  static guint dial_type = 0;
+  static GType dial_type = 0;
 
   if (!dial_type)
     {
-      GtkTypeInfo dial_info =
+      static const GTypeInfo dial_info =
       {
-       "GtkDial",
-       sizeof (GtkDial),
        sizeof (GtkDialClass),
-       (GtkClassInitFunc) gtk_dial_class_init,
-       (GtkObjectInitFunc) gtk_dial_init,
-       (GtkArgSetFunc) NULL,
-       (GtkArgGetFunc) NULL,
+       NULL,
+       NULL,
+       (GClassInitFunc) gtk_dial_class_init,
+       NULL,
+       NULL,
+       sizeof (GtkDial),
+        0,
+       (GInstanceInitFunc) gtk_dial_init,
       };
 
-      dial_type = gtk_type_unique (gtk_widget_get_type (), &dial_info);
+      dial_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkDial", &dial_info, 0);
     }
 
   return dial_type;
@@ -122,7 +126,7 @@ gtk_dial_new (GtkAdjustment *adjustment)
 {
   GtkDial *dial;
 
-  dial = gtk_type_new (gtk_dial_get_type ());
+  dial = g_object_new (gtk_dial_get_type (), NULL);
 
   if (!adjustment)
     adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
@@ -143,7 +147,10 @@ gtk_dial_destroy (GtkObject *object)
   dial = GTK_DIAL (object);
 
   if (dial->adjustment)
-    gtk_object_unref (GTK_OBJECT (dial->adjustment));
+    {
+      g_object_unref (GTK_OBJECT (dial->adjustment));
+      dial->adjustment = NULL;
+    }
 
   if (GTK_OBJECT_CLASS (parent_class)->destroy)
     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
@@ -177,19 +184,19 @@ gtk_dial_set_adjustment (GtkDial      *dial,
 
   if (dial->adjustment)
     {
-      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), (gpointer) dial);
-      gtk_object_unref (GTK_OBJECT (dial->adjustment));
+      g_signal_handlers_disconnect_by_func (GTK_OBJECT (dial->adjustment), NULL, (gpointer) dial);
+      g_object_unref (GTK_OBJECT (dial->adjustment));
     }
 
   dial->adjustment = adjustment;
-  gtk_object_ref (GTK_OBJECT (dial->adjustment));
+  g_object_ref (GTK_OBJECT (dial->adjustment));
 
-  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                     (GtkSignalFunc) gtk_dial_adjustment_changed,
-                     (gpointer) dial);
-  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                     (GtkSignalFunc) gtk_dial_adjustment_value_changed,
-                     (gpointer) dial);
+  g_signal_connect (GTK_OBJECT (adjustment), "changed",
+                   GTK_SIGNAL_FUNC (gtk_dial_adjustment_changed),
+                   (gpointer) dial);
+  g_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                   GTK_SIGNAL_FUNC (gtk_dial_adjustment_value_changed),
+                   (gpointer) dial);
 
   dial->old_value = adjustment->value;
   dial->old_lower = adjustment->lower;
@@ -263,21 +270,23 @@ gtk_dial_size_allocate (GtkWidget     *widget,
                              allocation->width, allocation->height);
 
     }
-  dial->radius = MIN(allocation->width,allocation->height) * 0.45;
+  dial->radius = MIN (allocation->width, allocation->height) * 0.45;
   dial->pointer_width = dial->radius / 5;
 }
 
-static gint
-gtk_dial_expose (GtkWidget      *widget,
-                GdkEventExpose *event)
+static gboolean
+gtk_dial_exposeGtkWidget      *widget,
+                GdkEventExpose *event )
 {
   GtkDial *dial;
-  GdkPoint points[3];
+  GdkPoint points[6];
   gdouble s,c;
-  gdouble theta;
+  gdouble theta, last, increment;
+  GtkStyle      *blankstyle;
   gint xc, yc;
+  gint upper, lower;
   gint tick_length;
-  gint i;
+  gint i, inc;
 
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
@@ -288,37 +297,96 @@ gtk_dial_expose (GtkWidget      *widget,
   
   dial = GTK_DIAL (widget);
 
-  gdk_window_clear_area (widget->window,
+/*  gdk_window_clear_area (widget->window,
                         0, 0,
                         widget->allocation.width,
                         widget->allocation.height);
+*/
+  xc = widget->allocation.width / 2;
+  yc = widget->allocation.height / 2;
+
+  upper = dial->adjustment->upper;
+  lower = dial->adjustment->lower;
+
+  /* Erase old pointer */
+
+  s = sin (dial->last_angle);
+  c = cos (dial->last_angle);
+  dial->last_angle = dial->angle;
+
+  points[0].x = xc + s*dial->pointer_width/2;
+  points[0].y = yc + c*dial->pointer_width/2;
+  points[1].x = xc + c*dial->radius;
+  points[1].y = yc - s*dial->radius;
+  points[2].x = xc - s*dial->pointer_width/2;
+  points[2].y = yc - c*dial->pointer_width/2;
+  points[3].x = xc - c*dial->radius/10;
+  points[3].y = yc + s*dial->radius/10;
+  points[4].x = points[0].x;
+  points[4].y = points[0].y;
+
+  blankstyle = gtk_style_new ();
+  blankstyle->bg_gc[GTK_STATE_NORMAL] =
+                widget->style->bg_gc[GTK_STATE_NORMAL];
+  blankstyle->dark_gc[GTK_STATE_NORMAL] =
+                widget->style->bg_gc[GTK_STATE_NORMAL];
+  blankstyle->light_gc[GTK_STATE_NORMAL] =
+                widget->style->bg_gc[GTK_STATE_NORMAL];
+  blankstyle->black_gc =
+                widget->style->bg_gc[GTK_STATE_NORMAL];
+
+  gtk_paint_polygon (blankstyle,
+                    widget->window,
+                    GTK_STATE_NORMAL,
+                    GTK_SHADOW_OUT,
+                   NULL,
+                    widget,
+                    NULL,
+                    points, 5,
+                    FALSE);
+
+  g_object_unref (blankstyle);
 
-  xc = widget->allocation.width/2;
-  yc = widget->allocation.height/2;
 
   /* Draw ticks */
 
-  for (i=0; i<25; i++)
+  if ((upper - lower) == 0)
+    return FALSE;
+
+  increment = (100*M_PI) / (dial->radius*dial->radius);
+
+  inc = (upper - lower);
+
+  while (inc < 100) inc *= 10;
+  while (inc >= 1000) inc /= 10;
+  last = -1;
+
+  for (i = 0; i <= inc; i++)
     {
-      theta = (i*M_PI/18. - M_PI/6.);
-      s = sin(theta);
-      c = cos(theta);
+      theta = ((gfloat)i*M_PI / (18*inc/24.) - M_PI/6.);
+
+      if ((theta - last) < (increment))
+       continue;     
+      last = theta;
+
+      s = sin (theta);
+      c = cos (theta);
+
+      tick_length = (i%(inc/10) == 0) ? dial->pointer_width : dial->pointer_width / 2;
 
-      tick_length = (i%6 == 0) ? dial->pointer_width : dial->pointer_width/2;
-      
       gdk_draw_line (widget->window,
-                    widget->style->fg_gc[widget->state],
-                    xc + c*(dial->radius - tick_length),
-                    yc - s*(dial->radius - tick_length),
-                    xc + c*dial->radius,
-                    yc - s*dial->radius);
+                     widget->style->fg_gc[widget->state],
+                     xc + c*(dial->radius - tick_length),
+                     yc - s*(dial->radius - tick_length),
+                     xc + c*dial->radius,
+                     yc - s*dial->radius);
     }
 
   /* Draw pointer */
 
-  s = sin(dial->angle);
-  c = cos(dial->angle);
-
+  s = sin (dial->angle);
+  c = cos (dial->angle);
+  dial->last_angle = dial->angle;
 
   points[0].x = xc + s*dial->pointer_width/2;
   points[0].y = yc + c*dial->pointer_width/2;
@@ -326,20 +394,28 @@ gtk_dial_expose (GtkWidget      *widget,
   points[1].y = yc - s*dial->radius;
   points[2].x = xc - s*dial->pointer_width/2;
   points[2].y = yc - c*dial->pointer_width/2;
+  points[3].x = xc - c*dial->radius/10;
+  points[3].y = yc + s*dial->radius/10;
+  points[4].x = points[0].x;
+  points[4].y = points[0].y;
 
-  gtk_draw_polygon (widget->style,
+
+  gtk_paint_polygon (widget->style,
                    widget->window,
                    GTK_STATE_NORMAL,
                    GTK_SHADOW_OUT,
-                   points, 3,
+                   NULL,
+                    widget,
+                    NULL,
+                   points, 5,
                    TRUE);
-  
+
   return FALSE;
 }
 
-static gint
-gtk_dial_button_press (GtkWidget      *widget,
-                      GdkEventButton *event)
+static gboolean
+gtk_dial_button_pressGtkWidget      *widget,
+                      GdkEventButton *event )
 {
   GtkDial *dial;
   gint dx, dy;
@@ -361,11 +437,11 @@ gtk_dial_button_press (GtkWidget      *widget,
   dx = event->x - widget->allocation.width / 2;
   dy = widget->allocation.height / 2 - event->y;
   
-  s = sin(dial->angle);
-  c = cos(dial->angle);
+  s = sin (dial->angle);
+  c = cos (dial->angle);
   
   d_parallel = s*dy + c*dx;
-  d_perpendicular = fabs(s*dx - c*dy);
+  d_perpendicular = fabs (s*dx - c*dy);
   
   if (!dial->button &&
       (d_perpendicular < dial->pointer_width/2) &&
@@ -381,9 +457,9 @@ gtk_dial_button_press (GtkWidget      *widget,
   return FALSE;
 }
 
-static gint
-gtk_dial_button_release (GtkWidget      *widget,
-                         GdkEventButton *event)
+static gboolean
+gtk_dial_button_releaseGtkWidget      *widget,
+                         GdkEventButton *event )
 {
   GtkDial *dial;
 
@@ -400,19 +476,19 @@ gtk_dial_button_release (GtkWidget      *widget,
       dial->button = 0;
 
       if (dial->policy == GTK_UPDATE_DELAYED)
-       gtk_timeout_remove (dial->timer);
+       g_source_remove (dial->timer);
       
       if ((dial->policy != GTK_UPDATE_CONTINUOUS) &&
          (dial->old_value != dial->adjustment->value))
-       gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+       g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
     }
 
   return FALSE;
 }
 
-static gint
-gtk_dial_motion_notify (GtkWidget      *widget,
-                        GdkEventMotion *event)
+static gboolean
+gtk_dial_motion_notifyGtkWidget      *widget,
+                        GdkEventMotion *event )
 {
   GtkDial *dial;
   GdkModifierType mods;
@@ -455,20 +531,20 @@ gtk_dial_motion_notify (GtkWidget      *widget,
   return FALSE;
 }
 
-static gint
-gtk_dial_timer (GtkDial *dial)
+static gboolean
+gtk_dial_timer( GtkDial *dial )
 {
   g_return_val_if_fail (dial != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
 
   if (dial->policy == GTK_UPDATE_DELAYED)
-    gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
 
   return FALSE;
 }
 
 static void
-gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
+gtk_dial_update_mouse( GtkDial *dial, gint x, gint y )
 {
   gint xc, yc;
   gfloat old_value;
@@ -498,20 +574,20 @@ gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
     {
       if (dial->policy == GTK_UPDATE_CONTINUOUS)
        {
-         gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+         g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
        }
       else
        {
-         gtk_widget_draw (GTK_WIDGET(dial), NULL);
+         gtk_widget_queue_draw (GTK_WIDGET (dial));
 
          if (dial->policy == GTK_UPDATE_DELAYED)
            {
              if (dial->timer)
-               gtk_timeout_remove (dial->timer);
+               g_source_remove (dial->timer);
 
-             dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
-                                            (GtkFunction) gtk_dial_timer,
-                                            (gpointer) dial);
+             dial->timer = gdk_threads_add_timeout (SCROLL_DELAY_LENGTH,
+                                          (GSourceFunc) gtk_dial_timer,
+                                          (gpointer) dial);
            }
        }
     }
@@ -536,13 +612,13 @@ gtk_dial_update (GtkDial *dial)
   if (new_value != dial->adjustment->value)
     {
       dial->adjustment->value = new_value;
-      gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+      g_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
     }
 
   dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
     (dial->adjustment->upper - dial->adjustment->lower);
 
-  gtk_widget_draw (GTK_WIDGET(dial), NULL);
+  gtk_widget_queue_draw (GTK_WIDGET (dial));
 }
 
 static void
@@ -586,5 +662,3 @@ gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
       dial->old_value = adjustment->value;
     }
 }
-
-