diff options
author | Havoc Pennington <hp@pobox.com> | 2001-06-04 02:31:12 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-06-04 02:31:12 +0000 |
commit | 42f429be76e96f1861a17da2cd5ef56741172e25 (patch) | |
tree | 3ca33e80692cfb0f73e4621113bce3dbcb0546a9 /gtk/gtkhscale.c | |
parent | 741c71eb931cb85651e9f5aba99db4017dda180a (diff) | |
download | gdk-pixbuf-42f429be76e96f1861a17da2cd5ef56741172e25.tar.gz |
make this special-case hscale/vscale details, so we can use it for
2001-06-03 Havoc Pennington <hp@pobox.com>
* gtk/gtkstyle.c (gtk_default_draw_slider): make this special-case
hscale/vscale details, so we can use it for scrollbar as well.
* tests/testgtk.c (reformat_value): honor digits from GtkScale
* gtk/gtkenums.h (GtkTroughType): Remove this enum
(GtkScrollType): add START and END from GtkTroughType
* gtk/gtkstyle.c (gtk_default_draw_slider): was not properly using
its x/y arguments
* gtk/gtkrange.h, gtk/gtkrange.c, gtk/gtkscrollbar.h,
gtk/gtkscrollbar.c, gtk/gtkscale.h, gtk/gtkscale.c,
gtk/gtkhscrollbar.h, gtk/gtkhscrollbar.c, gtk/gtkvscrollbar.h,
gtk/gtkvscrollbar.c, gtk/gtkhscale.h, gtk/gtkhscale.c,
gtk/gtkvscale.h, gtk/gtkvscale.c: Rewrite GtkRange and subclasses.
Notable changes in the process:
- stepper_size style property is the height for vertical
ranges, width for horizontal; the other dimension matches
the trough size
- add ability to do NeXT-style steppers (and several other styles
that don't make any sense)
- added min_slider_length, fixed_slider_length properties to
GtkScrollbar
- cleaned some private (or at least useless) functions out of
gtkscale.h
- moved bindings to GtkScale from subclasses, even arrow keys,
since blind users don't know scale orientation.
- change move_slider action signal to use new GtkScrollType,
remove GtkTroughType argument
- digits rounds the values a range will input to the given
number of decimals, but will not try to force adjustment
values set by other controllers. That is, we no longer
modify adjustment->value inside a value_changed handler.
- added getters for GtkScale setters
- middle-click begins a slider drag
Diffstat (limited to 'gtk/gtkhscale.c')
-rw-r--r-- | gtk/gtkhscale.c | 506 |
1 files changed, 52 insertions, 454 deletions
diff --git a/gtk/gtkhscale.c b/gtk/gtkhscale.c index a59efe889..4b6e34a4c 100644 --- a/gtk/gtkhscale.c +++ b/gtk/gtkhscale.c @@ -1,5 +1,5 @@ /* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * Copyright (C) 2001 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,47 +27,14 @@ #include <stdio.h> #include "gtkhscale.h" #include "gtksignal.h" -#include "gdk/gdkkeysyms.h" #include "gtkintl.h" -#include "gtkbindings.h" -#define SCALE_CLASS(w) GTK_SCALE_GET_CLASS (w) -#define RANGE_CLASS(w) GTK_RANGE_GET_CLASS (w) - -enum { - PROP_0 -}; +static gpointer parent_class; static void gtk_hscale_class_init (GtkHScaleClass *klass); static void gtk_hscale_init (GtkHScale *hscale); -static void gtk_hscale_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_hscale_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_hscale_realize (GtkWidget *widget); -static void gtk_hscale_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void gtk_hscale_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void gtk_hscale_pos_trough (GtkHScale *hscale, - gint *x, - gint *y, - gint *w, - gint *h); -static void gtk_hscale_pos_background (GtkHScale *hscale, - gint *x, - gint *y, - gint *w, - gint *h); -static void gtk_hscale_draw_slider (GtkRange *range); -static void gtk_hscale_draw_value (GtkScale *scale); - -static void gtk_hscale_clear_background (GtkRange *range); - +static gboolean gtk_hscale_expose (GtkWidget *widget, + GdkEventExpose *event); GtkType gtk_hscale_get_type (void) @@ -94,124 +61,33 @@ gtk_hscale_get_type (void) return hscale_type; } -#define add_slider_binding(binding_set, keyval, mask, scroll, trough) \ - gtk_binding_entry_add_signal (binding_set, keyval, mask, \ - "move_slider", 2, \ - GTK_TYPE_SCROLL_TYPE, scroll, \ - GTK_TYPE_TROUGH_TYPE, trough) - static void gtk_hscale_class_init (GtkHScaleClass *class) { GObjectClass *gobject_class; - GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkRangeClass *range_class; - GtkScaleClass *scale_class; - GtkBindingSet *binding_set; - - gobject_class = (GObjectClass*) class; - object_class = (GtkObjectClass*) class; - widget_class = (GtkWidgetClass*) class; - range_class = (GtkRangeClass*) class; - scale_class = (GtkScaleClass*) class; - - gobject_class->set_property = gtk_hscale_set_property; - gobject_class->get_property = gtk_hscale_get_property; - - widget_class->realize = gtk_hscale_realize; - widget_class->size_request = gtk_hscale_size_request; - widget_class->size_allocate = gtk_hscale_size_allocate; - - range_class->slider_update = _gtk_range_default_hslider_update; - range_class->trough_click = _gtk_range_default_htrough_click; - range_class->motion = _gtk_range_default_hmotion; - range_class->draw_slider = gtk_hscale_draw_slider; - range_class->clear_background = gtk_hscale_clear_background; - scale_class->draw_value = gtk_hscale_draw_value; - - binding_set = gtk_binding_set_by_class (object_class); - - add_slider_binding (binding_set, GDK_Left, 0, - GTK_SCROLL_STEP_LEFT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_Left, GDK_CONTROL_MASK, - GTK_SCROLL_PAGE_LEFT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_KP_Left, 0, - GTK_SCROLL_STEP_LEFT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK, - GTK_SCROLL_PAGE_LEFT, GTK_TROUGH_NONE); - - - add_slider_binding (binding_set, GDK_Right, 0, - GTK_SCROLL_STEP_RIGHT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_Right, GDK_CONTROL_MASK, - GTK_SCROLL_PAGE_RIGHT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_KP_Right, 0, - GTK_SCROLL_STEP_RIGHT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK, - GTK_SCROLL_PAGE_RIGHT, GTK_TROUGH_NONE); - - add_slider_binding (binding_set, GDK_Home, 0, - GTK_SCROLL_NONE, GTK_TROUGH_START); - - add_slider_binding (binding_set, GDK_KP_Home, 0, - GTK_SCROLL_NONE, GTK_TROUGH_START); - + gobject_class = G_OBJECT_CLASS (class); + widget_class = GTK_WIDGET_CLASS (class); + range_class = GTK_RANGE_CLASS (class); - add_slider_binding (binding_set, GDK_End, 0, - GTK_SCROLL_NONE, GTK_TROUGH_END); + parent_class = g_type_class_peek_parent (class); - add_slider_binding (binding_set, GDK_KP_End, 0, - GTK_SCROLL_NONE, GTK_TROUGH_END); -} - -static void -gtk_hscale_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkHScale *hscale; - - hscale = GTK_HSCALE (object); - - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_hscale_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkHScale *hscale; - - hscale = GTK_HSCALE (object); + range_class->slider_detail = "hscale"; - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + widget_class->expose_event = gtk_hscale_expose; } static void gtk_hscale_init (GtkHScale *hscale) { - GTK_WIDGET_SET_FLAGS (hscale, GTK_NO_WINDOW); + GtkRange *range; + + range = GTK_RANGE (hscale); + + range->orientation = GTK_ORIENTATION_HORIZONTAL; + range->flippable = TRUE; } GtkWidget* @@ -223,305 +99,32 @@ gtk_hscale_new (GtkAdjustment *adjustment) "adjustment", adjustment, NULL); - GTK_RANGE (hscale) -> flippable = 1; - return hscale; } - -static void -gtk_hscale_realize (GtkWidget *widget) -{ - GtkRange *range; - GdkWindowAttr attributes; - gint attributes_mask; - gint x, y, w, h; - gint slider_width, slider_length; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_HSCALE (widget)); - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - range = GTK_RANGE (widget); - - _gtk_range_get_props (range, &slider_width, NULL, NULL, NULL); - gtk_widget_style_get (widget, "slider_length", &slider_length, NULL); - - widget->window = gtk_widget_get_parent_window (widget); - gdk_window_ref (widget->window); - - gtk_hscale_pos_trough (GTK_HSCALE (widget), &x, &y, &w, &h); - - attributes.x = x; - attributes.y = y; - attributes.width = w; - attributes.height = h; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.window_type = GDK_WINDOW_CHILD; - - attributes.event_mask = gtk_widget_get_events (widget) | - (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK); - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - range->trough = gdk_window_new (widget->window, &attributes, attributes_mask); - - attributes.width = slider_length; - attributes.height = slider_width; - attributes.event_mask |= (GDK_BUTTON_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK); - - range->slider = gdk_window_new (range->trough, &attributes, attributes_mask); - - widget->style = gtk_style_attach (widget->style, widget->window); - - gdk_window_set_user_data (range->trough, widget); - gdk_window_set_user_data (range->slider, widget); - - gtk_style_set_background (widget->style, range->trough, GTK_STATE_ACTIVE); - gtk_style_set_background (widget->style, range->slider, GTK_STATE_NORMAL); - - _gtk_range_slider_update (GTK_RANGE (widget)); - - gdk_window_show (range->slider); -} - -static void -gtk_hscale_clear_background (GtkRange *range) -{ - GtkWidget *widget; - gint x, y, width, height; - - g_return_if_fail (range != NULL); - - widget = GTK_WIDGET (range); - - gtk_hscale_pos_background (GTK_HSCALE (range), &x, &y, &width, &height); - - gtk_widget_queue_clear_area (GTK_WIDGET (range), - x, y, width, height); -} - -static void -gtk_hscale_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - GtkScale *scale = GTK_SCALE (widget); - gint slider_width, slider_length, trough_border; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_HSCALE (widget)); - g_return_if_fail (requisition != NULL); - - _gtk_range_get_props (GTK_RANGE (scale), - &slider_width, &trough_border, NULL, NULL); - gtk_widget_style_get (widget, "slider_length", &slider_length, NULL); - - requisition->width = (slider_length + trough_border) * 2; - requisition->height = (slider_width + trough_border * 2); - - if (scale->draw_value) - { - gint value_width, value_height; - gtk_scale_get_value_size (scale, &value_width, &value_height); - - if ((scale->value_pos == GTK_POS_LEFT) || - (scale->value_pos == GTK_POS_RIGHT)) - { - requisition->width += value_width + SCALE_CLASS (scale)->value_spacing; - if (requisition->height < value_height) - requisition->height = value_height; - } - else if ((scale->value_pos == GTK_POS_TOP) || - (scale->value_pos == GTK_POS_BOTTOM)) - { - if (requisition->width < value_width) - requisition->width = value_width; - requisition->height += value_height; - } - } -} - -static void -gtk_hscale_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +static gboolean +gtk_hscale_expose (GtkWidget *widget, + GdkEventExpose *event) { GtkRange *range; + GtkHScale *hscale; GtkScale *scale; - gint width, height; - gint x, y; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_HSCALE (widget)); - g_return_if_fail (allocation != NULL); - - widget->allocation = *allocation; - if (GTK_WIDGET_REALIZED (widget)) - { - range = GTK_RANGE (widget); - scale = GTK_SCALE (widget); - - gtk_hscale_pos_trough (GTK_HSCALE (widget), &x, &y, &width, &height); - - gdk_window_move_resize (range->trough, - x, y, width, height); - _gtk_range_slider_update (GTK_RANGE (widget)); - } -} - -static void -gtk_hscale_pos_trough (GtkHScale *hscale, - gint *x, - gint *y, - gint *w, - gint *h) -{ - GtkWidget *widget = GTK_WIDGET (hscale); - GtkScale *scale = GTK_SCALE (hscale); - gint slider_width; - gint trough_border; - - _gtk_range_get_props (GTK_RANGE (scale), - &slider_width, &trough_border, NULL, NULL); - - *w = widget->allocation.width; - *h = (slider_width + trough_border * 2); - - if (scale->draw_value) - { - gint value_width, value_height; - gtk_scale_get_value_size (scale, &value_width, &value_height); - - *x = 0; - *y = 0; - - switch (scale->value_pos) - { - case GTK_POS_LEFT: - *x += value_width + SCALE_CLASS (scale)->value_spacing; - *y = (widget->allocation.height - *h) / 2; - *w -= *x; - break; - case GTK_POS_RIGHT: - *w -= value_width + SCALE_CLASS (scale)->value_spacing; - *y = (widget->allocation.height - *h) / 2; - break; - case GTK_POS_TOP: - *y = (value_height + (widget->allocation.height - widget->requisition.height) / 2); - break; - case GTK_POS_BOTTOM: - *y = (widget->allocation.height - widget->requisition.height) / 2; - break; - } - } - else - { - *x = 0; - *y = (widget->allocation.height - *h) / 2; - } - *x += 1; - *w -= 2; - - *x += widget->allocation.x; - *y += widget->allocation.y; -} - -static void -gtk_hscale_pos_background (GtkHScale *hscale, - gint *x, - gint *y, - gint *w, - gint *h) -{ - GtkWidget *widget; - GtkScale *scale; - - gint tx, ty, twidth, theight; - - g_return_if_fail (hscale != NULL); - g_return_if_fail (GTK_IS_HSCALE (hscale)); - g_return_if_fail ((x != NULL) && (y != NULL) && (w != NULL) && (h != NULL)); - - gtk_hscale_pos_trough (hscale, &tx, &ty, &twidth, &theight); - - widget = GTK_WIDGET (hscale); - scale = GTK_SCALE (hscale); - - *x = widget->allocation.x; - *y = widget->allocation.y; - *w = widget->allocation.width; - *h = widget->allocation.height; - - switch (scale->value_pos) - { - case GTK_POS_LEFT: - *w -= twidth; - break; - case GTK_POS_RIGHT: - *x += twidth; - *w -= twidth; - break; - case GTK_POS_TOP: - *h -= theight; - break; - case GTK_POS_BOTTOM: - *y += theight; - *h -= theight; - break; - } - *w = MAX (*w, 0); - *h = MAX (*h, 0); -} - -static void -gtk_hscale_draw_slider (GtkRange *range) -{ - GtkStateType state_type; - - g_return_if_fail (range != NULL); - g_return_if_fail (GTK_IS_HSCALE (range)); - - if (range->slider) - { - if ((range->in_child == RANGE_CLASS (range)->slider) || - (range->click_child == RANGE_CLASS (range)->slider)) - state_type = GTK_STATE_PRELIGHT; - else - state_type = GTK_STATE_NORMAL; - - gtk_paint_slider (GTK_WIDGET (range)->style, range->slider, state_type, - GTK_SHADOW_OUT, - NULL, GTK_WIDGET (range), "hscale", - 0, 0, -1, -1, - GTK_ORIENTATION_HORIZONTAL); - } -} - -static void -gtk_hscale_draw_value (GtkScale *scale) -{ - GtkStateType state_type; - GtkWidget *widget; - gint width, height; - gint x, y; - g_return_if_fail (scale != NULL); - g_return_if_fail (GTK_IS_HSCALE (scale)); - - widget = GTK_WIDGET (scale); + range = GTK_RANGE (widget); + scale = GTK_SCALE (widget); + hscale = GTK_HSCALE (widget); if (scale->draw_value) { PangoLayout *layout; PangoRectangle logical_rect; gchar *txt; + gint x, y; + GtkStateType state_type; + gint value_spacing; + gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL); + txt = _gtk_scale_format_value (scale, GTK_RANGE (scale)->adjustment->value); @@ -529,44 +132,37 @@ gtk_hscale_draw_value (GtkScale *scale) g_free (txt); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - + switch (scale->value_pos) { case GTK_POS_LEFT: - gdk_window_get_position (GTK_RANGE (scale)->trough, &x, &y); - gdk_window_get_size (GTK_RANGE (scale)->trough, &width, &height); - - x -= SCALE_CLASS (scale)->value_spacing + logical_rect.width; - y += (height - logical_rect.height) / 2; + 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: - gdk_window_get_position (GTK_RANGE (scale)->trough, &x, &y); - gdk_window_get_size (GTK_RANGE (scale)->trough, &width, &height); - x += width + SCALE_CLASS (scale)->value_spacing; - y += (height - logical_rect.height) / 2; + 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: - gdk_window_get_position (GTK_RANGE (scale)->slider, &x, NULL); - gdk_window_get_position (GTK_RANGE (scale)->trough, NULL, &y); - gdk_window_get_size (GTK_RANGE (scale)->slider, &width, NULL); - gdk_window_get_size (GTK_RANGE (scale)->trough, NULL, &height); - x += widget->allocation.x + (width - logical_rect.width) / 2; - x = CLAMP (x, widget->allocation.x, - widget->allocation.x + widget->allocation.width - logical_rect.width); - y -= logical_rect.height; + 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: - gdk_window_get_position (GTK_RANGE (scale)->slider, &x, NULL); - gdk_window_get_position (GTK_RANGE (scale)->trough, NULL, &y); - gdk_window_get_size (GTK_RANGE (scale)->slider, &width, NULL); - gdk_window_get_size (GTK_RANGE (scale)->trough, NULL, &height); - x += widget->allocation.x + (width - logical_rect.width) / 2; - x = CLAMP (x, widget->allocation.x, - widget->allocation.x + widget->allocation.width - logical_rect.width); - y += height; + 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_val_if_reached (FALSE); + x = 0; + y = 0; break; } @@ -586,4 +182,6 @@ gtk_hscale_draw_value (GtkScale *scale) g_object_unref (G_OBJECT (layout)); } + + return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); } |