Commit e73a2e56 authored by Matthias Clasen's avatar Matthias Clasen

Add context to detail strings when drawing steppers

As usual, this is protected by a style property:
GtkRange::stepper-position-details
The detail strings are
<detail>_start, <detail>_end and <detail>_middle.

See bug 621250
parent 53796b7f
...@@ -92,6 +92,13 @@ typedef enum { ...@@ -92,6 +92,13 @@ typedef enum {
MOUSE_WIDGET /* inside widget but not in any of the above GUI elements */ MOUSE_WIDGET /* inside widget but not in any of the above GUI elements */
} MouseLocation; } MouseLocation;
typedef enum {
STEPPER_A,
STEPPER_B,
STEPPER_C,
STEPPER_D
} Stepper;
#define GTK_RANGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RANGE, GtkRangeLayout)) #define GTK_RANGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RANGE, GtkRangeLayout))
struct _GtkRangeLayout struct _GtkRangeLayout
...@@ -108,7 +115,7 @@ struct _GtkRangeLayout ...@@ -108,7 +115,7 @@ struct _GtkRangeLayout
GdkRectangle slider; GdkRectangle slider;
/* Layout-related state */ /* Layout-related state */
MouseLocation mouse_location; MouseLocation mouse_location;
/* last mouse coords we got, or -1 if mouse is outside the range */ /* last mouse coords we got, or -1 if mouse is outside the range */
gint mouse_x; gint mouse_x;
...@@ -133,8 +140,8 @@ struct _GtkRangeLayout ...@@ -133,8 +140,8 @@ struct _GtkRangeLayout
gdouble fill_level; gdouble fill_level;
GQuark slider_detail_quark; GQuark slider_detail_quark;
GQuark stepper_detail_quark; GQuark stepper_detail_quark[4];
gdouble *marks; gdouble *marks;
gint *mark_pos; gint *mark_pos;
gint n_marks; gint n_marks;
...@@ -584,6 +591,21 @@ gtk_range_class_init (GtkRangeClass *class) ...@@ -584,6 +591,21 @@ gtk_range_class_init (GtkRangeClass *class)
0.0, 1.0, 0.5, 0.0, 1.0, 0.5,
GTK_PARAM_READABLE)); GTK_PARAM_READABLE));
/**
* GtkRange:stepper-position-details:
*
* When %TRUE, the detail string for rendering the steppers will be
* suffixed with information about the stepper position.
*
* Since: 2.22
*/
gtk_widget_class_install_style_property (widget_class,
g_param_spec_boolean ("stepper-position-details",
P_("Stepper Position Details"),
P_("When TRUE, the detail string for rendering the steppers is suffixed with position information"),
FALSE,
GTK_PARAM_READABLE));
g_type_class_add_private (class, sizeof (GtkRangeLayout)); g_type_class_add_private (class, sizeof (GtkRangeLayout));
} }
...@@ -601,7 +623,10 @@ gtk_range_set_property (GObject *object, ...@@ -601,7 +623,10 @@ gtk_range_set_property (GObject *object,
range->orientation = g_value_get_enum (value); range->orientation = g_value_get_enum (value);
range->layout->slider_detail_quark = 0; range->layout->slider_detail_quark = 0;
range->layout->stepper_detail_quark = 0; range->layout->stepper_detail_quark[0] = 0;
range->layout->stepper_detail_quark[1] = 0;
range->layout->stepper_detail_quark[2] = 0;
range->layout->stepper_detail_quark[3] = 0;
gtk_widget_queue_resize (GTK_WIDGET (range)); gtk_widget_queue_resize (GTK_WIDGET (range));
break; break;
...@@ -1608,26 +1633,66 @@ gtk_range_get_slider_detail (GtkRange *range) ...@@ -1608,26 +1633,66 @@ gtk_range_get_slider_detail (GtkRange *range)
} }
static const gchar * static const gchar *
gtk_range_get_stepper_detail (GtkRange *range) gtk_range_get_stepper_detail (GtkRange *range,
Stepper stepper)
{ {
const gchar *stepper_detail; const gchar *stepper_detail;
gboolean need_orientation;
gboolean need_position;
if (range->layout->stepper_detail_quark) if (range->layout->stepper_detail_quark[stepper])
return g_quark_to_string (range->layout->stepper_detail_quark); return g_quark_to_string (range->layout->stepper_detail_quark[stepper]);
stepper_detail = GTK_RANGE_GET_CLASS (range)->stepper_detail; stepper_detail = GTK_RANGE_GET_CLASS (range)->stepper_detail;
if (stepper_detail && stepper_detail[0] == 'X') need_orientation = stepper_detail && stepper_detail[0] == 'X';
gtk_widget_style_get (GTK_WIDGET (range),
"stepper-position-details", &need_position,
NULL);
if (need_orientation || need_position)
{ {
gchar *detail = g_strdup (stepper_detail); gchar *detail;
const gchar *position = NULL;
detail[0] = range->orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; if (need_position)
{
switch (stepper)
{
case STEPPER_A:
position = "_start";
break;
case STEPPER_B:
if (range->has_stepper_a)
position = "_middle";
else
position = "_start";
break;
case STEPPER_C:
if (range->has_stepper_d)
position = "_middle";
else
position = "_end";
break;
case STEPPER_D:
position = "_end";
break;
default:
g_assert_not_reached ();
}
}
detail = g_strconcat (stepper_detail, position, NULL);
if (need_orientation)
detail[0] = range->orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v';
range->layout->stepper_detail_quark = g_quark_from_string (detail); range->layout->stepper_detail_quark[stepper] = g_quark_from_string (detail);
g_free (detail); g_free (detail);
return g_quark_to_string (range->layout->stepper_detail_quark); return g_quark_to_string (range->layout->stepper_detail_quark[stepper]);
} }
return stepper_detail; return stepper_detail;
...@@ -1635,7 +1700,7 @@ gtk_range_get_stepper_detail (GtkRange *range) ...@@ -1635,7 +1700,7 @@ gtk_range_get_stepper_detail (GtkRange *range)
static void static void
draw_stepper (GtkRange *range, draw_stepper (GtkRange *range,
GdkRectangle *rect, Stepper stepper,
GtkArrowType arrow_type, GtkArrowType arrow_type,
gboolean clicked, gboolean clicked,
gboolean prelighted, gboolean prelighted,
...@@ -1646,12 +1711,30 @@ draw_stepper (GtkRange *range, ...@@ -1646,12 +1711,30 @@ draw_stepper (GtkRange *range,
GdkRectangle intersection; GdkRectangle intersection;
GtkWidget *widget = GTK_WIDGET (range); GtkWidget *widget = GTK_WIDGET (range);
gfloat arrow_scaling; gfloat arrow_scaling;
GdkRectangle *rect;
gint arrow_x; gint arrow_x;
gint arrow_y; gint arrow_y;
gint arrow_width; gint arrow_width;
gint arrow_height; gint arrow_height;
switch (stepper)
{
case STEPPER_A:
rect = &range->layout->stepper_a;
break;
case STEPPER_B:
rect = &range->layout->stepper_b;
break;
case STEPPER_C:
rect = &range->layout->stepper_c;
break;
case STEPPER_D:
rect = &range->layout->stepper_d;
break;
default:
g_assert_not_reached ();
};
gboolean arrow_sensitive = TRUE; gboolean arrow_sensitive = TRUE;
/* More to get the right clip region than for efficiency */ /* More to get the right clip region than for efficiency */
...@@ -1691,7 +1774,7 @@ draw_stepper (GtkRange *range, ...@@ -1691,7 +1774,7 @@ draw_stepper (GtkRange *range,
widget->window, widget->window,
state_type, shadow_type, state_type, shadow_type,
&intersection, widget, &intersection, widget,
gtk_range_get_stepper_detail (range), gtk_range_get_stepper_detail (range, stepper),
widget->allocation.x + rect->x, widget->allocation.x + rect->x,
widget->allocation.y + rect->y, widget->allocation.y + rect->y,
rect->width, rect->width,
...@@ -1719,9 +1802,9 @@ draw_stepper (GtkRange *range, ...@@ -1719,9 +1802,9 @@ draw_stepper (GtkRange *range,
gtk_paint_arrow (widget->style, gtk_paint_arrow (widget->style,
widget->window, widget->window,
state_type, shadow_type, state_type, shadow_type,
&intersection, widget, &intersection, widget,
gtk_range_get_stepper_detail (range), gtk_range_get_stepper_detail (range, stepper),
arrow_type, arrow_type,
TRUE, TRUE,
arrow_x, arrow_y, arrow_width, arrow_height); arrow_x, arrow_y, arrow_width, arrow_height);
...@@ -2002,28 +2085,28 @@ gtk_range_expose (GtkWidget *widget, ...@@ -2002,28 +2085,28 @@ gtk_range_expose (GtkWidget *widget,
} }
if (range->has_stepper_a) if (range->has_stepper_a)
draw_stepper (range, &range->layout->stepper_a, draw_stepper (range, STEPPER_A,
range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT, range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
range->layout->grab_location == MOUSE_STEPPER_A, range->layout->grab_location == MOUSE_STEPPER_A,
!touchscreen && range->layout->mouse_location == MOUSE_STEPPER_A, !touchscreen && range->layout->mouse_location == MOUSE_STEPPER_A,
&expose_area); &expose_area);
if (range->has_stepper_b) if (range->has_stepper_b)
draw_stepper (range, &range->layout->stepper_b, draw_stepper (range, STEPPER_B,
range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT, range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
range->layout->grab_location == MOUSE_STEPPER_B, range->layout->grab_location == MOUSE_STEPPER_B,
!touchscreen && range->layout->mouse_location == MOUSE_STEPPER_B, !touchscreen && range->layout->mouse_location == MOUSE_STEPPER_B,
&expose_area); &expose_area);
if (range->has_stepper_c) if (range->has_stepper_c)
draw_stepper (range, &range->layout->stepper_c, draw_stepper (range, STEPPER_C,
range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT, range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
range->layout->grab_location == MOUSE_STEPPER_C, range->layout->grab_location == MOUSE_STEPPER_C,
!touchscreen && range->layout->mouse_location == MOUSE_STEPPER_C, !touchscreen && range->layout->mouse_location == MOUSE_STEPPER_C,
&expose_area); &expose_area);
if (range->has_stepper_d) if (range->has_stepper_d)
draw_stepper (range, &range->layout->stepper_d, draw_stepper (range, STEPPER_D,
range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT, range->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
range->layout->grab_location == MOUSE_STEPPER_D, range->layout->grab_location == MOUSE_STEPPER_D,
!touchscreen && range->layout->mouse_location == MOUSE_STEPPER_D, !touchscreen && range->layout->mouse_location == MOUSE_STEPPER_D,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment