diff options
author | Michael Natterer <mitch@imendio.com> | 2008-11-11 17:47:13 +0000 |
---|---|---|
committer | Michael Natterer <mitch@src.gnome.org> | 2008-11-11 17:47:13 +0000 |
commit | 0498dca831099c1fac3c0d0a38b0bb08c4bd96de (patch) | |
tree | 684058a5c5624ce509bff9b297d9bd1e6f17206b | |
parent | 4d8f9d2ef380f9158e0611df6f791042d0ebae76 (diff) | |
download | gtk+-0498dca831099c1fac3c0d0a38b0bb08c4bd96de.tar.gz |
Bug 553765 – Add orientation API to GtkRange
2008-11-11 Michael Natterer <mitch@imendio.com>
Bug 553765 – Add orientation API to GtkRange
* gtk/gtkrange.[ch]: implement the GtkOrientable interface. Add
evil code that makes sure that the stepper_detail and slider_detail
set in GtkRangeClass continue to work with the hacked subclasses
below.
* gtk/gtkscale.[ch]: swallow all code from GtkHScale and GtkVScale
and add gtk_scale_new() and gtk_scale_new_with_range() which take
a GtkOrientation argument. Set slider_detail to "Xscale" so above
evil code works.
* gtk/gtkscrollbar.[ch]: add gtk_scrollbar_new() which takes a
GtkOrientation argument. Set stepper_detail to "Xscrollbar" so
above evil code works.
* gtk/gtkhscale.c
* gtk/gtkvscale.c
* gtk/gtkhscrollbar.c
* gtk/gtkvscrollbar.c: remove all code except the constructor and
call gtk_orientable_set_orientation() in init().
* gtk/gtk.symbols: changed accordingly.
svn path=/trunk/; revision=21779
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | gtk/gtkhscale.c | 179 | ||||
-rw-r--r-- | gtk/gtkhscrollbar.c | 25 | ||||
-rw-r--r-- | gtk/gtkrange.c | 97 | ||||
-rw-r--r-- | gtk/gtkrange.h | 1 | ||||
-rw-r--r-- | gtk/gtkscale.c | 306 | ||||
-rw-r--r-- | gtk/gtkscale.h | 55 | ||||
-rw-r--r-- | gtk/gtkscrollbar.c | 28 | ||||
-rw-r--r-- | gtk/gtkscrollbar.h | 5 | ||||
-rw-r--r-- | gtk/gtkvscale.c | 180 | ||||
-rw-r--r-- | gtk/gtkvscrollbar.c | 27 |
11 files changed, 528 insertions, 401 deletions
@@ -1,5 +1,31 @@ 2008-11-11 Michael Natterer <mitch@imendio.com> + Bug 553765 – Add orientation API to GtkRange + + * gtk/gtkrange.[ch]: implement the GtkOrientable interface. Add + evil code that makes sure that the stepper_detail and slider_detail + set in GtkRangeClass continue to work with the hacked subclasses + below. + + * gtk/gtkscale.[ch]: swallow all code from GtkHScale and GtkVScale + and add gtk_scale_new() and gtk_scale_new_with_range() which take + a GtkOrientation argument. Set slider_detail to "Xscale" so above + evil code works. + + * gtk/gtkscrollbar.[ch]: add gtk_scrollbar_new() which takes a + GtkOrientation argument. Set stepper_detail to "Xscrollbar" so + above evil code works. + + * gtk/gtkhscale.c + * gtk/gtkvscale.c + * gtk/gtkhscrollbar.c + * gtk/gtkvscrollbar.c: remove all code except the constructor and + call gtk_orientable_set_orientation() in init(). + + * gtk/gtk.symbols: changed accordingly. + +2008-11-11 Michael Natterer <mitch@imendio.com> + * gtk/gtktoolbar.h: move deprecated functions together, move setters and getters together, some indentation cleanup. diff --git a/gtk/gtkhscale.c b/gtk/gtkhscale.c index 966d2085f1..c641dcbcaf 100644 --- a/gtk/gtkhscale.c +++ b/gtk/gtkhscale.c @@ -21,59 +21,45 @@ * 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/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" + #include <math.h> -#include <stdio.h> #include <stdlib.h> + #include "gtkhscale.h" -#include "gtkintl.h" +#include "gtkorientable.h" #include "gtkalias.h" -static gboolean gtk_hscale_expose (GtkWidget *widget, - GdkEventExpose *event); - -static void gtk_hscale_get_layout_offsets (GtkScale *scale, - gint *x, - gint *y); G_DEFINE_TYPE (GtkHScale, gtk_hscale, GTK_TYPE_SCALE) static void gtk_hscale_class_init (GtkHScaleClass *class) { - GtkWidgetClass *widget_class; - GtkRangeClass *range_class; - GtkScaleClass *scale_class; - - widget_class = GTK_WIDGET_CLASS (class); - range_class = GTK_RANGE_CLASS (class); - scale_class = GTK_SCALE_CLASS (class); + GtkRangeClass *range_class = GTK_RANGE_CLASS (class); range_class->slider_detail = "hscale"; - - scale_class->get_layout_offsets = gtk_hscale_get_layout_offsets; - - widget_class->expose_event = gtk_hscale_expose; } static void gtk_hscale_init (GtkHScale *hscale) { - GtkRange *range; - - range = GTK_RANGE (hscale); - - range->orientation = GTK_ORIENTATION_HORIZONTAL; - range->flippable = TRUE; + gtk_orientable_set_orientation (GTK_ORIENTABLE (hscale), + GTK_ORIENTATION_HORIZONTAL); } -GtkWidget* +GtkWidget * gtk_hscale_new (GtkAdjustment *adjustment) { - return g_object_new (GTK_TYPE_HSCALE, "adjustment", adjustment, NULL); + g_return_val_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment), + NULL); + + return g_object_new (GTK_TYPE_HSCALE, + "adjustment", adjustment, + NULL); } /** @@ -81,19 +67,19 @@ gtk_hscale_new (GtkAdjustment *adjustment) * @min: minimum value * @max: maximum value * @step: step increment (tick size) used with keyboard shortcuts - * + * * Creates a new horizontal scale widget that lets the user input a * number between @min and @max (including @min and @max) with the * increment @step. @step must be nonzero; it's the distance the * slider moves when using the arrow keys to adjust the scale value. - * - * Note that the way in which the precision is derived works best if @step - * is a power of ten. If the resulting precision is not suitable for your + * + * Note that the way in which the precision is derived works best if @step + * is a power of ten. If the resulting precision is not suitable for your * needs, use gtk_scale_set_digits() to correct it. - * + * * Return value: a new #GtkHScale **/ -GtkWidget* +GtkWidget * gtk_hscale_new_with_range (gdouble min, gdouble max, gdouble step) @@ -108,127 +94,22 @@ gtk_hscale_new_with_range (gdouble min, adj = gtk_adjustment_new (min, min, max, step, 10 * step, 0); if (fabs (step) >= 1.0 || step == 0.0) - digits = 0; - else { - digits = abs ((gint) floor (log10 (fabs (step)))); - if (digits > 5) - digits = 5; - } - - scale = g_object_new (GTK_TYPE_HSCALE, - "adjustment", adj, - "digits", digits, - NULL); - - return GTK_WIDGET (scale); -} - -static gboolean -gtk_hscale_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - GtkScale *scale; - - scale = GTK_SCALE (widget); - - /* We need to chain up _first_ so the various geometry members of - * GtkRange struct are updated. - */ - if (GTK_WIDGET_CLASS (gtk_hscale_parent_class)->expose_event) - GTK_WIDGET_CLASS (gtk_hscale_parent_class)->expose_event (widget, event); - - if (scale->draw_value) { - PangoLayout *layout; - gint x, y; - GtkStateType state_type; - - layout = gtk_scale_get_layout (scale); - gtk_scale_get_layout_offsets (scale, &x, &y); - - state_type = GTK_STATE_NORMAL; - if (!GTK_WIDGET_IS_SENSITIVE (scale)) - state_type = GTK_STATE_INSENSITIVE; - - gtk_paint_layout (widget->style, - widget->window, - state_type, - FALSE, - NULL, - widget, - "hscale", - x, y, - layout); - + digits = 0; } - - return FALSE; -} - -static void -gtk_hscale_get_layout_offsets (GtkScale *scale, - gint *x, - gint *y) -{ - GtkWidget *widget; - GtkRange *range; - PangoLayout *layout; - PangoRectangle logical_rect; - gint value_spacing; - - widget = GTK_WIDGET (scale); - layout = gtk_scale_get_layout (scale); - - if (!layout) + else { - *x = 0; - *y = 0; - - return; + digits = abs ((gint) floor (log10 (fabs (step)))); + if (digits > 5) + digits = 5; } - gtk_widget_style_get (widget, "value-spacing", &value_spacing, NULL); - - range = GTK_RANGE (widget); - scale = GTK_SCALE (widget); - - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - - switch (scale->value_pos) - { - case GTK_POS_LEFT: - *x = range->range_rect.x - value_spacing - logical_rect.width; - *y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2; - break; - - case GTK_POS_RIGHT: - *x = range->range_rect.x + range->range_rect.width + value_spacing; - *y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2; - break; - - case GTK_POS_TOP: - *x = range->slider_start + - (range->slider_end - range->slider_start - logical_rect.width) / 2; - *x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width); - *y = range->range_rect.y - logical_rect.height - value_spacing; - break; - - case GTK_POS_BOTTOM: - *x = range->slider_start + - (range->slider_end - range->slider_start - logical_rect.width) / 2; - *x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width); - *y = range->range_rect.y + range->range_rect.height + value_spacing; - break; - - default: - g_return_if_reached (); - *x = 0; - *y = 0; - break; - } + scale = g_object_new (GTK_TYPE_HSCALE, + "adjustment", adj, + "digits", digits, + NULL); - *x += widget->allocation.x; - *y += widget->allocation.y; + return GTK_WIDGET (scale); } #define __GTK_HSCALE_C__ diff --git a/gtk/gtkhscrollbar.c b/gtk/gtkhscrollbar.c index 1ec5c651f9..a5522fb63b 100644 --- a/gtk/gtkhscrollbar.c +++ b/gtk/gtkhscrollbar.c @@ -22,12 +22,13 @@ * 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/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" + #include "gtkhscrollbar.h" -#include "gdk/gdkkeysyms.h" +#include "gtkorientable.h" #include "gtkintl.h" #include "gtkalias.h" @@ -42,23 +43,19 @@ gtk_hscrollbar_class_init (GtkHScrollbarClass *class) static void gtk_hscrollbar_init (GtkHScrollbar *hscrollbar) { - GtkRange *range; - - range = GTK_RANGE (hscrollbar); - - range->orientation = GTK_ORIENTATION_HORIZONTAL; + gtk_orientable_set_orientation (GTK_ORIENTABLE (hscrollbar), + GTK_ORIENTATION_HORIZONTAL); } -GtkWidget* +GtkWidget * gtk_hscrollbar_new (GtkAdjustment *adjustment) { - GtkWidget *hscrollbar; - - hscrollbar = g_object_new (GTK_TYPE_HSCROLLBAR, - "adjustment", adjustment, - NULL); + g_return_val_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment), + NULL); - return hscrollbar; + return g_object_new (GTK_TYPE_HSCROLLBAR, + "adjustment", adjustment, + NULL); } #define __GTK_HSCROLLBAR_C__ diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index 7fa75303a1..e926f70d34 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -26,15 +26,18 @@ */ #include "config.h" + #include <stdio.h> #include <math.h> + #include <gdk/gdkkeysyms.h> -#include "gtkintl.h" #include "gtkmain.h" #include "gtkmarshalers.h" +#include "gtkorientable.h" #include "gtkrange.h" #include "gtkscrollbar.h" #include "gtkprivate.h" +#include "gtkintl.h" #include "gtkalias.h" #define SCROLL_DELAY_FACTOR 5 /* Scroll repeat multiplier */ @@ -42,6 +45,7 @@ enum { PROP_0, + PROP_ORIENTATION, PROP_UPDATE_POLICY, PROP_ADJUSTMENT, PROP_INVERTED, @@ -110,6 +114,9 @@ struct _GtkRangeLayout guint repaint_id; gdouble fill_level; + + GQuark slider_detail_quark; + GQuark stepper_detail_quark; }; @@ -208,9 +215,12 @@ static gboolean gtk_range_key_press (GtkWidget *range, GdkEventKey *event); +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkRange, gtk_range, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, + NULL)) + static guint signals[LAST_SIGNAL]; -G_DEFINE_ABSTRACT_TYPE (GtkRange, gtk_range, GTK_TYPE_WIDGET) static void gtk_range_class_init (GtkRangeClass *class) @@ -225,6 +235,7 @@ gtk_range_class_init (GtkRangeClass *class) gobject_class->set_property = gtk_range_set_property; gobject_class->get_property = gtk_range_get_property; + object_class->destroy = gtk_range_destroy; widget_class->size_request = gtk_range_size_request; @@ -331,6 +342,10 @@ gtk_range_class_init (GtkRangeClass *class) GTK_TYPE_SCROLL_TYPE, G_TYPE_DOUBLE); + g_object_class_override_property (gobject_class, + PROP_ORIENTATION, + "orientation"); + g_object_class_install_property (gobject_class, PROP_UPDATE_POLICY, g_param_spec_enum ("update-policy", @@ -545,12 +560,18 @@ gtk_range_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - GtkRange *range; - - range = GTK_RANGE (object); + GtkRange *range = GTK_RANGE (object); switch (prop_id) { + case PROP_ORIENTATION: + range->orientation = g_value_get_enum (value); + + range->layout->slider_detail_quark = 0; + range->layout->stepper_detail_quark = 0; + + gtk_widget_queue_resize (GTK_WIDGET (range)); + break; case PROP_UPDATE_POLICY: gtk_range_set_update_policy (range, g_value_get_enum (value)); break; @@ -587,12 +608,13 @@ gtk_range_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - GtkRange *range; - - range = GTK_RANGE (object); + GtkRange *range = GTK_RANGE (object); switch (prop_id) { + case PROP_ORIENTATION: + g_value_set_enum (value, range->orientation); + break; case PROP_UPDATE_POLICY: g_value_set_enum (value, range->update_policy); break; @@ -628,6 +650,7 @@ gtk_range_init (GtkRange *range) { GTK_WIDGET_SET_FLAGS (range, GTK_NO_WINDOW); + range->orientation = GTK_ORIENTATION_HORIZONTAL; range->adjustment = NULL; range->update_policy = GTK_UPDATE_CONTINUOUS; range->inverted = FALSE; @@ -1319,6 +1342,58 @@ gtk_range_unmap (GtkWidget *widget) GTK_WIDGET_CLASS (gtk_range_parent_class)->unmap (widget); } +static const gchar * +gtk_range_get_slider_detail (GtkRange *range) +{ + const gchar *slider_detail; + + if (range->layout->slider_detail_quark) + return g_quark_to_string (range->layout->slider_detail_quark); + + slider_detail = GTK_RANGE_GET_CLASS (range)->slider_detail; + + if (slider_detail && slider_detail[0] == 'X') + { + gchar *detail = g_strdup (slider_detail); + + detail[0] = range->orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; + + range->layout->slider_detail_quark = g_quark_from_string (detail); + + g_free (detail); + + return g_quark_to_string (range->layout->slider_detail_quark); + } + + return slider_detail; +} + +static const gchar * +gtk_range_get_stepper_detail (GtkRange *range) +{ + const gchar *stepper_detail; + + if (range->layout->stepper_detail_quark) + return g_quark_to_string (range->layout->stepper_detail_quark); + + stepper_detail = GTK_RANGE_GET_CLASS (range)->stepper_detail; + + if (stepper_detail && stepper_detail[0] == 'X') + { + gchar *detail = g_strdup (stepper_detail); + + detail[0] = range->orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; + + range->layout->stepper_detail_quark = g_quark_from_string (detail); + + g_free (detail); + + return g_quark_to_string (range->layout->stepper_detail_quark); + } + + return stepper_detail; +} + static void draw_stepper (GtkRange *range, GdkRectangle *rect, @@ -1377,7 +1452,7 @@ draw_stepper (GtkRange *range, widget->window, state_type, shadow_type, &intersection, widget, - GTK_RANGE_GET_CLASS (range)->stepper_detail, + gtk_range_get_stepper_detail (range), widget->allocation.x + rect->x, widget->allocation.y + rect->y, rect->width, @@ -1407,7 +1482,7 @@ draw_stepper (GtkRange *range, widget->window, state_type, shadow_type, &intersection, widget, - GTK_RANGE_GET_CLASS (range)->stepper_detail, + gtk_range_get_stepper_detail (range), arrow_type, TRUE, arrow_x, arrow_y, arrow_width, arrow_height); @@ -1679,7 +1754,7 @@ gtk_range_expose (GtkWidget *widget, shadow_type, &area, widget, - GTK_RANGE_GET_CLASS (range)->slider_detail, + gtk_range_get_slider_detail (range), widget->allocation.x + range->layout->slider.x, widget->allocation.y + range->layout->slider.y, range->layout->slider.width, diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h index 7c6b46d011..08860f8121 100644 --- a/gtk/gtkrange.h +++ b/gtk/gtkrange.h @@ -174,6 +174,7 @@ void gtk_range_set_fill_level (GtkRange *range gdouble fill_level); gdouble gtk_range_get_fill_level (GtkRange *range); +/* internal API */ gdouble _gtk_range_get_wheel_delta (GtkRange *range, GdkScrollDirection direction); diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index 9535823c90..929bb64529 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -22,17 +22,20 @@ * 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/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" + #include <math.h> -#include "gtkintl.h" +#include <stdlib.h> + +#include "gdk/gdkkeysyms.h" #include "gtkscale.h" #include "gtkmarshalers.h" -#include "gdk/gdkkeysyms.h" #include "gtkbindings.h" #include "gtkprivate.h" +#include "gtkintl.h" #include "gtkalias.h" @@ -65,23 +68,28 @@ enum { static guint signals[LAST_SIGNAL]; -static void gtk_scale_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_scale_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_scale_style_set (GtkWidget *widget, - GtkStyle *previous); -static void gtk_scale_get_range_border (GtkRange *range, - GtkBorder *border); -static void gtk_scale_finalize (GObject *object); -static void gtk_scale_screen_changed (GtkWidget *widget, - GdkScreen *old_screen); - -G_DEFINE_ABSTRACT_TYPE (GtkScale, gtk_scale, GTK_TYPE_RANGE) +static void gtk_scale_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_scale_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gtk_scale_style_set (GtkWidget *widget, + GtkStyle *previous); +static void gtk_scale_get_range_border (GtkRange *range, + GtkBorder *border); +static void gtk_scale_finalize (GObject *object); +static void gtk_scale_screen_changed (GtkWidget *widget, + GdkScreen *old_screen); +static gboolean gtk_scale_expose (GtkWidget *widget, + GdkEventExpose *event); +static void gtk_scale_real_get_layout_offsets (GtkScale *scale, + gint *x, + gint *y); + +G_DEFINE_TYPE (GtkScale, gtk_scale, GTK_TYPE_RANGE) static gboolean single_string_accumulator (GSignalInvocationHint *ihint, @@ -123,9 +131,13 @@ gtk_scale_class_init (GtkScaleClass *class) widget_class->style_set = gtk_scale_style_set; widget_class->screen_changed = gtk_scale_screen_changed; + widget_class->expose_event = gtk_scale_expose; + range_class->slider_detail = "Xscale"; range_class->get_range_border = gtk_scale_get_range_border; - + + class->get_layout_offsets = gtk_scale_real_get_layout_offsets; + signals[FORMAT_VALUE] = g_signal_new (I_("format-value"), G_TYPE_FROM_CLASS (gobject_class), @@ -303,6 +315,37 @@ gtk_scale_class_init (GtkScaleClass *class) } static void +gtk_scale_orientation_notify (GtkRange *range, + const GParamSpec *pspec) +{ + range->flippable = (range->orientation == GTK_ORIENTATION_HORIZONTAL); +} + +static void +gtk_scale_init (GtkScale *scale) +{ + GtkRange *range = GTK_RANGE (scale); + + GTK_WIDGET_SET_FLAGS (scale, GTK_CAN_FOCUS); + + range->slider_size_fixed = TRUE; + range->has_stepper_a = FALSE; + range->has_stepper_b = FALSE; + range->has_stepper_c = FALSE; + range->has_stepper_d = FALSE; + + scale->draw_value = TRUE; + scale->value_pos = GTK_POS_TOP; + scale->digits = 1; + range->round_digits = scale->digits; + + gtk_scale_orientation_notify (range, NULL); + g_signal_connect (scale, "notify::orientation", + G_CALLBACK (gtk_scale_orientation_notify), + NULL); +} + +static void gtk_scale_set_property (GObject *object, guint prop_id, const GValue *value, @@ -356,25 +399,82 @@ gtk_scale_get_property (GObject *object, } } -static void -gtk_scale_init (GtkScale *scale) +/** + * gtk_scale_new: + * @orientation: the scale's orientation. + * @adjustment: the #GtkAdjustment which sets the range of the scale, or + * %NULL to create a new adjustment. + * + * Creates a new #GtkScale. + * + * Return value: a new #GtkScale + * + * Since: 2.16 + **/ +GtkWidget * +gtk_scale_new (GtkOrientation orientation, + GtkAdjustment *adjustment) { - GtkRange *range; + g_return_val_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment), + NULL); - range = GTK_RANGE (scale); - - GTK_WIDGET_SET_FLAGS (scale, GTK_CAN_FOCUS); + return g_object_new (GTK_TYPE_SCALE, + "orientation", orientation, + "adjustment", adjustment, + NULL); +} - range->slider_size_fixed = TRUE; - range->has_stepper_a = FALSE; - range->has_stepper_b = FALSE; - range->has_stepper_c = FALSE; - range->has_stepper_d = FALSE; - - scale->draw_value = TRUE; - scale->value_pos = GTK_POS_TOP; - scale->digits = 1; - range->round_digits = scale->digits; +/** + * gtk_scale_new_with_range: + * @orientation: the scale's orientation. + * @min: minimum value + * @max: maximum value + * @step: step increment (tick size) used with keyboard shortcuts + * + * Creates a new scale widget with the given orientation that lets the + * user input a number between @min and @max (including @min and @max) + * with the increment @step. @step must be nonzero; it's the distance + * the slider moves when using the arrow keys to adjust the scale + * value. + * + * Note that the way in which the precision is derived works best if @step + * is a power of ten. If the resulting precision is not suitable for your + * needs, use gtk_scale_set_digits() to correct it. + * + * Return value: a new #GtkScale + * + * Since: 2.16 + **/ +GtkWidget * +gtk_scale_new_with_range (GtkOrientation orientation, + gdouble min, + gdouble max, + gdouble step) +{ + GtkObject *adj; + gint digits; + + g_return_val_if_fail (min < max, NULL); + g_return_val_if_fail (step != 0.0, NULL); + + adj = gtk_adjustment_new (min, min, max, step, 10 * step, 0); + + if (fabs (step) >= 1.0 || step == 0.0) + { + digits = 0; + } + else + { + digits = abs ((gint) floor (log10 (fabs (step)))); + if (digits > 5) + digits = 5; + } + + return g_object_new (GTK_TYPE_SCALE, + "orientation", orientation, + "adjustment", adj, + "digits", digits, + NULL); } void @@ -590,6 +690,138 @@ gtk_scale_screen_changed (GtkWidget *widget, _gtk_scale_clear_layout (GTK_SCALE (widget)); } +static gboolean +gtk_scale_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GtkScale *scale = GTK_SCALE (widget); + + /* We need to chain up _first_ so the various geometry members of + * GtkRange struct are updated. + */ + GTK_WIDGET_CLASS (gtk_scale_parent_class)->expose_event (widget, event); + + if (scale->draw_value) + { + GtkRange *range = GTK_RANGE (scale); + PangoLayout *layout; + gint x, y; + GtkStateType state_type; + + layout = gtk_scale_get_layout (scale); + gtk_scale_get_layout_offsets (scale, &x, &y); + + state_type = GTK_STATE_NORMAL; + if (!GTK_WIDGET_IS_SENSITIVE (scale)) + state_type = GTK_STATE_INSENSITIVE; + + gtk_paint_layout (widget->style, + widget->window, + state_type, + FALSE, + NULL, + widget, + range->orientation == GTK_ORIENTATION_HORIZONTAL ? + "hscale" : "vscale", + x, y, + layout); + + } + + return FALSE; +} + +static void +gtk_scale_real_get_layout_offsets (GtkScale *scale, + gint *x, + gint *y) +{ + GtkWidget *widget = GTK_WIDGET (scale); + GtkRange *range = GTK_RANGE (widget); + PangoLayout *layout = gtk_scale_get_layout (scale); + PangoRectangle logical_rect; + gint value_spacing; + + if (!layout) + { + *x = 0; + *y = 0; + + return; + } + + gtk_widget_style_get (widget, "value-spacing", &value_spacing, NULL); + + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + if (range->orientation == GTK_ORIENTATION_HORIZONTAL) + { + switch (scale->value_pos) + { + case GTK_POS_LEFT: + *x = range->range_rect.x - value_spacing - logical_rect.width; + *y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2; + break; + + case GTK_POS_RIGHT: + *x = range->range_rect.x + range->range_rect.width + value_spacing; + *y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2; + break; + + case GTK_POS_TOP: + *x = range->slider_start + + (range->slider_end - range->slider_start - logical_rect.width) / 2; + *x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width); + *y = range->range_rect.y - logical_rect.height - value_spacing; + break; + + case GTK_POS_BOTTOM: + *x = range->slider_start + + (range->slider_end - range->slider_start - logical_rect.width) / 2; + *x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width); + *y = range->range_rect.y + range->range_rect.height + value_spacing; + break; + + default: + g_return_if_reached (); + break; + } + } + else + { + switch (scale->value_pos) + { + case GTK_POS_LEFT: + *x = range->range_rect.x - logical_rect.width - value_spacing; + *y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2; + *y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height); + break; + + case GTK_POS_RIGHT: + *x = range->range_rect.x + range->range_rect.width + value_spacing; + *y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2; + *y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height); + break; + + case GTK_POS_TOP: + *x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2; + *y = range->range_rect.y - logical_rect.height - value_spacing; + break; + + case GTK_POS_BOTTOM: + *x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2; + *y = range->range_rect.y + range->range_rect.height + value_spacing; + break; + + default: + g_return_if_reached (); + } + } + + *x += widget->allocation.x; + *y += widget->allocation.y; +} + /** * _gtk_scale_format_value: * @scale: a #GtkScale diff --git a/gtk/gtkscale.h b/gtk/gtkscale.h index 3a86ee1ac6..b8587d2821 100644 --- a/gtk/gtkscale.h +++ b/gtk/gtkscale.h @@ -69,36 +69,43 @@ struct _GtkScaleClass void (* get_layout_offsets) (GtkScale *scale, gint *x, gint *y); + /* Padding for future expansion */ void (*_gtk_reserved2) (void); void (*_gtk_reserved3) (void); void (*_gtk_reserved4) (void); }; -GType gtk_scale_get_type (void) G_GNUC_CONST; - -void gtk_scale_set_digits (GtkScale *scale, - gint digits); -gint gtk_scale_get_digits (GtkScale *scale); -void gtk_scale_set_draw_value (GtkScale *scale, - gboolean draw_value); -gboolean gtk_scale_get_draw_value (GtkScale *scale); -void gtk_scale_set_value_pos (GtkScale *scale, - GtkPositionType pos); -GtkPositionType gtk_scale_get_value_pos (GtkScale *scale); - -PangoLayout *gtk_scale_get_layout (GtkScale *scale); -void gtk_scale_get_layout_offsets (GtkScale *scale, - gint *x, - gint *y); -void _gtk_scale_clear_layout (GtkScale *scale); - -void _gtk_scale_get_value_size (GtkScale *scale, - gint *width, - gint *height); -gchar *_gtk_scale_format_value (GtkScale *scale, - gdouble value); - +GType gtk_scale_get_type (void) G_GNUC_CONST; +GtkWidget * gtk_scale_new (GtkOrientation orientation, + GtkAdjustment *adjustment); +GtkWidget * gtk_scale_new_with_range (GtkOrientation orientation, + gdouble min, + gdouble max, + gdouble step); + +void gtk_scale_set_digits (GtkScale *scale, + gint digits); +gint gtk_scale_get_digits (GtkScale *scale); +void gtk_scale_set_draw_value (GtkScale *scale, + gboolean draw_value); +gboolean gtk_scale_get_draw_value (GtkScale *scale); +void gtk_scale_set_value_pos (GtkScale *scale, + GtkPositionType pos); +GtkPositionType gtk_scale_get_value_pos (GtkScale *scale); + +PangoLayout * gtk_scale_get_layout (GtkScale *scale); +void gtk_scale_get_layout_offsets (GtkScale *scale, + gint *x, + gint *y); + +/* internal API */ +void _gtk_scale_clear_layout (GtkScale *scale); +void _gtk_scale_get_value_size (GtkScale *scale, + gint *width, + gint *height); +gchar * _gtk_scale_format_value (GtkScale *scale, + gdouble value); G_END_DECLS diff --git a/gtk/gtkscrollbar.c b/gtk/gtkscrollbar.c index cd81b8ba10..4c69983817 100644 --- a/gtk/gtkscrollbar.c +++ b/gtk/gtkscrollbar.c @@ -35,7 +35,7 @@ static void gtk_scrollbar_style_set (GtkWidget *widget, GtkStyle *previous); -G_DEFINE_ABSTRACT_TYPE (GtkScrollbar, gtk_scrollbar, GTK_TYPE_RANGE) +G_DEFINE_TYPE (GtkScrollbar, gtk_scrollbar, GTK_TYPE_RANGE) static void gtk_scrollbar_class_init (GtkScrollbarClass *class) @@ -44,6 +44,8 @@ gtk_scrollbar_class_init (GtkScrollbarClass *class) widget_class->style_set = gtk_scrollbar_style_set; + GTK_RANGE_CLASS (class)->stepper_detail = "Xscrollbar"; + gtk_widget_class_install_style_property (widget_class, g_param_spec_int ("min-slider-length", P_("Minimum Slider Length"), @@ -123,5 +125,29 @@ gtk_scrollbar_style_set (GtkWidget *widget, GTK_WIDGET_CLASS (gtk_scrollbar_parent_class)->style_set (widget, previous); } +/** + * gtk_scrollbar_new: + * @orientation: the scrollbar's orientation. + * @adjustment: the #GtkAdjustment to use, or %NULL to create a new adjustment. + * + * Creates a new scrollbar with the given orientation. + * + * Return value: the new #GtkScrollbar. + * + * Since: 2.16 + **/ +GtkWidget * +gtk_scrollbar_new (GtkOrientation orientation, + GtkAdjustment *adjustment) +{ + g_return_val_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment), + NULL); + + return g_object_new (GTK_TYPE_SCROLLBAR, + "orientation", orientation, + "adjustment", adjustment, + NULL); +} + #define __GTK_SCROLLBAR_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkscrollbar.h b/gtk/gtkscrollbar.h index b1d182e6a3..2cca80a0cd 100644 --- a/gtk/gtkscrollbar.h +++ b/gtk/gtkscrollbar.h @@ -65,8 +65,9 @@ struct _GtkScrollbarClass }; -GType gtk_scrollbar_get_type (void) G_GNUC_CONST; - +GType gtk_scrollbar_get_type (void) G_GNUC_CONST; +GtkWidget * gtk_scrollbar_new (GtkOrientation orientation, + GtkAdjustment *adjustment); G_END_DECLS diff --git a/gtk/gtkvscale.c b/gtk/gtkvscale.c index 3961ee074c..20d39bcb3b 100644 --- a/gtk/gtkvscale.c +++ b/gtk/gtkvscale.c @@ -21,81 +21,65 @@ * 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/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" + #include <math.h> -#include <stdio.h> #include <stdlib.h> + #include "gtkvscale.h" -#include "gtkintl.h" +#include "gtkorientable.h" #include "gtkalias.h" -#define VALUE_SPACING 2 - -static gboolean gtk_vscale_expose (GtkWidget *widget, - GdkEventExpose *event); - -static void gtk_vscale_get_layout_offsets (GtkScale *scale, - gint *x, - gint *y); G_DEFINE_TYPE (GtkVScale, gtk_vscale, GTK_TYPE_SCALE) static void gtk_vscale_class_init (GtkVScaleClass *class) { - GtkWidgetClass *widget_class; - GtkRangeClass *range_class; - GtkScaleClass *scale_class; - - widget_class = GTK_WIDGET_CLASS (class); - range_class = GTK_RANGE_CLASS (class); - scale_class = GTK_SCALE_CLASS (class); + GtkRangeClass *range_class = GTK_RANGE_CLASS (class); range_class->slider_detail = "vscale"; - - scale_class->get_layout_offsets = gtk_vscale_get_layout_offsets; - - widget_class->expose_event = gtk_vscale_expose; } static void gtk_vscale_init (GtkVScale *vscale) { - GtkRange *range; - - range = GTK_RANGE (vscale); - - range->orientation = GTK_ORIENTATION_VERTICAL; + gtk_orientable_set_orientation (GTK_ORIENTABLE (vscale), + GTK_ORIENTATION_VERTICAL); } -GtkWidget* +GtkWidget * gtk_vscale_new (GtkAdjustment *adjustment) { - return g_object_new (GTK_TYPE_VSCALE, "adjustment", adjustment, NULL); -} + g_return_val_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment), + NULL); + return g_object_new (GTK_TYPE_VSCALE, + "adjustment", adjustment, + NULL); +} /** * gtk_vscale_new_with_range: * @min: minimum value * @max: maximum value * @step: step increment (tick size) used with keyboard shortcuts - * + * * Creates a new vertical scale widget that lets the user input a * number between @min and @max (including @min and @max) with the * increment @step. @step must be nonzero; it's the distance the * slider moves when using the arrow keys to adjust the scale value. - * - * Note that the way in which the precision is derived works best if @step - * is a power of ten. If the resulting precision is not suitable for your - * needs, use gtk_scale_set_digits() to correct it. - * + * + * Note that the way in which the precision is derived works best if @step + * is a power of ten. If the resulting precision is not suitable for your + * needs, use gtk_scale_set_digits() to correct it. + * * Return value: a new #GtkVScale **/ -GtkWidget* +GtkWidget * gtk_vscale_new_with_range (gdouble min, gdouble max, gdouble step) @@ -108,124 +92,24 @@ gtk_vscale_new_with_range (gdouble min, g_return_val_if_fail (step != 0.0, NULL); adj = gtk_adjustment_new (min, min, max, step, 10 * step, 0); - - if (fabs (step) >= 1.0 || step == 0.0) - digits = 0; - else { - digits = abs ((gint) floor (log10 (fabs (step)))); - if (digits > 5) - digits = 5; - } - scale = g_object_new (GTK_TYPE_VSCALE, - "adjustment", adj, - "digits", digits, - NULL); - - return GTK_WIDGET (scale); -} - -static gboolean -gtk_vscale_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - GtkScale *scale; - - scale = GTK_SCALE (widget); - - /* We need to chain up _first_ so the various geometry members of - * GtkRange struct are updated. - */ - if (GTK_WIDGET_CLASS (gtk_vscale_parent_class)->expose_event) - GTK_WIDGET_CLASS (gtk_vscale_parent_class)->expose_event (widget, event); - - if (scale->draw_value) + if (fabs (step) >= 1.0 || step == 0.0) { - PangoLayout *layout; - gint x, y; - GtkStateType state_type; - - layout = gtk_scale_get_layout (scale); - gtk_scale_get_layout_offsets (scale, &x, &y); - - state_type = GTK_STATE_NORMAL; - if (!GTK_WIDGET_IS_SENSITIVE (scale)) - state_type = GTK_STATE_INSENSITIVE; - - gtk_paint_layout (widget->style, - widget->window, - state_type, - FALSE, - NULL, - widget, - "vscale", - x, y, - layout); + digits = 0; } - - return FALSE; - -} - -static void -gtk_vscale_get_layout_offsets (GtkScale *scale, - gint *x, - gint *y) -{ - GtkWidget *widget; - GtkRange *range; - PangoLayout *layout; - PangoRectangle logical_rect; - gint value_spacing; - - widget = GTK_WIDGET (scale); - layout = gtk_scale_get_layout (scale); - - if (!layout) + else { - *x = 0; - *y = 0; - - return; + digits = abs ((gint) floor (log10 (fabs (step)))); + if (digits > 5) + digits = 5; } - range = GTK_RANGE (widget); - scale = GTK_SCALE (widget); - - gtk_widget_style_get (widget, "value-spacing", &value_spacing, NULL); - - pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - - switch (scale->value_pos) - { - case GTK_POS_LEFT: - *x = range->range_rect.x - logical_rect.width - value_spacing; - *y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2; - *y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height); - break; - - case GTK_POS_RIGHT: - *x = range->range_rect.x + range->range_rect.width + value_spacing; - *y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2; - *y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height); - break; - - case GTK_POS_TOP: - *x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2; - *y = range->range_rect.y - logical_rect.height - value_spacing; - break; - - case GTK_POS_BOTTOM: - *x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2; - *y = range->range_rect.y + range->range_rect.height + value_spacing; - break; - - default: - g_return_if_reached (); - } + scale = g_object_new (GTK_TYPE_VSCALE, + "adjustment", adj, + "digits", digits, + NULL); - *x += widget->allocation.x; - *y += widget->allocation.y; + return GTK_WIDGET (scale); } #define __GTK_VSCALE_C__ diff --git a/gtk/gtkvscrollbar.c b/gtk/gtkvscrollbar.c index fb6903858f..8b29dd37e4 100644 --- a/gtk/gtkvscrollbar.c +++ b/gtk/gtkvscrollbar.c @@ -22,12 +22,13 @@ * 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/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" + +#include "gtkorientable.h" #include "gtkvscrollbar.h" -#include "gdk/gdkkeysyms.h" #include "gtkintl.h" #include "gtkalias.h" @@ -42,23 +43,19 @@ gtk_vscrollbar_class_init (GtkVScrollbarClass *class) static void gtk_vscrollbar_init (GtkVScrollbar *vscrollbar) { - GtkRange *range; - - range = GTK_RANGE (vscrollbar); - - range->orientation = GTK_ORIENTATION_VERTICAL; + gtk_orientable_set_orientation (GTK_ORIENTABLE (vscrollbar), + GTK_ORIENTATION_VERTICAL); } -GtkWidget* +GtkWidget * gtk_vscrollbar_new (GtkAdjustment *adjustment) { - GtkWidget *vscrollbar; - - vscrollbar = g_object_new (GTK_TYPE_VSCROLLBAR, - "adjustment", adjustment, - NULL); - - return vscrollbar; + g_return_val_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment), + NULL); + + return g_object_new (GTK_TYPE_VSCROLLBAR, + "adjustment", adjustment, + NULL); } #define __GTK_VSCROLLBAR_C__ |