]> Pileus Git - ~andy/gtk/blob - gtk/gtkscale.c
Fix various compilation problems (#134312, David Hawthorne)
[~andy/gtk] / gtk / gtkscale.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 2001 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include <math.h>
29 #include "gtkintl.h"
30 #include "gtkscale.h"
31 #include "gtkmarshalers.h"
32 #include "gdk/gdkkeysyms.h"
33 #include "gtkbindings.h"
34
35
36 #define MAX_DIGITS      (64)    /* don't change this,
37                                  * a) you don't need to and
38                                  * b) you might cause buffer owerflows in
39                                  *    unrelated code portions otherwise
40                                  */
41
42 #define GTK_SCALE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_SCALE, GtkScalePrivate))
43
44 typedef struct _GtkScalePrivate GtkScalePrivate;
45
46 struct _GtkScalePrivate
47 {
48   PangoLayout *layout;
49 };
50
51 enum {
52   PROP_0,
53   PROP_DIGITS,
54   PROP_DRAW_VALUE,
55   PROP_VALUE_POS
56 };
57
58 enum {
59   FORMAT_VALUE,
60   LAST_SIGNAL
61 };
62
63 static guint signals[LAST_SIGNAL];
64 static GtkRangeClass *parent_class = NULL;
65
66 static void gtk_scale_class_init       (GtkScaleClass *klass);
67 static void gtk_scale_init             (GtkScale      *scale);
68 static void gtk_scale_set_property     (GObject       *object,
69                                         guint          prop_id,
70                                         const GValue  *value,
71                                         GParamSpec    *pspec);
72 static void gtk_scale_get_property     (GObject       *object,
73                                         guint          prop_id,
74                                         GValue        *value,
75                                         GParamSpec    *pspec);
76 static void gtk_scale_style_set        (GtkWidget     *widget,
77                                         GtkStyle      *previous);
78 static void gtk_scale_get_range_border (GtkRange      *range,
79                                         GtkBorder     *border);
80 static void gtk_scale_finalize         (GObject       *object);
81 static void gtk_scale_screen_changed   (GtkWidget     *widget,
82                                         GdkScreen     *old_screen);
83
84 GType
85 gtk_scale_get_type (void)
86 {
87   static GType scale_type = 0;
88
89   if (!scale_type)
90     {
91       static const GTypeInfo scale_info =
92       {
93         sizeof (GtkScaleClass),
94         NULL,           /* base_init */
95         NULL,           /* base_finalize */
96         (GClassInitFunc) gtk_scale_class_init,
97         NULL,           /* class_finalize */
98         NULL,           /* class_data */
99         sizeof (GtkScale),
100         0,              /* n_preallocs */
101         (GInstanceInitFunc) gtk_scale_init,
102         NULL,           /* value_table */
103       };
104
105       scale_type = g_type_register_static (GTK_TYPE_RANGE, "GtkScale",
106                                            &scale_info, G_TYPE_FLAG_ABSTRACT);
107     }
108
109   return scale_type;
110 }
111
112 static gboolean
113 single_string_accumulator (GSignalInvocationHint *ihint,
114                            GValue                *return_accu,
115                            const GValue          *handler_return,
116                            gpointer               dummy)
117 {
118   gboolean continue_emission;
119   const gchar *str;
120   
121   str = g_value_get_string (handler_return);
122   g_value_set_string (return_accu, str);
123   continue_emission = str == NULL;
124   
125   return continue_emission;
126 }
127
128
129 #define add_slider_binding(binding_set, keyval, mask, scroll)          \
130   gtk_binding_entry_add_signal (binding_set, keyval, mask,             \
131                                 "move_slider", 1,                      \
132                                 GTK_TYPE_SCROLL_TYPE, scroll)
133
134 static void
135 gtk_scale_class_init (GtkScaleClass *class)
136 {
137   GObjectClass   *gobject_class;
138   GtkWidgetClass *widget_class;
139   GtkRangeClass  *range_class;
140   GtkBindingSet  *binding_set;
141   
142   gobject_class = G_OBJECT_CLASS (class);
143   range_class = (GtkRangeClass*) class;
144   widget_class = (GtkWidgetClass*) class;
145   
146   parent_class = g_type_class_peek_parent (class);
147   
148   gobject_class->set_property = gtk_scale_set_property;
149   gobject_class->get_property = gtk_scale_get_property;
150   gobject_class->finalize = gtk_scale_finalize;
151
152   widget_class->style_set = gtk_scale_style_set;
153   widget_class->screen_changed = gtk_scale_screen_changed;
154
155   range_class->get_range_border = gtk_scale_get_range_border;
156   
157   signals[FORMAT_VALUE] =
158     g_signal_new ("format_value",
159                   G_TYPE_FROM_CLASS (gobject_class),
160                   G_SIGNAL_RUN_LAST,
161                   G_STRUCT_OFFSET (GtkScaleClass, format_value),
162                   single_string_accumulator, NULL,
163                   _gtk_marshal_STRING__DOUBLE,
164                   G_TYPE_STRING, 1,
165                   G_TYPE_DOUBLE);
166
167   g_object_class_install_property (gobject_class,
168                                    PROP_DIGITS,
169                                    g_param_spec_int ("digits",
170                                                      P_("Digits"),
171                                                      P_("The number of decimal places that are displayed in the value"),
172                                                      -1,
173                                                      MAX_DIGITS,
174                                                      1,
175                                                      G_PARAM_READWRITE));
176   
177   g_object_class_install_property (gobject_class,
178                                    PROP_DRAW_VALUE,
179                                    g_param_spec_boolean ("draw_value",
180                                                          P_("Draw Value"),
181                                                          P_("Whether the current value is displayed as a string next to the slider"),
182                                                          FALSE,
183                                                          G_PARAM_READWRITE));
184   
185   g_object_class_install_property (gobject_class,
186                                    PROP_VALUE_POS,
187                                    g_param_spec_enum ("value_pos",
188                                                       P_("Value Position"),
189                                                       P_("The position in which the current value is displayed"),
190                                                       GTK_TYPE_POSITION_TYPE,
191                                                       GTK_POS_LEFT,
192                                                       G_PARAM_READWRITE));
193
194   gtk_widget_class_install_style_property (widget_class,
195                                            g_param_spec_int ("slider_length",
196                                                              P_("Slider Length"),
197                                                              P_("Length of scale's slider"),
198                                                              0,
199                                                              G_MAXINT,
200                                                              31,
201                                                              G_PARAM_READABLE));
202
203   gtk_widget_class_install_style_property (widget_class,
204                                            g_param_spec_int ("value_spacing",
205                                                              P_("Value spacing"),
206                                                              P_("Space between value text and the slider/trough area"),
207                                                              0,
208                                                              G_MAXINT,
209                                                              2,
210                                                              G_PARAM_READABLE));
211   
212   /* All bindings (even arrow keys) are on both h/v scale, because
213    * blind users etc. don't care about scale orientation.
214    */
215   
216   binding_set = gtk_binding_set_by_class (class);
217
218   add_slider_binding (binding_set, GDK_Left, 0,
219                       GTK_SCROLL_STEP_LEFT);
220
221   add_slider_binding (binding_set, GDK_Left, GDK_CONTROL_MASK,
222                       GTK_SCROLL_PAGE_LEFT);
223
224   add_slider_binding (binding_set, GDK_KP_Left, 0,
225                       GTK_SCROLL_STEP_LEFT);
226
227   add_slider_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK,
228                       GTK_SCROLL_PAGE_LEFT);
229
230   add_slider_binding (binding_set, GDK_Right, 0,
231                       GTK_SCROLL_STEP_RIGHT);
232
233   add_slider_binding (binding_set, GDK_Right, GDK_CONTROL_MASK,
234                       GTK_SCROLL_PAGE_RIGHT);
235
236   add_slider_binding (binding_set, GDK_KP_Right, 0,
237                       GTK_SCROLL_STEP_RIGHT);
238
239   add_slider_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK,
240                       GTK_SCROLL_PAGE_RIGHT);
241
242   add_slider_binding (binding_set, GDK_Up, 0,
243                       GTK_SCROLL_STEP_UP);
244
245   add_slider_binding (binding_set, GDK_Up, GDK_CONTROL_MASK,
246                       GTK_SCROLL_PAGE_UP);
247
248   add_slider_binding (binding_set, GDK_KP_Up, 0,
249                       GTK_SCROLL_STEP_UP);
250
251   add_slider_binding (binding_set, GDK_KP_Up, GDK_CONTROL_MASK,
252                       GTK_SCROLL_PAGE_UP);
253
254   add_slider_binding (binding_set, GDK_Down, 0,
255                       GTK_SCROLL_STEP_DOWN);
256
257   add_slider_binding (binding_set, GDK_Down, GDK_CONTROL_MASK,
258                       GTK_SCROLL_PAGE_DOWN);
259
260   add_slider_binding (binding_set, GDK_KP_Down, 0,
261                       GTK_SCROLL_STEP_DOWN);
262
263   add_slider_binding (binding_set, GDK_KP_Down, GDK_CONTROL_MASK,
264                       GTK_SCROLL_PAGE_DOWN);
265    
266   add_slider_binding (binding_set, GDK_Page_Up, 0,
267                       GTK_SCROLL_PAGE_LEFT);
268
269   add_slider_binding (binding_set, GDK_KP_Page_Up, 0,
270                       GTK_SCROLL_PAGE_LEFT);  
271
272   add_slider_binding (binding_set, GDK_Page_Up, 0,
273                       GTK_SCROLL_PAGE_UP);
274
275   add_slider_binding (binding_set, GDK_KP_Page_Up, 0,
276                       GTK_SCROLL_PAGE_UP);
277   
278   add_slider_binding (binding_set, GDK_Page_Down, 0,
279                       GTK_SCROLL_PAGE_RIGHT);
280
281   add_slider_binding (binding_set, GDK_KP_Page_Down, 0,
282                       GTK_SCROLL_PAGE_RIGHT);
283
284   add_slider_binding (binding_set, GDK_Page_Down, 0,
285                       GTK_SCROLL_PAGE_DOWN);
286
287   add_slider_binding (binding_set, GDK_KP_Page_Down, 0,
288                       GTK_SCROLL_PAGE_DOWN);
289
290   /* Logical bindings (vs. visual bindings above) */
291
292   add_slider_binding (binding_set, GDK_plus, 0,
293                       GTK_SCROLL_STEP_FORWARD);  
294
295   add_slider_binding (binding_set, GDK_minus, 0,
296                       GTK_SCROLL_STEP_BACKWARD);  
297
298   add_slider_binding (binding_set, GDK_plus, GDK_CONTROL_MASK,
299                       GTK_SCROLL_PAGE_FORWARD);  
300
301   add_slider_binding (binding_set, GDK_minus, GDK_CONTROL_MASK,
302                       GTK_SCROLL_PAGE_BACKWARD);
303
304
305   add_slider_binding (binding_set, GDK_KP_Add, 0,
306                       GTK_SCROLL_STEP_FORWARD);  
307
308   add_slider_binding (binding_set, GDK_KP_Subtract, 0,
309                       GTK_SCROLL_STEP_BACKWARD);  
310
311   add_slider_binding (binding_set, GDK_KP_Add, GDK_CONTROL_MASK,
312                       GTK_SCROLL_PAGE_FORWARD);  
313
314   add_slider_binding (binding_set, GDK_KP_Subtract, GDK_CONTROL_MASK,
315                       GTK_SCROLL_PAGE_BACKWARD);
316   
317   
318   add_slider_binding (binding_set, GDK_Home, 0,
319                       GTK_SCROLL_START);
320
321   add_slider_binding (binding_set, GDK_KP_Home, 0,
322                       GTK_SCROLL_START);
323
324   add_slider_binding (binding_set, GDK_End, 0,
325                       GTK_SCROLL_END);
326
327   add_slider_binding (binding_set, GDK_KP_End, 0,
328                       GTK_SCROLL_END);
329
330   g_type_class_add_private (gobject_class, sizeof (GtkScalePrivate));
331 }
332
333 static void
334 gtk_scale_set_property (GObject      *object,
335                         guint         prop_id,
336                         const GValue *value,
337                         GParamSpec   *pspec)
338 {
339   GtkScale *scale;
340
341   scale = GTK_SCALE (object);
342
343   switch (prop_id)
344     {
345     case PROP_DIGITS:
346       gtk_scale_set_digits (scale, g_value_get_int (value));
347       break;
348     case PROP_DRAW_VALUE:
349       gtk_scale_set_draw_value (scale, g_value_get_boolean (value));
350       break;
351     case PROP_VALUE_POS:
352       gtk_scale_set_value_pos (scale, g_value_get_enum (value));
353       break;
354     default:
355       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
356       break;
357     }
358 }
359
360 static void
361 gtk_scale_get_property (GObject      *object,
362                         guint         prop_id,
363                         GValue       *value,
364                         GParamSpec   *pspec)
365 {
366   GtkScale *scale;
367
368   scale = GTK_SCALE (object);
369
370   switch (prop_id)
371     {
372     case PROP_DIGITS:
373       g_value_set_int (value, scale->digits);
374       break;
375     case PROP_DRAW_VALUE:
376       g_value_set_boolean (value, scale->draw_value);
377       break;
378     case PROP_VALUE_POS:
379       g_value_set_enum (value, scale->value_pos);
380       break;
381     default:
382       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
383       break;
384     }
385 }
386
387 static void
388 gtk_scale_init (GtkScale *scale)
389 {
390   GtkRange *range;
391
392   range = GTK_RANGE (scale);
393   
394   GTK_WIDGET_SET_FLAGS (scale, GTK_CAN_FOCUS);
395
396   range->slider_size_fixed = TRUE;
397   range->has_stepper_a = FALSE;
398   range->has_stepper_b = FALSE;
399   range->has_stepper_c = FALSE;
400   range->has_stepper_d = FALSE;
401   
402   scale->draw_value = TRUE;
403   scale->value_pos = GTK_POS_TOP;
404   scale->digits = 1;
405   range->round_digits = scale->digits;
406 }
407
408 void
409 gtk_scale_set_digits (GtkScale *scale,
410                       gint      digits)
411 {
412   GtkRange *range;
413   
414   g_return_if_fail (GTK_IS_SCALE (scale));
415
416   range = GTK_RANGE (scale);
417   
418   digits = CLAMP (digits, -1, MAX_DIGITS);
419
420   if (scale->digits != digits)
421     {
422       scale->digits = digits;
423       if (scale->draw_value)
424         range->round_digits = digits;
425       
426       _gtk_scale_clear_layout (scale);
427       gtk_widget_queue_resize (GTK_WIDGET (scale));
428
429       g_object_notify (G_OBJECT (scale), "digits");
430     }
431 }
432
433 gint
434 gtk_scale_get_digits (GtkScale *scale)
435 {
436   g_return_val_if_fail (GTK_IS_SCALE (scale), -1);
437
438   return scale->digits;
439 }
440
441 void
442 gtk_scale_set_draw_value (GtkScale *scale,
443                           gboolean  draw_value)
444 {
445   g_return_if_fail (GTK_IS_SCALE (scale));
446
447   draw_value = draw_value != FALSE;
448
449   if (scale->draw_value != draw_value)
450     {
451       scale->draw_value = draw_value;
452       if (draw_value)
453         GTK_RANGE (scale)->round_digits = scale->digits;
454       else
455         GTK_RANGE (scale)->round_digits = -1;
456
457       _gtk_scale_clear_layout (scale);
458
459       gtk_widget_queue_resize (GTK_WIDGET (scale));
460
461       g_object_notify (G_OBJECT (scale), "draw_value");
462     }
463 }
464
465 gboolean
466 gtk_scale_get_draw_value (GtkScale *scale)
467 {
468   g_return_val_if_fail (GTK_IS_SCALE (scale), FALSE);
469
470   return scale->draw_value;
471 }
472
473 void
474 gtk_scale_set_value_pos (GtkScale        *scale,
475                          GtkPositionType  pos)
476 {
477   g_return_if_fail (GTK_IS_SCALE (scale));
478
479   if (scale->value_pos != pos)
480     {
481       scale->value_pos = pos;
482
483       _gtk_scale_clear_layout (scale);
484       if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
485         gtk_widget_queue_resize (GTK_WIDGET (scale));
486
487       g_object_notify (G_OBJECT (scale), "value_pos");
488     }
489 }
490
491 GtkPositionType
492 gtk_scale_get_value_pos (GtkScale *scale)
493 {
494   g_return_val_if_fail (GTK_IS_SCALE (scale), 0);
495
496   return scale->value_pos;
497 }
498
499 static void
500 gtk_scale_get_range_border (GtkRange  *range,
501                             GtkBorder *border)
502 {
503   GtkWidget *widget;
504   GtkScale *scale;
505   gint w, h;
506   
507   widget = GTK_WIDGET (range);
508   scale = GTK_SCALE (range);
509
510   _gtk_scale_get_value_size (scale, &w, &h);
511
512   border->left = 0;
513   border->right = 0;
514   border->top = 0;
515   border->bottom = 0;
516
517   if (scale->draw_value)
518     {
519       gint value_spacing;
520       gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
521
522       switch (scale->value_pos)
523         {
524         case GTK_POS_LEFT:
525           border->left += w + value_spacing;
526           break;
527         case GTK_POS_RIGHT:
528           border->right += w + value_spacing;
529           break;
530         case GTK_POS_TOP:
531           border->top += h + value_spacing;
532           break;
533         case GTK_POS_BOTTOM:
534           border->bottom += h + value_spacing;
535           break;
536         }
537     }
538 }
539
540 /* FIXME this could actually be static at the moment. */
541 void
542 _gtk_scale_get_value_size (GtkScale *scale,
543                            gint     *width,
544                            gint     *height)
545 {
546   GtkRange *range;
547
548   g_return_if_fail (GTK_IS_SCALE (scale));
549
550   if (scale->draw_value)
551     {
552       PangoLayout *layout;
553       PangoRectangle logical_rect;
554       gchar *txt;
555       
556       range = GTK_RANGE (scale);
557
558       layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
559
560       txt = _gtk_scale_format_value (scale, range->adjustment->lower);
561       pango_layout_set_text (layout, txt, -1);
562       g_free (txt);
563       
564       pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
565
566       if (width)
567         *width = logical_rect.width;
568       if (height)
569         *height = logical_rect.height;
570
571       txt = _gtk_scale_format_value (scale, range->adjustment->upper);
572       pango_layout_set_text (layout, txt, -1);
573       g_free (txt);
574       
575       pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
576
577       if (width)
578         *width = MAX (*width, logical_rect.width);
579       if (height)
580         *height = MAX (*height, logical_rect.height);
581
582       g_object_unref (layout);
583     }
584   else
585     {
586       if (width)
587         *width = 0;
588       if (height)
589         *height = 0;
590     }
591
592 }
593
594 static void
595 gtk_scale_style_set (GtkWidget *widget,
596                      GtkStyle  *previous)
597 {
598   gint slider_length;
599   GtkRange *range;
600
601   range = GTK_RANGE (widget);
602   
603   gtk_widget_style_get (widget,
604                         "slider_length", &slider_length,
605                         NULL);
606   
607   range->min_slider_size = slider_length;
608   
609   _gtk_scale_clear_layout (GTK_SCALE (widget));
610
611   (* GTK_WIDGET_CLASS (parent_class)->style_set) (widget, previous);
612 }
613
614 static void
615 gtk_scale_screen_changed (GtkWidget *widget,
616                           GdkScreen *old_screen)
617 {
618   _gtk_scale_clear_layout (GTK_SCALE (widget));
619 }
620
621 /**
622  * _gtk_scale_format_value:
623  * @scale: a #GtkScale
624  * @value: adjustment value
625  * 
626  * Emits "format_value" signal to format the value, if no user
627  * signal handlers, falls back to a default format.
628  * 
629  * Return value: formatted value
630  **/
631 gchar*
632 _gtk_scale_format_value (GtkScale *scale,
633                          gdouble   value)
634 {
635   gchar *fmt = NULL;
636
637   g_signal_emit (scale,
638                  signals[FORMAT_VALUE],
639                  0,
640                  value,
641                  &fmt);
642
643   if (fmt)
644     return fmt;
645   else
646     return g_strdup_printf ("%0.*f", scale->digits,
647                             value);
648 }
649
650 static void
651 gtk_scale_finalize (GObject *object)
652 {
653   GtkScale *scale;
654
655   g_return_if_fail (GTK_IS_SCALE (object));
656
657   scale = GTK_SCALE (object);
658
659   _gtk_scale_clear_layout (scale);
660
661   G_OBJECT_CLASS (parent_class)->finalize (object);
662 }
663
664 /**
665  * gtk_scale_get_layout:
666  * @scale: A #GtkScale
667  *
668  * Gets the #PangoLayout used to display the scale. The returned object
669  * is owned by the scale so does not need to be freed by the caller. 
670  *
671  * Return value: the #PangoLayout for this scale, or %NULL if the draw_value property
672  *    is %FALSE.
673  *   
674  * Since: 2.4
675  **/
676 PangoLayout *
677 gtk_scale_get_layout (GtkScale *scale)
678 {
679   GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale);
680   gchar *txt;
681
682   g_return_val_if_fail (GTK_IS_SCALE (scale), NULL);
683
684   if (!priv->layout)
685     {
686       if (scale->draw_value)
687         priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
688     }
689
690   if (scale->draw_value) 
691     {
692       txt = _gtk_scale_format_value (scale,
693                                      GTK_RANGE (scale)->adjustment->value);
694       pango_layout_set_text (priv->layout, txt, -1);
695       g_free (txt);
696     }
697
698   return priv->layout;
699 }
700
701 /**
702  * gtk_scale_get_layout_offsets:
703  * @scale: a #GtkScale
704  * @x: location to store X offset of layout, or %NULL
705  * @y: location to store Y offset of layout, or %NULL
706  *
707  * Obtains the coordinates where the scale will draw the #PangoLayout
708  * representing the text in the scale. Remember
709  * when using the #PangoLayout function you need to convert to
710  * and from pixels using PANGO_PIXELS() or #PANGO_SCALE. 
711  *
712  * If the draw_value property is %FALSE, the return values are 
713  * undefined.
714  *
715  * Since: 2.4
716  **/
717 void 
718 gtk_scale_get_layout_offsets (GtkScale *scale,
719                               gint     *x,
720                               gint     *y)
721 {
722   gint local_x, local_y;
723
724   g_return_if_fail (GTK_IS_SCALE (scale));
725
726   if (GTK_SCALE_GET_CLASS (scale)->get_layout_offsets)
727     (GTK_SCALE_GET_CLASS (scale)->get_layout_offsets) (scale, &local_x, &local_y);
728
729   if (x)
730     *x = local_x;
731   
732   if (y)
733     *y = local_y;
734 }
735
736 void _gtk_scale_clear_layout (GtkScale *scale)
737 {
738   GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale);
739
740   g_return_if_fail (GTK_IS_SCALE (scale));
741
742   if (priv->layout)
743     {
744       g_object_unref (priv->layout);
745       priv->layout = NULL;
746     }
747 }
748