diff options
author | Matthias Clasen <mclasen@redhat.com> | 2010-02-09 00:42:56 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2010-02-09 13:41:58 -0500 |
commit | 893408352d89a04fe70d4b160a6010a0e00072a4 (patch) | |
tree | a5dfc285b398545199a466f042d57add36691951 /gtk/gtkscale.c | |
parent | 412beb444440c01e2e2558cd0d20dac0fc1d9a69 (diff) | |
download | gtk+-893408352d89a04fe70d4b160a6010a0e00072a4.tar.gz |
Avoid overlap of scale marks
This was reported to be a problem in bug 608807.
Diffstat (limited to 'gtk/gtkscale.c')
-rw-r--r-- | gtk/gtkscale.c | 88 |
1 files changed, 79 insertions, 9 deletions
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index 2f4cc98fb6..4c3f478506 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -925,6 +925,27 @@ gtk_scale_size_request (GtkWidget *widget, } } +static gint +find_next_pos (GtkWidget *widget, + GSList *list, + gint *marks, + GtkPositionType pos, + gint match) +{ + GSList *m; + gint i; + + for (m = list->next, i = 1; m; m = m->next, i++) + { + GtkScaleMark *mark = m->data; + + if (match == (mark->position == pos)) + return marks[i]; + } + + return widget->allocation.width; +} + static gboolean gtk_scale_expose (GtkWidget *widget, GdkEventExpose *event) @@ -938,6 +959,7 @@ gtk_scale_expose (GtkWidget *widget, gint focus_padding; gint slider_width; gint value_spacing; + gint min_sep = 4; gtk_widget_style_get (widget, "focus-padding", &focus_padding, @@ -961,10 +983,16 @@ gtk_scale_expose (GtkWidget *widget, PangoLayout *layout; PangoRectangle logical_rect; GSList *m; + gint min_pos_before, min_pos_after; + gint min_pos, max_pos; n_marks = _gtk_range_get_stop_positions (range, &marks); layout = gtk_widget_create_pango_layout (widget, NULL); + if (range->orientation == GTK_ORIENTATION_HORIZONTAL) + min_pos_before = min_pos_after = widget->allocation.x; + else + min_pos_before = min_pos_after = widget->allocation.y; for (m = priv->marks, i = 0; m; m = m->next, i++) { GtkScaleMark *mark = m->data; @@ -976,11 +1004,15 @@ gtk_scale_expose (GtkWidget *widget, { y1 = widget->allocation.y + range->range_rect.y; y2 = y1 - slider_width / 2; + min_pos = min_pos_before; + max_pos = widget->allocation.x + find_next_pos (widget, m, marks + i, GTK_POS_TOP, 1) - min_sep; } else { y1 = widget->allocation.y + range->range_rect.y + range->range_rect.height; y2 = y1 + slider_width / 2; + min_pos = min_pos_after; + max_pos = widget->allocation.x + find_next_pos (widget, m, marks + i, GTK_POS_TOP, 0) - min_sep; } gtk_paint_vline (widget->style, widget->window, state_type, @@ -990,15 +1022,27 @@ gtk_scale_expose (GtkWidget *widget, { pango_layout_set_markup (layout, mark->markup, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - + x3 = x1 - logical_rect.width / 2; + if (x3 < min_pos) + x3 = min_pos; + if (x3 + logical_rect.width > max_pos) + x3 = max_pos - logical_rect.width; + if (x3 < widget->allocation.x) + x3 = widget->allocation.x; if (mark->position == GTK_POS_TOP) - y3 = y2 - value_spacing - logical_rect.height; + { + y3 = y2 - value_spacing - logical_rect.height; + min_pos_before = x3 + logical_rect.width + min_sep; + } else - y3 = y2 + value_spacing; + { + y3 = y2 + value_spacing; + min_pos_after = x3 + logical_rect.width + min_sep; + } gtk_paint_layout (widget->style, widget->window, state_type, - FALSE, NULL, widget, "scale-mark", + FALSE, NULL, widget, "scale-mark", x3, y3, layout); } } @@ -1008,11 +1052,15 @@ gtk_scale_expose (GtkWidget *widget, { x1 = widget->allocation.x + range->range_rect.x; x2 = widget->allocation.x + range->range_rect.x - slider_width / 2; + min_pos = min_pos_before; + max_pos = widget->allocation.y + find_next_pos (widget, m, marks + i, GTK_POS_LEFT, 1) - min_sep; } 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; + min_pos = min_pos_after; + max_pos = widget->allocation.y + find_next_pos (widget, m, marks + i, GTK_POS_LEFT, 0) - min_sep; } y1 = widget->allocation.y + marks[i]; @@ -1024,14 +1072,26 @@ gtk_scale_expose (GtkWidget *widget, pango_layout_set_markup (layout, mark->markup, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + y3 = y1 - logical_rect.height / 2; + if (y3 < min_pos) + y3 = min_pos; + if (y3 + logical_rect.height > max_pos) + y3 = max_pos - logical_rect.height; + if (y3 < widget->allocation.y) + y3 = widget->allocation.y; if (mark->position == GTK_POS_LEFT) - x3 = x2 - value_spacing - logical_rect.width; + { + x3 = x2 - value_spacing - logical_rect.width; + min_pos_before = y3 + logical_rect.height + min_sep; + } else - x3 = x2 + value_spacing; - y3 = y1 - logical_rect.height / 2; + { + x3 = x2 + value_spacing; + min_pos_after = y3 + logical_rect.height + min_sep; + } gtk_paint_layout (widget->style, widget->window, state_type, - FALSE, NULL, widget, "scale-mark", + FALSE, NULL, widget, "scale-mark", x3, y3, layout); } } @@ -1315,6 +1375,16 @@ gtk_scale_clear_marks (GtkScale *scale) gtk_widget_queue_resize (GTK_WIDGET (scale)); } +static gint +compare_marks (gpointer a, gpointer b) +{ + GtkScaleMark *ma, *mb; + + ma = a; mb = b; + + return (gint) (ma->value - mb->value); +} + /** * gtk_scale_add_mark: * @scale: a #GtkScale @@ -1356,7 +1426,7 @@ gtk_scale_add_mark (GtkScale *scale, mark->markup = g_strdup (markup); mark->position = position; - priv->marks = g_slist_prepend (priv->marks, mark); + priv->marks = g_slist_insert_sorted (priv->marks, mark, compare_marks); n = g_slist_length (priv->marks); values = g_new (gdouble, n); |