1with Glib.Object;
2with Gdk.Drawable; use Gdk.Drawable;
3with Gdk.Event;    use Gdk.Event;
4with Gdk.Types;    use Gdk.Types;
5with Gdk.Window;   use Gdk.Window;
6with Gdk.Window_Attr; use Gdk.Window_Attr;
7
8with Gtk.Widget;    use Gtk.Widget;
9with Gtk.Style;     use Gtk.Style;
10with Gtk.Handlers;  use Gtk.Handlers;
11with Gtk.Event_Box; use Gtk.Event_Box;
12
13with System;
14
15with Ada.Numerics.Generic_Elementary_Functions; use Ada.Numerics;
16
17package body Gtk_Dial is
18
19   package Gdouble_Types is new
20     Ada.Numerics.Generic_Elementary_Functions (Gdouble);
21   use Gdouble_Types;
22
23   Scroll_Delay_Length : constant := 300;
24   Dial_Default_Size   : constant := 100;
25
26   ------------------------
27   -- Internal Callbacks --
28   ------------------------
29
30   procedure Destroy (Dial : access Gtk_Dial_Record'Class);
31
32   procedure Realize (Dial : access Gtk_Dial_Record'Class);
33
34   procedure Size_Request
35     (Dial : access Gtk_Dial_Record'Class;
36      Requisition : Gtk_Requisition_Access);
37
38   procedure Size_Allocate
39     (Dial : access Gtk_Dial_Record'Class;
40      Allocation : Gtk_Allocation_Access);
41
42   function Expose
43     (Dial : access Gtk_Dial_Record'Class; Event : Gdk_Event) return Boolean;
44
45   function Button_Press
46     (Dial  : access Gtk_Dial_Record'Class;
47      Event : Gdk_Event) return Boolean;
48
49   function Button_Release
50     (Dial  : access Gtk_Dial_Record'Class;
51      Event : Gdk_Event) return Boolean;
52
53   function Motion_Notify
54     (Dial : access Gtk_Dial_Record'Class;
55      Event : Gdk_Event) return Boolean;
56
57   procedure Adjustment_Changed
58     (Adjustment : access Gtk_Adjustment_Record'Class;
59      Dial       : Gtk_Dial);
60
61   procedure Adjustment_Value_Changed
62     (Adjustment : access Gtk_Adjustment_Record'Class;
63      Dial : Gtk_Dial);
64
65   ---------------------
66   -- Internal Timers --
67   ---------------------
68
69   function Timer (Dial : Gtk_Dial) return Boolean;
70
71   package Timeout is new Gtk.Main.Timeout (Gtk_Dial);
72
73   -------------------------
74   -- Internal procedures --
75   -------------------------
76
77   procedure Update_Mouse (Dial : access Gtk_Dial_Record'Class; X, Y : Gint);
78
79   procedure Update (Dial : access Gtk_Dial_Record'Class);
80
81   ----------------------------
82   -- Handler Instantiations --
83   ----------------------------
84
85   package Dial_Cb is new Gtk.Handlers.Callback (Gtk_Dial_Record);
86   package Adj_Cb is new Gtk.Handlers.Callback (Gtk_Adjustment_Record);
87
88   package Size_Cb is new Gtk.Handlers.Callback (Gtk_Dial_Record);
89   package Requisition_Marshaller is new Size_Cb.Marshallers.Generic_Marshaller
90     (Gtk_Requisition_Access, Get_Requisition);
91
92   package Allocation_Cb is new Gtk.Handlers.Callback (Gtk_Dial_Record);
93   package Allocation_Marshaller is new
94     Allocation_Cb.Marshallers.Generic_Marshaller
95       (Gtk_Allocation_Access, Get_Allocation);
96
97   package Event_Cb is new Gtk.Handlers.Return_Callback
98     (Gtk_Dial_Record, Boolean);
99
100   package Adjustment_Cb is new Gtk.Handlers.User_Callback
101     (Gtk_Adjustment_Record, Gtk_Dial);
102
103   package Realize_Pkg is new Gtk.Widget.Realize_Handling
104     (Gtk_Dial_Record, Realize);
105
106   -------------
107   -- Gtk_New --
108   -------------
109
110   procedure Gtk_New (Dial : out Gtk_Dial; Adjustment : Gtk_Adjustment) is
111   begin
112      Dial := new Gtk_Dial_Record;
113      Initialize (Dial, Adjustment);
114   end Gtk_New;
115
116   ----------------
117   -- Initialize --
118   ----------------
119
120   procedure Initialize
121     (Dial : access Gtk_Dial_Record'class;
122      Adjustment : Gtk_Adjustment)
123   is
124      Adj : Gtk_Adjustment;
125   begin
126      --  We first need to call the ancestor's Initialize function to create
127      --  the underlying C object.
128      Gtk.Event_Box.Initialize (Dial);
129
130      if Adjustment = null then
131         Gtk_New (Adj, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
132         Set_Adjustment (Dial, Adj);
133      else
134         Set_Adjustment (Dial, Adjustment);
135      end if;
136
137      --  Set up the appropriate callbacks to redraw, ...
138      Event_Cb.Connect
139        (Dial, "expose_event", Event_Cb.To_Marshaller (Expose'Access), True);
140      Size_Cb.Connect
141        (Dial, "size_request",
142         Requisition_Marshaller.To_Marshaller (Size_Request'Access));
143      Allocation_Cb.Connect
144        (Dial, "size_allocate",
145         Allocation_Marshaller.To_Marshaller (Size_Allocate'Access));
146      Event_Cb.Connect
147        (Dial, "button_press_event",
148         Event_Cb.To_Marshaller (Button_Press'Access), True);
149      Event_Cb.Connect
150        (Dial, "button_release_event",
151         Event_Cb.To_Marshaller (Button_Release'Access), True);
152      Dial_Cb.Connect
153        (Dial, "destroy", Dial_Cb.To_Marshaller (Destroy'Access));
154      Event_Cb.Connect
155        (Dial, "motion_notify_event",
156         Event_Cb.To_Marshaller (Motion_Notify'Access), True);
157
158      Realize_Pkg.Set_Realize (Dial);
159   end Initialize;
160
161   -------------
162   -- Destroy --
163   -------------
164
165   procedure Destroy (Dial : access Gtk_Dial_Record'Class) is
166   begin
167      if Dial.Adjustment /= null then
168         Unref (Dial.Adjustment);
169      end if;
170
171      Gtk.Handlers.Emit_Stop_By_Name (Dial, "destroy");
172   end Destroy;
173
174   --------------------
175   -- Get_Adjustment --
176   --------------------
177
178   function Get_Adjustment (Dial : access Gtk_Dial_Record)
179     return Gtk_Adjustment is
180   begin
181      return Dial.Adjustment;
182   end Get_Adjustment;
183
184   -----------------------
185   -- Set_Update_Policy --
186   -----------------------
187
188   procedure Set_Update_Policy
189     (Dial : access Gtk_Dial_Record;
190      Policy : Gtk_Update_Type) is
191   begin
192      Dial.Policy := Policy;
193   end Set_Update_Policy;
194
195   --------------------
196   -- Set_Adjustment --
197   --------------------
198
199   procedure Set_Adjustment
200     (Dial : access Gtk_Dial_Record; Adjustment : Gtk_Adjustment) is
201   begin
202      if Dial.Adjustment /= null then
203         Gtk.Handlers.Disconnect (Dial.Adjustment, Dial.Changed_Id);
204         Gtk.Handlers.Disconnect (Dial.Adjustment, Dial.Value_Changed_Id);
205         Unref (Dial.Adjustment);
206      end if;
207
208      Dial.Adjustment := Adjustment;
209      Ref (Dial.Adjustment);
210
211      Dial.Changed_Id := Adjustment_Cb.Connect
212        (Adjustment, "changed",
213         Adjustment_Cb.To_Marshaller (Adjustment_Changed'Access),
214         Gtk_Dial (Dial));
215      Dial.Value_Changed_Id := Adjustment_Cb.Connect
216        (Adjustment, "value_changed",
217         Adjustment_Cb.To_Marshaller (Adjustment_Value_Changed'Access),
218         Gtk_Dial (Dial));
219
220      Dial.Old_Value := Get_Value (Adjustment);
221      Dial.Old_Lower := Get_Lower (Adjustment);
222      Dial.Old_Upper := Get_Upper (Adjustment);
223
224      Update (Dial);
225   end Set_Adjustment;
226
227   -------------
228   -- Realize --
229   -------------
230
231   procedure Realize (Dial : access Gtk_Dial_Record'Class) is
232      Attributes : Gdk_Window_Attr;
233      Attributes_Mask : Gdk_Window_Attributes_Type;
234      Window : Gdk_Window;
235
236      procedure Set_User_Data
237        (Window : Gdk.Gdk_Window; Widget : System.Address);
238      pragma Import (C, Set_User_Data, "gdk_window_set_user_data");
239
240   begin
241      Set_Flags (Dial, Realized);
242
243      Gdk_New (Attributes,
244        X => Get_Allocation_X (Dial),
245        Y => Get_Allocation_Y (Dial),
246        Width => Gint (Get_Allocation_Width (Dial)),
247        Height => Gint (Get_Allocation_Height (Dial)),
248        Window_Type => Window_Child,
249        Event_Mask => Get_Events (Dial) or Exposure_Mask or
250          Button_Press_Mask or Button_Release_Mask or Pointer_Motion_Mask or
251          Pointer_Motion_Hint_Mask,
252        Visual => Get_Visual (Dial),
253        Colormap => Get_Colormap (Dial));
254      Attributes_Mask := Wa_X or Wa_Y or Wa_Visual or Wa_Colormap;
255      Gdk_New (Window, Get_Window (Get_Parent (Dial)),
256        Attributes, Attributes_Mask);
257      Set_Window (Dial, Window);
258      Set_Style (Dial, Attach (Get_Style (Dial), Get_Window (Dial)));
259
260      Set_User_Data (Window, Glib.Object.Get_Object (Dial));
261
262      Set_Background (Get_Style (Dial), Get_Window (Dial), State_Active);
263   end Realize;
264
265   ------------------
266   -- Size_Request --
267   ------------------
268
269   procedure Size_Request
270     (Dial : access Gtk_Dial_Record'Class;
271      Requisition : Gtk_Requisition_Access) is
272   begin
273      Requisition.Width := Dial_Default_Size;
274      Requisition.Height := Dial_Default_Size;
275
276      --  Stop the signal from being propagated to the parent's default
277      --  size_request function
278      Gtk.Handlers.Emit_Stop_By_Name (Dial, "size_request");
279   end Size_Request;
280
281   -------------------
282   -- Size_Allocate --
283   -------------------
284
285   procedure Size_Allocate
286     (Dial : access Gtk_Dial_Record'Class;
287      Allocation : Gtk_Allocation_Access) is
288   begin
289      if Realized_Is_Set (Dial) then
290         Gdk.Window.Move_Resize
291           (Get_Window (Dial),
292            Allocation.X, Allocation.Y,
293            Gint (Allocation.Width),
294            Gint (Allocation.Height));
295      end if;
296
297      Dial.Radius := Gint (
298        Gdouble (Gint'Min (Allocation.Width, Allocation.Height)) * 0.45);
299      Dial.Pointer_Width := Dial.Radius / 5;
300
301      Gtk.Handlers.Emit_Stop_By_Name (Dial, "size_allocate");
302   end Size_Allocate;
303
304   ------------
305   -- Expose --
306   ------------
307
308   function Expose
309     (Dial : access Gtk_Dial_Record'Class; Event : Gdk_Event) return Boolean
310   is
311      Points       : Gdk_Points_Array (1 .. 5);
312      S, C         : Gdouble;
313      Theta,
314      Last,
315      Increment    : Gdouble;
316      Blankstyle   : Gtk_Style;
317      Xc, Yc       : Gdouble;
318      Upper, Lower : Gint;
319      Tick_Length  : Gint;
320      Inc          : Gint;
321
322   begin
323      Gtk.Handlers.Emit_Stop_By_Name (Dial, "expose_event");
324
325      if Get_Count (Event) > 0 then
326         return False;
327      end if;
328
329      Gdk.Window.Clear_Area (Get_Window (Dial),
330        0, 0,
331        Gint (Get_Allocation_Width (Dial)),
332        Gint (Get_Allocation_Height (Dial)));
333
334      Xc := Gdouble (Get_Allocation_Width (Dial)) / 2.0;
335      Yc := Gdouble (Get_Allocation_Height (Dial)) / 2.0;
336
337      Upper := Gint (Get_Upper (Dial.Adjustment));
338      Lower := Gint (Get_Lower (Dial.Adjustment));
339
340      --  Erase old pointer
341
342      S := Gdouble (Sin (Dial.Last_Angle));
343      C := Gdouble (Cos (Dial.Last_Angle));
344      Dial.Last_Angle := Dial.Angle;
345
346      Points (1).X := Gint (Xc + S * Gdouble (Dial.Pointer_Width) / 2.0);
347      Points (1).Y := Gint (Yc + C * Gdouble (Dial.Pointer_Width) / 2.0);
348      Points (2).X := Gint (Xc + C * Gdouble (Dial.Radius));
349      Points (2).Y := Gint (Yc - S * Gdouble (Dial.Radius));
350      Points (3).X := Gint (Xc - S * Gdouble (Dial.Pointer_Width) / 2.0);
351      Points (3).Y := Gint (Yc - C * Gdouble (Dial.Pointer_Width) / 2.0);
352      Points (4).X := Gint (Xc - C * Gdouble (Dial.Radius) / 10.0);
353      Points (4).Y := Gint (Yc + S * Gdouble (Dial.Radius) / 10.0);
354      Points (5).X := Points (1).X;
355      Points (5).Y := Points (1).Y;
356
357      Gtk_New (Blankstyle);
358      Set_Bg_GC (Blankstyle, State_Normal,
359        Get_Bg_GC (Get_Style (Dial), State_Normal));
360      Set_Dark_GC (Blankstyle, State_Normal,
361        Get_Bg_GC (Get_Style (Dial), State_Normal));
362      Set_Light_GC (Blankstyle, State_Normal,
363        Get_Bg_GC (Get_Style (Dial), State_Normal));
364      Set_Black_GC (Blankstyle,
365        Get_Bg_GC (Get_Style (Dial), State_Normal));
366
367      Draw_Polygon
368        (Blankstyle, Get_Window (Dial),
369         State_Normal, Shadow_Out,
370         Points, False);
371
372      Unref (Blankstyle);
373
374      --  Draw ticks
375
376      if Upper - Lower = 0 then
377         return False;
378      end if;
379
380      Increment := (100.0 * Pi) / (Gdouble (Dial.Radius * Dial.Radius));
381      Inc := Upper - Lower;
382
383      while Inc < 100 loop
384         Inc := Inc * 10;
385      end loop;
386
387      while Inc >= 1000 loop
388         Inc := Inc / 10;
389      end loop;
390
391      Last := -1.0;
392
393      for J in 0 .. Inc loop
394         Theta := Gdouble (J) * Pi / (18.0 * Gdouble (Inc) / 24.0) - Pi / 6.0;
395
396         if Theta - Last >= Increment then
397            Last := Theta;
398
399            S := Sin (Theta);
400            C := Cos (Theta);
401
402            if J rem (Inc / 10) = 0 then
403               Tick_Length := Dial.Pointer_Width;
404            else
405               Tick_Length := Dial.Pointer_Width / 2;
406            end if;
407
408            Draw_Line
409              (Get_Window (Dial),
410               Get_Fg_GC (Get_Style (Dial), Get_State (Dial)),
411               Gint (Xc + C * Gdouble (Dial.Radius - Tick_Length)),
412               Gint (Yc - S * Gdouble (Dial.Radius - Tick_Length)),
413               Gint (Xc + C * Gdouble (Dial.Radius)),
414               Gint (Yc - S * Gdouble (Dial.Radius)));
415         end if;
416      end loop;
417
418      --  Draw pointer
419
420      S := Sin (Dial.Angle);
421      C := Cos (Dial.Angle);
422      Dial.Last_Angle := Dial.Angle;
423
424      Points (1).X := Gint (Xc + S * Gdouble (Dial.Pointer_Width) / 2.0);
425      Points (1).Y := Gint (Yc + C * Gdouble (Dial.Pointer_Width) / 2.0);
426      Points (2).X := Gint (Xc + C * Gdouble (Dial.Radius));
427      Points (2).Y := Gint (Yc - S * Gdouble (Dial.Radius));
428      Points (3).X := Gint (Xc - S * Gdouble (Dial.Pointer_Width) / 2.0);
429      Points (3).Y := Gint (Yc - C * Gdouble (Dial.Pointer_Width) / 2.0);
430      Points (4).X := Gint (Xc - C * Gdouble (Dial.Radius) / 10.0);
431      Points (4).Y := Gint (Yc + S * Gdouble (Dial.Radius) / 10.0);
432      Points (5).X := Points (1).X;
433      Points (5).Y := Points (1).Y;
434
435      Draw_Polygon
436        (Get_Style (Dial), Get_Window (Dial), State_Normal, Shadow_Out,
437         Points, True);
438
439      return False;
440   end Expose;
441
442   ------------------
443   -- Button_Press --
444   ------------------
445
446   function Button_Press
447     (Dial  : access Gtk_Dial_Record'Class;
448      Event : Gdk_Event) return Boolean
449   is
450      Dx, Dy          : Gint;
451      S, C            : Gdouble;
452      D_Parallel      : Gdouble;
453      D_Perpendicular : Gdouble;
454
455   begin
456      --  Determine if button press was within pointer region - we
457      --  do this by computing the parallel and perpendicular distance of
458      --  the point where the mouse was pressed from the line passing through
459      --  the pointer
460
461      Dx := Gint (Get_X (Event) - Gdouble (Get_Allocation_Width (Dial)) / 2.0);
462      Dy :=
463        Gint (Gdouble (Get_Allocation_Height (Dial)) / 2.0 - Get_Y (Event));
464
465      S := Sin (Dial.Angle);
466      C := Cos (Dial.Angle);
467
468      D_Parallel := S * Gdouble (Dy) + C * Gdouble (Dx);
469      D_Perpendicular := abs (S * Gdouble (Dx) - C * Gdouble (Dy));
470
471      if Dial.Button = 0 and then
472        D_Perpendicular < Gdouble (Dial.Pointer_Width) / 2.0 and then
473        D_Parallel > Gdouble (-Dial.Pointer_Width)
474      then
475         Grab_Add (Dial);
476         Dial.Button := Get_Button (Event);
477         Update_Mouse (Dial, Gint (Get_X (Event)), Gint (Get_Y (Event)));
478      end if;
479
480      Gtk.Handlers.Emit_Stop_By_Name (Dial, "button_press_event");
481      return False;
482   end Button_Press;
483
484   --------------------
485   -- Button_Release --
486   --------------------
487
488   function Button_Release
489     (Dial  : access Gtk_Dial_Record'Class;
490      Event : Gdk_Event) return Boolean is
491   begin
492      if Dial.Button = Get_Button (Event) then
493         Grab_Remove (Dial);
494
495         Dial.Button := 0;
496
497         if Dial.Policy = Update_Delayed then
498            Timeout_Remove (Dial.Timer);
499         end if;
500
501         if Dial.Policy /= Update_Continuous and then
502           Dial.Old_Value /= Get_Value (Dial.Adjustment)
503         then
504            Adj_Cb.Emit_By_Name (Dial.Adjustment, "value_changed");
505         end if;
506      end if;
507
508      Gtk.Handlers.Emit_Stop_By_Name (Dial, "button_release_event");
509      return False;
510   end Button_Release;
511
512   -------------------
513   -- Motion_Notify --
514   -------------------
515
516   function Motion_Notify
517     (Dial : access Gtk_Dial_Record'Class; Event : Gdk_Event)
518      return Boolean
519   is
520      Mods, Mask : Gdk_Modifier_Type;
521      X, Y : Gint;
522      Window : Gdk_Window;
523
524      use Gdk;
525   begin
526      if Dial.Button /= 0 then
527         X := Gint (Get_X (Event));
528         Y := Gint (Get_Y (Event));
529
530         if Get_Is_Hint (Event)
531           or else Get_Window (Event) /= Get_Window (Dial)
532         then
533            Get_Pointer (Get_Window (Dial), X, Y, Mods, Window);
534         end if;
535
536         case Dial.Button is
537            when 1 => Mask := Button1_Mask;
538            when 2 => Mask := Button2_Mask;
539            when 3 => Mask := Button3_Mask;
540            when others => Mask := 0;
541         end case;
542
543         if (Mods and Mask) /= 0 then
544            Update_Mouse (Dial, X, Y);
545         end if;
546      end if;
547
548      Gtk.Handlers.Emit_Stop_By_Name (Dial, "motion_notify_event");
549      return False;
550   end Motion_Notify;
551
552   -----------
553   -- Timer --
554   -----------
555
556   function Timer (Dial : Gtk_Dial) return Boolean is
557   begin
558      if Dial.Policy = Update_Delayed then
559         Adj_Cb.Emit_By_Name (Dial.Adjustment, "value_changed");
560      end if;
561
562      return False;
563   end Timer;
564
565   ------------------
566   -- Update_Mouse --
567   ------------------
568
569   procedure Update_Mouse (Dial : access Gtk_Dial_Record'Class; X, Y : Gint) is
570      Xc, Yc : Gint;
571      Old_Value : Gdouble;
572
573   begin
574      Xc := Gint (Get_Allocation_Width (Dial) / 2);
575      Yc := Gint (Get_Allocation_Height (Dial) / 2);
576
577      Old_Value := Get_Value (Dial.Adjustment);
578      Dial.Angle := Arctan (Gdouble (Yc - Y), Gdouble (X - Xc));
579
580      if Dial.Angle < -Pi / 2.0 then
581         Dial.Angle := Dial.Angle + 2.0 * Pi;
582      end if;
583
584      if Dial.Angle < -Pi / 6.0 then
585         Dial.Angle := -Pi / 6.0;
586      end if;
587
588      if Dial.Angle > 7.0 * Pi/6.0 then
589         Dial.Angle := 7.0 * Pi/6.0;
590      end if;
591
592      Set_Value
593        (Dial.Adjustment,
594         Get_Lower (Dial.Adjustment) +
595           (7.0 * Pi / 6.0 - Dial.Angle) *
596             (Get_Upper (Dial.Adjustment) - Get_Lower (Dial.Adjustment)) /
597               (4.0 * Pi / 3.0));
598
599      if Get_Value (Dial.Adjustment) /= Old_Value then
600         if Dial.Policy = Update_Continuous then
601            Adj_Cb.Emit_By_Name (Dial.Adjustment, "value_changed");
602         else
603            Draw (Dial);
604
605            if Dial.Policy = Update_Delayed then
606               if Dial.Timer /= 0 then
607                  Timeout_Remove (Dial.Timer);
608               end if;
609
610               Dial.Timer := Timeout.Add
611                 (Scroll_Delay_Length, Timer'Access, Gtk_Dial (Dial));
612            end if;
613         end if;
614      end if;
615
616      exception
617         when Ada.Numerics.Argument_Error => null;
618   end Update_Mouse;
619
620   ------------
621   -- Update --
622   ------------
623
624   procedure Update (Dial : access Gtk_Dial_Record'Class) is
625      New_Value : Gdouble;
626   begin
627      New_Value := Get_Value (Dial.Adjustment);
628
629      if New_Value < Get_Lower (Dial.Adjustment) then
630         New_Value := Get_Lower (Dial.Adjustment);
631      end if;
632
633      if New_Value > Get_Upper (Dial.Adjustment) then
634         New_Value := Get_Upper (Dial.Adjustment);
635      end if;
636
637      if New_Value /= Get_Value (Dial.Adjustment) then
638         Set_Value (Dial.Adjustment, New_Value);
639         Adj_Cb.Emit_By_Name (Dial.Adjustment, "value_changed");
640      end if;
641
642      Dial.Angle := 7.0 * Pi / 6.0 -
643        (Gdouble (New_Value - Get_Lower (Dial.Adjustment))) * 4.0 * Pi / 3.0 /
644          Gdouble (Get_Upper (Dial.Adjustment) - Get_Lower (Dial.Adjustment));
645      Draw (Dial);
646   end Update;
647
648   ------------------------
649   -- Adjustment_Changed --
650   ------------------------
651
652   procedure Adjustment_Changed
653     (Adjustment : access Gtk_Adjustment_Record'Class;
654      Dial       : Gtk_Dial) is
655   begin
656      if Dial.Old_Value /= Get_Value (Adjustment) or else
657         Dial.Old_Lower /= Get_Lower (Adjustment) or else
658         Dial.Old_Upper /= Get_Upper (Adjustment)
659      then
660         Update (Dial);
661         Dial.Old_Value := Get_Value (Adjustment);
662         Dial.Old_Lower := Get_Lower (Adjustment);
663         Dial.Old_Upper := Get_Upper (Adjustment);
664      end if;
665   end Adjustment_Changed;
666
667   ------------------------------
668   -- Adjustment_Value_Changed --
669   ------------------------------
670
671   procedure Adjustment_Value_Changed
672     (Adjustment : access Gtk_Adjustment_Record'Class;
673      Dial : Gtk_Dial) is
674   begin
675      if Dial.Old_Value /= Get_Value (Adjustment) then
676         Update (Dial);
677         Dial.Old_Value := Get_Value (Adjustment);
678      end if;
679   end Adjustment_Value_Changed;
680
681end Gtk_Dial;
682