diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2016-02-28 09:23:14 -0800 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2016-02-29 10:45:14 -0800 |
commit | cdd7a7bdcd29109985d3846324ef52c19ed3f70b (patch) | |
tree | d53aa5518d18468cb2fcb900bd7ef982054b81da /gtk/gtkscale.c | |
parent | 1a8eb9fefa2693c274d7733c57727337dcba8b60 (diff) | |
download | gtk+-cdd7a7bdcd29109985d3846324ef52c19ed3f70b.tar.gz |
scale: implement rendering for marks gadgets
This completes the conversion of scale marks to gadgets.
Diffstat (limited to 'gtk/gtkscale.c')
-rw-r--r-- | gtk/gtkscale.c | 242 |
1 files changed, 129 insertions, 113 deletions
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index 3f351b0c4c..3794724071 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -1324,167 +1324,183 @@ find_next_pos (GtkWidget *widget, } static gboolean -gtk_scale_draw (GtkWidget *widget, - cairo_t *cr) +gtk_scale_render_marks (GtkCssGadget *gadget, + cairo_t *cr, + int x, + int y, + int width, + int height, + gpointer user_data) { + GtkWidget *widget = gtk_css_gadget_get_owner (gadget); GtkScale *scale = GTK_SCALE (widget); GtkScalePrivate *priv = scale->priv; - GtkRange *range = GTK_RANGE (scale); - GtkStyleContext *context; - gint *marks; - gint value_spacing; - gint min_sep = 4; + GtkOrientation orientation; + gint i; + gint x1, x2, x3, y1, y2, y3; + PangoLayout *layout; + PangoRectangle logical_rect; + GSList *m; + gint min_pos_before, min_pos_after; + gint min_pos, max_pos; GtkCssGadget *slider_gadget; GtkAllocation slider_alloc; + gint value_spacing; + gint min_sep = 4; + gint *marks; + GtkStyleContext *context; + GtkRange *range = GTK_RANGE (scale); context = gtk_widget_get_style_context (widget); + gtk_widget_style_get (widget, + "value-spacing", &value_spacing, + NULL); + slider_gadget = gtk_range_get_slider_gadget (range); gtk_css_gadget_get_content_allocation (slider_gadget, &slider_alloc, NULL); - gtk_widget_style_get (widget, - "value-spacing", &value_spacing, - NULL); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (range)); + _gtk_range_get_stop_positions (range, &marks); - if (priv->marks) - { - GtkOrientation orientation; - GdkRectangle range_rect, marks_alloc; - gint i; - gint x1, x2, x3, y1, y2, y3; - PangoLayout *layout; - PangoRectangle logical_rect; - GSList *m; - gint min_pos_before, min_pos_after; - gint min_pos, max_pos; + layout = gtk_widget_create_pango_layout (widget, NULL); - orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (range)); - _gtk_range_get_stop_positions (range, &marks); + min_pos_before = min_pos_after = 0; - layout = gtk_widget_create_pango_layout (widget, NULL); - gtk_range_get_range_rect (range, &range_rect); + for (m = priv->marks, i = 0; m; m = m->next, i++) + { + GtkScaleMark *mark = m->data; - min_pos_before = min_pos_after = 0; + if ((mark->position == GTK_POS_TOP && gadget == priv->bottom_marks_gadget) || + (mark->position == GTK_POS_BOTTOM && gadget == priv->top_marks_gadget)) + continue; - for (m = priv->marks, i = 0; m; m = m->next, i++) + gtk_style_context_save_to_node (context, mark->node); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) { - GtkScaleMark *mark = m->data; + x1 = marks[i]; + if (mark->position == GTK_POS_TOP) + { + y1 = y + height; + y2 = y + height - slider_alloc.height / 4; + min_pos = min_pos_before; + max_pos = find_next_pos (widget, m, marks + i, GTK_POS_TOP) - min_sep; + } + else + { + y1 = y; + y2 = y + slider_alloc.height / 4; + min_pos = min_pos_after; + max_pos = find_next_pos (widget, m, marks + i, GTK_POS_BOTTOM) - min_sep; + } - gtk_style_context_save_to_node (context, mark->node); + gtk_render_line (context, cr, x1, y1, x1, y2); - if (orientation == GTK_ORIENTATION_HORIZONTAL) + if (mark->markup) { - x1 = marks[i]; + 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 < 0) + x3 = 0; if (mark->position == GTK_POS_TOP) { - gtk_css_gadget_get_content_box (priv->top_marks_gadget, &marks_alloc); - y1 = marks_alloc.y + marks_alloc.height; - y2 = marks_alloc.y + marks_alloc.height - slider_alloc.height / 4; - min_pos = min_pos_before; - max_pos = find_next_pos (widget, m, marks + i, GTK_POS_TOP) - min_sep; + y3 = y2 - value_spacing - logical_rect.height; + min_pos_before = x3 + logical_rect.width + min_sep; } else { - gtk_css_gadget_get_content_box (priv->bottom_marks_gadget, &marks_alloc); - y1 = marks_alloc.y; - y2 = marks_alloc.y + slider_alloc.height / 4; - min_pos = min_pos_after; - max_pos = find_next_pos (widget, m, marks + i, GTK_POS_BOTTOM) - min_sep; + y3 = y2 + value_spacing; + min_pos_after = x3 + logical_rect.width + min_sep; } - gtk_render_line (context, cr, x1, y1, x1, y2); - - 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 (x3 < min_pos) - x3 = min_pos; - if (x3 + logical_rect.width > max_pos) - x3 = max_pos - logical_rect.width; - if (x3 < 0) - x3 = 0; - if (mark->position == GTK_POS_TOP) - { - y3 = y2 - value_spacing - logical_rect.height; - min_pos_before = x3 + logical_rect.width + min_sep; - } - else - { - y3 = y2 + value_spacing; - min_pos_after = x3 + logical_rect.width + min_sep; - } - - gtk_render_layout (context, cr, x3, y3, layout); - } + gtk_render_layout (context, cr, x3, y3, layout); + } + } + else + { + if (mark->position == GTK_POS_TOP) + { + x1 = x + width; + x2 = x + width - slider_alloc.width / 4; + min_pos = min_pos_before; + max_pos = find_next_pos (widget, m, marks + i, GTK_POS_TOP) - min_sep; } else { + x1 = x; + x2 = x + slider_alloc.width / 4; + min_pos = min_pos_after; + max_pos = find_next_pos (widget, m, marks + i, GTK_POS_BOTTOM) - min_sep; + } + y1 = marks[i]; + + gtk_render_line (context, cr, x1, y1, x2, y1); + + if (mark->markup) + { + 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 < 0) + y3 = 0; if (mark->position == GTK_POS_TOP) { - gtk_css_gadget_get_content_box (priv->top_marks_gadget, &marks_alloc); - x1 = marks_alloc.x + slider_alloc.width / 4; - x2 = marks_alloc.x; - min_pos = min_pos_before; - max_pos = find_next_pos (widget, m, marks + i, GTK_POS_TOP) - min_sep; + x3 = x2 - value_spacing - logical_rect.width; + min_pos_before = y3 + logical_rect.height + min_sep; } else { - gtk_css_gadget_get_content_box (priv->bottom_marks_gadget, &marks_alloc); - x1 = marks_alloc.x; - x2 = marks_alloc.x + slider_alloc.width / 4; - min_pos = min_pos_after; - max_pos = find_next_pos (widget, m, marks + i, GTK_POS_BOTTOM) - min_sep; + x3 = x2 + value_spacing; + min_pos_after = y3 + logical_rect.height + min_sep; } - y1 = marks[i]; - - gtk_render_line (context, cr, x1, y1, x2, y1); - if (mark->markup) - { - 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 < 0) - y3 = 0; - if (mark->position == GTK_POS_TOP) - { - 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_render_layout (context, cr, x3, y3, layout); - } + gtk_render_layout (context, cr, x3, y3, layout); } - - gtk_style_context_restore (context); } - g_object_unref (layout); - g_free (marks); + gtk_style_context_restore (context); } + g_object_unref (layout); + g_free (marks); + + return FALSE; +} + +static gboolean +gtk_scale_draw (GtkWidget *widget, + cairo_t *cr) +{ + GtkScale *scale = GTK_SCALE (widget); + GtkScalePrivate *priv = scale->priv; + + if (priv->top_marks_gadget) + gtk_css_gadget_draw (priv->top_marks_gadget, cr); + if (priv->bottom_marks_gadget) + gtk_css_gadget_draw (priv->bottom_marks_gadget, cr); + GTK_WIDGET_CLASS (gtk_scale_parent_class)->draw (widget, cr); if (priv->draw_value) { GtkAllocation allocation; - + GtkStyleContext *context; PangoLayout *layout; gint x, y; + context = gtk_widget_get_style_context (widget); layout = gtk_scale_get_layout (scale); gtk_scale_get_layout_offsets (scale, &x, &y); gtk_widget_get_allocation (widget, &allocation); @@ -1812,7 +1828,7 @@ gtk_scale_add_mark (GtkScale *scale, GTK_WIDGET (scale), NULL, NULL, gtk_scale_measure_marks, NULL, - NULL, + gtk_scale_render_marks, NULL, NULL); gtk_css_node_insert_after (widget_node, gtk_css_gadget_get_node (priv->top_marks_gadget), NULL); gtk_css_gadget_add_class (priv->top_marks_gadget, GTK_STYLE_CLASS_TOP); @@ -1829,7 +1845,7 @@ gtk_scale_add_mark (GtkScale *scale, GTK_WIDGET (scale), NULL, NULL, gtk_scale_measure_marks, NULL, - NULL, + gtk_scale_render_marks, NULL, NULL); gtk_css_node_insert_before (widget_node, gtk_css_gadget_get_node (priv->bottom_marks_gadget), NULL); gtk_css_gadget_add_class (priv->bottom_marks_gadget, GTK_STYLE_CLASS_BOTTOM); |