diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | docs/reference/ChangeLog | 4 | ||||
-rw-r--r-- | docs/reference/gtk/gtk-sections.txt | 2 | ||||
-rw-r--r-- | gtk/gtk.symbols | 2 | ||||
-rw-r--r-- | gtk/gtkrange.c | 119 | ||||
-rw-r--r-- | gtk/gtkrange.h | 6 | ||||
-rw-r--r-- | gtk/gtkscale.c | 340 | ||||
-rw-r--r-- | gtk/gtkscale.h | 8 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rwxr-xr-x | tests/testscale.c | 149 |
10 files changed, 641 insertions, 8 deletions
@@ -1,3 +1,19 @@ +2009-01-20 Matthias Clasen <mclasen@redhat.com> + + Bug 565656 – Add marks to scales + + * gtk/gtkrange.[hc]: Add internal api to define 'stop values' + that have a little resistance when dragging the slider over it. + + * gtk/gtk.symbols: + * gtk/gtkscale.[hc] (gtk_scale_add_mark): New function to add + a 'mark' to a scale, which will draws a tick, plus optionally + some text, and makes the value a stop value. + (gtk_scale_clear_values): Removes all marks. + + * tests/testscale.c: Test for marks on scales + * tests/Makefile.am: Integrate it + 2009-01-19 Matthias Clasen <mclasen@redhat.com> * gtk/gtkentry.c: diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index d86a1d04e4..dd3da2b828 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2009-01-20 Matthias Clasen <mclasen@redhat.com> + + * gtk/gtk-sections.txt: Add new scale api + 2009-01-19 Matthias Clasen <mclasen@redhat.com> * gdk/tmpl/cursors.sgml: Document GDK_BLANK_CURSOR. diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 448ba4e68a..597e65a740 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -3229,6 +3229,8 @@ gtk_scale_get_draw_value gtk_scale_get_value_pos gtk_scale_get_layout gtk_scale_get_layout_offsets +gtk_scale_add_mark +gtk_scale_clear_marks <SUBSECTION Standard> GTK_SCALE GTK_IS_SCALE diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 0e73df53de..096b8fe01e 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -3460,6 +3460,8 @@ gtk_scale_get_value_pos gtk_scale_set_digits gtk_scale_set_draw_value gtk_scale_set_value_pos +gtk_scale_add_mark +gtk_scale_clear_marks #endif #endif diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index e926f70d34..cdf9212839 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -117,6 +117,11 @@ struct _GtkRangeLayout GQuark slider_detail_quark; GQuark stepper_detail_quark; + + gdouble *marks; + gint *mark_pos; + gint n_marks; + gboolean recalc_marks; }; @@ -175,6 +180,7 @@ static gboolean gtk_range_scroll (GtkRange *range, static gboolean gtk_range_update_mouse_location (GtkRange *range); static void gtk_range_calc_layout (GtkRange *range, gdouble adjustment_value); +static void gtk_range_calc_marks (GtkRange *range); static void gtk_range_get_props (GtkRange *range, gint *slider_width, gint *stepper_size, @@ -1216,6 +1222,13 @@ gtk_range_destroy (GtkObject *object) range->adjustment = NULL; } + if (range->layout->n_marks) + { + g_free (range->layout->marks); + g_free (range->layout->mark_pos); + range->layout->n_marks = 0; + } + GTK_OBJECT_CLASS (gtk_range_parent_class)->destroy (object); } @@ -1255,6 +1268,8 @@ gtk_range_size_allocate (GtkWidget *widget, widget->allocation = *allocation; + range->layout->recalc_marks = TRUE; + range->need_recalc = TRUE; gtk_range_calc_layout (range, range->adjustment->value); @@ -1520,6 +1535,7 @@ gtk_range_expose (GtkWidget *widget, expose_area.x -= widget->allocation.x; expose_area.y -= widget->allocation.y; + gtk_range_calc_marks (range); gtk_range_calc_layout (range, range->adjustment->value); sensitive = GTK_WIDGET_IS_SENSITIVE (widget); @@ -2101,6 +2117,10 @@ update_slider_position (GtkRange *range, gint c; gdouble new_value; gboolean handled; + gdouble next_value; + gdouble mark_value; + gdouble mark_delta; + gint i; if (range->orientation == GTK_ORIENTATION_VERTICAL) delta = mouse_y - range->slide_initial_coordinate; @@ -2110,7 +2130,23 @@ update_slider_position (GtkRange *range, c = range->slide_initial_slider_position + delta; new_value = coord_to_value (range, c); - + next_value = coord_to_value (range, c + 1); + mark_delta = fabs (next_value - new_value); + + for (i = 0; i < range->layout->n_marks; i++) + { + mark_value = range->layout->marks[i]; + + if (fabs (range->adjustment->value - mark_value) < 3 * mark_delta) + { + if (fabs (new_value - mark_value) < (range->slider_end - range->slider_start) * 0.5 * mark_delta) + { + new_value = mark_value; + break; + } + } + } + g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_JUMP, new_value, &handled); } @@ -2340,6 +2376,7 @@ gtk_range_adjustment_changed (GtkAdjustment *adjustment, /* create a copy of the layout */ GtkRangeLayout layout = *range->layout; + range->layout->recalc_marks = TRUE; range->need_recalc = TRUE; gtk_range_calc_layout (range, range->adjustment->value); @@ -2409,12 +2446,33 @@ gtk_range_style_set (GtkWidget *widget, } static void +apply_marks (GtkRange *range, + gdouble oldval, + gdouble *newval) +{ + gint i; + gdouble mark; + + for (i = 0; i < range->layout->n_marks; i++) + { + mark = range->layout->marks[i]; + if ((oldval < mark && mark < *newval) || + (oldval > mark && mark > *newval)) + { + *newval = mark; + return; + } + } +} + +static void step_back (GtkRange *range) { gdouble newval; gboolean handled; newval = range->adjustment->value - range->adjustment->step_increment; + apply_marks (range, range->adjustment->value, &newval); g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_STEP_BACKWARD, newval, &handled); } @@ -2426,6 +2484,7 @@ step_forward (GtkRange *range) gboolean handled; newval = range->adjustment->value + range->adjustment->step_increment; + apply_marks (range, range->adjustment->value, &newval); g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_STEP_FORWARD, newval, &handled); } @@ -2438,6 +2497,7 @@ page_back (GtkRange *range) gboolean handled; newval = range->adjustment->value - range->adjustment->page_increment; + apply_marks (range, range->adjustment->value, &newval); g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_PAGE_BACKWARD, newval, &handled); } @@ -2449,6 +2509,7 @@ page_forward (GtkRange *range) gboolean handled; newval = range->adjustment->value + range->adjustment->page_increment; + apply_marks (range, range->adjustment->value, &newval); g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_PAGE_FORWARD, newval, &handled); } @@ -3337,6 +3398,29 @@ get_area (GtkRange *range, return NULL; } +static void +gtk_range_calc_marks (GtkRange *range) +{ + gint i; + + if (!range->layout->recalc_marks) + return; + + range->layout->recalc_marks = FALSE; + + for (i = 0; i < range->layout->n_marks; i++) + { + range->need_recalc = TRUE; + gtk_range_calc_layout (range, range->layout->marks[i]); + if (range->orientation == GTK_ORIENTATION_HORIZONTAL) + range->layout->mark_pos[i] = range->layout->slider.x + range->layout->slider.width / 2; + else + range->layout->mark_pos[i] = range->layout->slider.y + range->layout->slider.height / 2; + } + + range->need_recalc = TRUE; +} + static gboolean gtk_range_real_change_value (GtkRange *range, GtkScrollType scroll, @@ -3511,5 +3595,38 @@ gtk_range_remove_update_timer (GtkRange *range) } } +void +_gtk_range_set_stop_values (GtkRange *range, + gdouble *values, + gint n_values) +{ + gint i; + + g_free (range->layout->marks); + range->layout->marks = g_new (gdouble, n_values); + + g_free (range->layout->mark_pos); + range->layout->mark_pos = g_new (gint, n_values); + + range->layout->n_marks = n_values; + + for (i = 0; i < n_values; i++) + range->layout->marks[i] = values[i]; + + range->layout->recalc_marks = TRUE; +} + +gint +_gtk_range_get_stop_positions (GtkRange *range, + gint **values) +{ + gtk_range_calc_marks (range); + + if (values) + *values = g_memdup (range->layout->mark_pos, range->layout->n_marks * sizeof (gint)); + + return range->layout->n_marks; +} + #define __GTK_RANGE_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h index 08860f8121..f7f3b96aa7 100644 --- a/gtk/gtkrange.h +++ b/gtk/gtkrange.h @@ -178,6 +178,12 @@ gdouble gtk_range_get_fill_level (GtkRange *range gdouble _gtk_range_get_wheel_delta (GtkRange *range, GdkScrollDirection direction); +void _gtk_range_set_stop_values (GtkRange *range, + gdouble *values, + gint n_values); +gint _gtk_range_get_stop_positions (GtkRange *range, + gint **values); + G_END_DECLS diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index e602f9e4f7..87ba227991 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -32,6 +32,8 @@ #include "gdk/gdkkeysyms.h" #include "gtkscale.h" +#include "gtkiconfactory.h" +#include "gtkicontheme.h" #include "gtkmarshalers.h" #include "gtkbindings.h" #include "gtkprivate.h" @@ -49,9 +51,19 @@ typedef struct _GtkScalePrivate GtkScalePrivate; +typedef struct _GtkScaleMark GtkScaleMark; + +struct _GtkScaleMark +{ + gdouble value; + const gchar *markup; + GtkPositionType position; +}; + struct _GtkScalePrivate { PangoLayout *layout; + GSList *marks; }; enum { @@ -76,10 +88,20 @@ static void gtk_scale_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gtk_scale_size_request (GtkWidget *widget, + GtkRequisition *requisition); 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_get_mark_label_size (GtkScale *scale, + GtkPositionType position, + gint *count1, + gint *width1, + gint *height1, + gint *count2, + gint *width2, + gint *height2); static void gtk_scale_finalize (GObject *object); static void gtk_scale_screen_changed (GtkWidget *widget, GdkScreen *old_screen); @@ -132,6 +154,7 @@ 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; + widget_class->size_request = gtk_scale_size_request; range_class->slider_detail = "Xscale"; range_class->get_range_border = gtk_scale_get_range_border; @@ -647,12 +670,14 @@ static void gtk_scale_get_range_border (GtkRange *range, GtkBorder *border) { + GtkScalePrivate *priv; GtkWidget *widget; GtkScale *scale; gint w, h; widget = GTK_WIDGET (range); scale = GTK_SCALE (range); + priv = GTK_SCALE_GET_PRIVATE (scale); _gtk_scale_get_value_size (scale, &w, &h); @@ -682,6 +707,36 @@ gtk_scale_get_range_border (GtkRange *range, break; } } + + if (priv->marks) + { + gint slider_width; + gint value_spacing; + gint n1, w1, h1, n2, w2, h2; + + gtk_widget_style_get (widget, + "slider-width", &slider_width, + "value-spacing", &value_spacing, + NULL); + + + if (GTK_RANGE (scale)->orientation == GTK_ORIENTATION_HORIZONTAL) + { + gtk_scale_get_mark_label_size (scale, GTK_POS_TOP, &n1, &w1, &h1, &n2, &w2, &h2); + if (n1 > 0) + border->top += h1 + value_spacing + slider_width / 2; + if (n2 > 0) + border->bottom += h2 + value_spacing + slider_width / 2; + } + else + { + gtk_scale_get_mark_label_size (scale, GTK_POS_LEFT, &n1, &w1, &h1, &n2, &w2, &h2); + if (n1 > 0) + border->left += w1 + value_spacing + slider_width / 2; + if (n2 > 0) + border->right += w2 + value_spacing + slider_width / 2; + } + } } /* FIXME this could actually be static at the moment. */ @@ -739,6 +794,63 @@ _gtk_scale_get_value_size (GtkScale *scale, } static void +gtk_scale_get_mark_label_size (GtkScale *scale, + GtkPositionType position, + gint *count1, + gint *width1, + gint *height1, + gint *count2, + gint *width2, + gint *height2) +{ + GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale); + PangoLayout *layout; + PangoRectangle logical_rect; + GSList *m; + gint w, h; + + *count1 = *count2 = 0; + *width1 = *width2 = 0; + *height1 = *height2 = 0; + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL); + + for (m = priv->marks; m; m = m->next) + { + GtkScaleMark *mark = m->data; + + if (mark->markup) + { + pango_layout_set_markup (layout, mark->markup, -1); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + w = logical_rect.width; + h = logical_rect.height; + } + else + { + w = 0; + h = 0; + } + + if (mark->position == position) + { + (*count1)++; + *width1 = MAX (*width1, w); + *height1 = MAX (*height1, h); + } + else + { + (*count2)++; + *width2 = MAX (*width2, w); + *height2 = MAX (*height2, h); + } + } + + g_object_unref (layout); +} + +static void gtk_scale_style_set (GtkWidget *widget, GtkStyle *previous) { @@ -765,31 +877,160 @@ gtk_scale_screen_changed (GtkWidget *widget, _gtk_scale_clear_layout (GTK_SCALE (widget)); } +static void +gtk_scale_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkRange *range = GTK_RANGE (widget); + gint n1, w1, h1, n2, w2, h2; + gint slider_length; + + GTK_WIDGET_CLASS (gtk_scale_parent_class)->size_request (widget, requisition); + + gtk_widget_style_get (widget, "slider-length", &slider_length, NULL); + + + if (range->orientation == GTK_ORIENTATION_HORIZONTAL) + { + gtk_scale_get_mark_label_size (GTK_SCALE (widget), GTK_POS_TOP, &n1, &w1, &h1, &n2, &w2, &h2); + + w1 = (n1 - 1) * w1 + MAX (w1, slider_length); + w2 = (n2 - 1) * w2 + MAX (w2, slider_length); + requisition->width = MAX (requisition->width, MAX (w1, w2)); + } + else + { + gtk_scale_get_mark_label_size (GTK_SCALE (widget), GTK_POS_LEFT, &n1, &w1, &h1, &n2, &w2, &h2); + h1 = (n1 - 1) * h1 + MAX (h1, slider_length); + h2 = (n2 - 1) * h1 + MAX (h2, slider_length); + requisition->height = MAX (requisition->height, MAX (h1, h2)); + } +} + static gboolean gtk_scale_expose (GtkWidget *widget, GdkEventExpose *event) { GtkScale *scale = GTK_SCALE (widget); + GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale); + GtkRange *range = GTK_RANGE (scale); + GtkStateType state_type; + gint n_marks; + gint *marks; + gint focus_padding; + gint slider_width; + gint value_spacing; + + gtk_widget_style_get (widget, + "focus-padding", &focus_padding, + "slider-width", &slider_width, + "value-spacing", &value_spacing, + NULL); /* 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); + state_type = GTK_STATE_NORMAL; + if (!GTK_WIDGET_IS_SENSITIVE (widget)) + state_type = GTK_STATE_INSENSITIVE; + + if (priv->marks) + { + gint i; + gint x1, x2, x3, y1, y2, y3; + PangoLayout *layout; + PangoRectangle logical_rect; + GSList *m; + + n_marks = _gtk_range_get_stop_positions (range, &marks); + layout = gtk_widget_create_pango_layout (widget, NULL); + + for (m = priv->marks, i = 0; m; m = m->next, i++) + { + GtkScaleMark *mark = m->data; + + if (range->orientation == GTK_ORIENTATION_HORIZONTAL) + { + x1 = widget->allocation.x + marks[i]; + if (mark->position == GTK_POS_TOP) + { + y1 = widget->allocation.y + range->range_rect.y; + y2 = y1 - slider_width / 2; + } + else + { + y1 = widget->allocation.y + range->range_rect.y + range->range_rect.height; + y2 = y1 + slider_width / 2; + } + + gtk_paint_vline (widget->style, widget->window, state_type, + NULL, widget, "scale-mark", y1, y2, x1); + + if (mark->markup) + { + pango_layout_set_markup (layout, mark->markup, -1); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + x3 = x1 - logical_rect.width / 2; + if (mark->position == GTK_POS_TOP) + y3 = y2 - value_spacing - logical_rect.height; + else + y3 = y2 + value_spacing; + + gtk_paint_layout (widget->style, widget->window, state_type, + FALSE, NULL, widget, "scale-mark", + x3, y3, layout); + } + } + else + { + if (mark->position == GTK_POS_LEFT) + { + x1 = widget->allocation.x + range->range_rect.x; + x2 = widget->allocation.x + range->range_rect.x - slider_width / 2; + } + else + { + x1 = widget->allocation.x + range->range_rect.x + range->range_rect.width; + x2 = widget->allocation.x + range->range_rect.x + range->range_rect.width + slider_width / 2; + } + y1 = widget->allocation.y + marks[i]; + + gtk_paint_hline (widget->style, widget->window, state_type, + NULL, widget, "range-mark", x1, x2, y1); + + if (mark->markup) + { + pango_layout_set_markup (layout, mark->markup, -1); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + if (mark->position == GTK_POS_LEFT) + x3 = x2 - value_spacing - logical_rect.width; + else + x3 = x2 + value_spacing; + y3 = y1 - logical_rect.height / 2; + + gtk_paint_layout (widget->style, widget->window, state_type, + FALSE, NULL, widget, "scale-mark", + x3, y3, layout); + } + } + } + + g_object_unref (layout); + g_free (marks); + } + 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, @@ -932,6 +1173,7 @@ gtk_scale_finalize (GObject *object) GtkScale *scale = GTK_SCALE (object); _gtk_scale_clear_layout (scale); + gtk_scale_clear_marks (scale); G_OBJECT_CLASS (gtk_scale_parent_class)->finalize (object); } @@ -1024,5 +1266,91 @@ _gtk_scale_clear_layout (GtkScale *scale) } } +static void +gtk_scale_mark_free (GtkScaleMark *mark) +{ + g_free (mark->markup); + g_free (mark); +} + +/** + * gtk_scale_clear_marks: + * @scale: a #GtkScale + * + * Removes any marks that have been added with gtk_scale_add_mark(). + * + * Since: 2.16 + */ +void +gtk_scale_clear_marks (GtkScale *scale) +{ + GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale); + + g_return_if_fail (GTK_IS_SCALE (scale)); + + g_slist_foreach (priv->marks, (GFunc)gtk_scale_mark_free, NULL); + g_slist_free (priv->marks); + priv->marks = NULL; + + _gtk_range_set_stop_values (GTK_RANGE (scale), NULL, 0); +} + +/** + * gtk_scale_add_mark: + * @scale: a #GtkScale + * @value: the value at which the mark is placed, must be between + * the lower and upper limits of the scales' adjustment + * @position: where to draw the mark. For a horizontal scale, #GTK_POS_TOP + * is drawn above the scale, anything else below. For a vertical scale, + * #GTK_POS_LEFT is drawn to the left of the scale, anything else to the + * right. + * @markup: Text to be shown at the mark, using <link linkend="PangoMarkupFormat">Pango markup</link>, or %NULL + * + * + * Adds a mark at @value. + * + * A mark is indicated visually by drawing a tick mark next to the scale, + * and GTK+ makes it easy for the user to position the scale exactly at the + * marks value. + * + * If @markup is not %NULL, text is shown next to the tick mark. + * + * To remove marks from a scale, use gtk_scale_clear_marks(). + * + * Since: 2.16 + */ +void +gtk_scale_add_mark (GtkScale *scale, + gdouble value, + GtkPositionType position, + const gchar *markup) +{ + GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale); + GtkScaleMark *mark; + GSList *m; + gdouble *values; + gint n, i; + + mark = g_new (GtkScaleMark, 1); + mark->value = value; + mark->markup = g_strdup (markup); + mark->position = position; + + priv->marks = g_slist_prepend (priv->marks, mark); + + n = g_slist_length (priv->marks); + values = g_new (gdouble, n); + for (m = priv->marks, i = 0; m; m = m->next, i++) + { + mark = m->data; + values[i] = mark->value; + } + + _gtk_range_set_stop_values (GTK_RANGE (scale), values, n); + + g_free (values); +} + + #define __GTK_SCALE_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkscale.h b/gtk/gtkscale.h index 34e690adac..4221dd281c 100644 --- a/gtk/gtkscale.h +++ b/gtk/gtkscale.h @@ -71,9 +71,9 @@ struct _GtkScaleClass gint *y); /* Padding for future expansion */ + void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); }; GType gtk_scale_get_type (void) G_GNUC_CONST; @@ -92,6 +92,12 @@ void gtk_scale_get_layout_offsets (GtkScale *scale, gint *x, gint *y); +void gtk_scale_add_mark (GtkScale *scale, + gdouble value, + GtkPositionType position, + const gchar *markup); +void gtk_scale_clear_marks (GtkScale *scale); + /* internal API */ void _gtk_scale_clear_layout (GtkScale *scale); void _gtk_scale_get_value_size (GtkScale *scale, diff --git a/tests/Makefile.am b/tests/Makefile.am index 370b997ef3..426dea30e9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -60,6 +60,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \ testrecentchooser \ testrecentchoosermenu \ testrichtext \ + testscale \ testselection \ $(testsocket_programs) \ testspinbutton \ @@ -137,6 +138,7 @@ testrecentchooser_DEPENDENCIES = $(TEST_DEPS) testrecentchoosermenu_DEPENDENCIES = $(TEST_DEPS) testrgb_DEPENDENCIES = $(TEST_DEPS) testrichtext_DEPENDENCIES = $(TEST_DEPS) +testscale_DEPENDENCIES = $(TEST_DEPS) testselection_DEPENDENCIES = $(TEST_DEPS) testsocket_DEPENDENCIES = $(DEPS) testsocket_child_DEPENDENCIES = $(DEPS) @@ -194,6 +196,7 @@ testrecentchooser_LDADD = $(LDADDS) testrecentchoosermenu_LDADD = $(LDADDS) testrgb_LDADD = $(LDADDS) testrichtext_LDADD = $(LDADDS) +testscale_LDADD = $(LDADDS) testselection_LDADD = $(LDADDS) testsocket_LDADD = $(LDADDS) testsocket_child_LDADD = $(LDADDS) diff --git a/tests/testscale.c b/tests/testscale.c new file mode 100755 index 0000000000..35b287e2dd --- /dev/null +++ b/tests/testscale.c @@ -0,0 +1,149 @@ +/* testscale.c - scale mark demo + * Copyright (C) 2009 Red Hat, Inc. + * Author: Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gtk/gtk.h> + +int main (int argc, char *argv[]) +{ + GtkWidget *window; + GtkWidget *box; + GtkWidget *box2; + GtkWidget *frame; + GtkWidget *scale; + GIcon *icon; + gdouble marks[3] = { 0.0, 50.0, 100.0 }; + const gchar *labels[3] = { + "<small>Left</small>", + "<small>Middle</small>", + "<small>Right</small>" + }; + + gdouble bath_marks[4] = { 0.0, 33.3, 66.6, 100.0 }; + const gchar *bath_labels[4] = { + "<span color='blue' size='small'>Cold</span>", + "<span size='small'>Baby bath</span>", + "<span size='small'>Hot tub</span>", + "<span color='Red' size='small'>Hot</span>" + }; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "Ranges with marks"); + box = gtk_vbox_new (FALSE, 5); + + frame = gtk_frame_new ("No marks"); + scale = gtk_hscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Simple marks"); + scale = gtk_hscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_BOTTOM, NULL); + gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_BOTTOM, NULL); + gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_BOTTOM, NULL); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Labeled marks"); + scale = gtk_hscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_BOTTOM, labels[0]); + gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_BOTTOM, labels[1]); + gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_BOTTOM, labels[2]); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Some labels"); + scale = gtk_hscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_BOTTOM, labels[0]); + gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_BOTTOM, NULL); + gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_BOTTOM, labels[2]); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Above and below"); + scale = gtk_hscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[0], GTK_POS_TOP, bath_labels[0]); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[1], GTK_POS_BOTTOM, bath_labels[1]); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[2], GTK_POS_BOTTOM, bath_labels[2]); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[3], GTK_POS_TOP, bath_labels[3]); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 0); + + box2 = gtk_hbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (box), box2, TRUE, TRUE, 0); + + frame = gtk_frame_new ("No marks"); + scale = gtk_vscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Simple marks"); + scale = gtk_vscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_LEFT, NULL); + gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_LEFT, NULL); + gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_LEFT, NULL); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Labeled marks"); + scale = gtk_vscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_LEFT, labels[0]); + gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_LEFT, labels[1]); + gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_LEFT, labels[2]); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Some labels"); + scale = gtk_vscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_LEFT, labels[0]); + gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_LEFT, NULL); + gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_LEFT, labels[2]); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Right and left"); + scale = gtk_vscale_new_with_range (0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[0], GTK_POS_RIGHT, bath_labels[0]); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[1], GTK_POS_LEFT, bath_labels[1]); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[2], GTK_POS_LEFT, bath_labels[2]); + gtk_scale_add_mark (GTK_SCALE (scale), bath_marks[3], GTK_POS_RIGHT, bath_labels[3]); + gtk_container_add (GTK_CONTAINER (frame), scale); + gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (window), box); + gtk_widget_show_all (window); + + gtk_main (); + + return 0; +} + + |