forked from AuroraMiddleware/gtk
Avoid overlap of scale marks
This was reported to be a problem in bug 608807.
This commit is contained in:
parent
412beb4444
commit
893408352d
@ -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);
|
||||
|
||||
if (mark->position == GTK_POS_LEFT)
|
||||
x3 = x2 - value_spacing - logical_rect.width;
|
||||
else
|
||||
x3 = x2 + value_spacing;
|
||||
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;
|
||||
min_pos_before = y3 + logical_rect.height + min_sep;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user