Add has-origin property for GtkScale

If the scale has an origin (it will have one by default), GtkRange will
render the two sides before/after the current value with different style
classes, making it possible for themes to use different colors and
properties for the two areas.
This was possible in GTK 2 with style details, but got lost during the
road to 3.0.

https://bugzilla.gnome.org/show_bug.cgi?id=665140
This commit is contained in:
Andrea Cimitan 2011-12-14 17:16:09 +01:00 committed by Cosimo Cecchi
parent 8c1f8c0668
commit 40423df234
6 changed files with 167 additions and 27 deletions

View File

@ -2820,9 +2820,11 @@ gtk_scale_new
gtk_scale_new_with_range
gtk_scale_set_digits
gtk_scale_set_draw_value
gtk_scale_set_has_origin
gtk_scale_set_value_pos
gtk_scale_get_digits
gtk_scale_get_draw_value
gtk_scale_get_has_origin
gtk_scale_get_value_pos
gtk_scale_get_layout
gtk_scale_get_layout_offsets

View File

@ -2300,6 +2300,7 @@ gtk_scale_button_set_value
gtk_scale_clear_marks
gtk_scale_get_digits
gtk_scale_get_draw_value
gtk_scale_get_has_origin
gtk_scale_get_layout
gtk_scale_get_layout_offsets
gtk_scale_get_type
@ -2308,6 +2309,7 @@ gtk_scale_new
gtk_scale_new_with_range
gtk_scale_set_digits
gtk_scale_set_draw_value
gtk_scale_set_has_origin
gtk_scale_set_value_pos
gtk_scrollable_get_hadjustment
gtk_scrollable_get_hscroll_policy

View File

@ -137,6 +137,9 @@ struct _GtkRangePrivate
guint lower_sensitive : 1;
guint upper_sensitive : 1;
/* The range has an origin, should be drawn differently. Used by GtkScale */
guint has_origin : 1;
/* Fill level */
guint show_fill_level : 1;
guint restrict_to_fill_level : 1;
@ -736,6 +739,7 @@ gtk_range_init (GtkRange *range)
priv->upper_sensitivity = GTK_SENSITIVITY_AUTO;
priv->lower_sensitive = TRUE;
priv->upper_sensitive = TRUE;
priv->has_origin = FALSE;
priv->show_fill_level = FALSE;
priv->restrict_to_fill_level = TRUE;
priv->fill_level = G_MAXDOUBLE;
@ -2109,37 +2113,82 @@ gtk_range_draw (GtkWidget *widget,
if (draw_trough)
{
gint trough_change_pos_x = width;
gint trough_change_pos_y = height;
if (!priv->has_origin)
{
gtk_render_background (context, cr,
x, y, width, height);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
trough_change_pos_x = (priv->slider.x +
priv->slider.width / 2 -
x);
gtk_render_frame (context, cr,
x, y, width, height);
}
else
trough_change_pos_y = (priv->slider.y +
priv->slider.height / 2 -
y);
{
gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
/* FIXME: was trough-upper and trough-lower really used,
* in that case, it should still be exposed somehow.
*/
gtk_render_background (context, cr, x, y,
trough_change_pos_x,
trough_change_pos_y);
gint trough_change_pos_x = width;
gint trough_change_pos_y = height;
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
trough_change_pos_y = 0;
else
trough_change_pos_x = 0;
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
trough_change_pos_x = (priv->slider.x +
priv->slider.width / 2 -
x);
else
trough_change_pos_y = (priv->slider.y +
priv->slider.height / 2 -
y);
gtk_render_background (context, cr,
x + trough_change_pos_x, y + trough_change_pos_y,
width - trough_change_pos_x,
height - trough_change_pos_y);
gtk_style_context_save (context);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
gtk_render_frame (context, cr,
x, y, width, height);
if (!is_rtl)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
}
else
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
gtk_render_background (context, cr, x, y,
trough_change_pos_x,
trough_change_pos_y);
gtk_render_frame (context, cr, x, y,
trough_change_pos_x,
trough_change_pos_y);
gtk_style_context_restore (context);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
trough_change_pos_y = 0;
else
trough_change_pos_x = 0;
gtk_style_context_save (context);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
if (is_rtl)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
}
else
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
}
gtk_render_background (context, cr,
x + trough_change_pos_x, y + trough_change_pos_y,
width - trough_change_pos_x,
height - trough_change_pos_y);
gtk_render_frame (context, cr,
x + trough_change_pos_x, y + trough_change_pos_y,
width - trough_change_pos_x,
height - trough_change_pos_y);
gtk_style_context_restore (context);
}
}
else
{
@ -4062,6 +4111,19 @@ gtk_range_remove_step_timer (GtkRange *range)
}
}
void
_gtk_range_set_has_origin (GtkRange *range,
gboolean has_origin)
{
range->priv->has_origin = has_origin;
}
gboolean
_gtk_range_get_has_origin (GtkRange *range)
{
return range->priv->has_origin;
}
void
_gtk_range_set_stop_values (GtkRange *range,
gdouble *values,

View File

@ -150,7 +150,9 @@ gint gtk_range_get_round_digits (GtkRange *rang
/* internal API */
gdouble _gtk_range_get_wheel_delta (GtkRange *range,
GdkScrollDirection direction);
void _gtk_range_set_has_origin (GtkRange *range,
gboolean has_origin);
gboolean _gtk_range_get_has_origin (GtkRange *range);
void _gtk_range_set_stop_values (GtkRange *range,
gdouble *values,
gint n_values);

View File

@ -104,6 +104,7 @@ enum {
PROP_0,
PROP_DIGITS,
PROP_DRAW_VALUE,
PROP_HAS_ORIGIN,
PROP_VALUE_POS
};
@ -248,7 +249,15 @@ gtk_scale_class_init (GtkScaleClass *class)
P_("Whether the current value is displayed as a string next to the slider"),
TRUE,
GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_HAS_ORIGIN,
g_param_spec_boolean ("has-origin",
P_("Has Origin"),
P_("Whether the scale has an origin"),
TRUE,
GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_VALUE_POS,
g_param_spec_enum ("value-pos",
@ -426,6 +435,8 @@ gtk_scale_init (GtkScale *scale)
gtk_range_set_slider_size_fixed (range, TRUE);
_gtk_range_set_has_origin (range, TRUE);
priv->draw_value = TRUE;
priv->value_pos = GTK_POS_TOP;
priv->digits = 1;
@ -458,6 +469,9 @@ gtk_scale_set_property (GObject *object,
case PROP_DRAW_VALUE:
gtk_scale_set_draw_value (scale, g_value_get_boolean (value));
break;
case PROP_HAS_ORIGIN:
gtk_scale_set_has_origin (scale, g_value_get_boolean (value));
break;
case PROP_VALUE_POS:
gtk_scale_set_value_pos (scale, g_value_get_enum (value));
break;
@ -484,6 +498,9 @@ gtk_scale_get_property (GObject *object,
case PROP_DRAW_VALUE:
g_value_set_boolean (value, priv->draw_value);
break;
case PROP_HAS_ORIGIN:
g_value_set_boolean (value, gtk_scale_get_has_origin (scale));
break;
case PROP_VALUE_POS:
g_value_set_enum (value, priv->value_pos);
break;
@ -677,6 +694,58 @@ gtk_scale_get_draw_value (GtkScale *scale)
return scale->priv->draw_value;
}
/**
* gtk_scale_set_has_origin:
* @scale: a #GtkScale
* @has_origin: %TRUE if the scale has an origin
*
* If @has_origin is set to %TRUE (the default),
* the scale will highlight the part of the scale
* between the origin (bottom or left side) of the scale
* and the current value.
*
* Since: 3.4
*/
void
gtk_scale_set_has_origin (GtkScale *scale,
gboolean has_origin)
{
GtkScalePrivate *priv;
g_return_if_fail (GTK_IS_SCALE (scale));
priv = scale->priv;
has_origin = has_origin != FALSE;
if (_gtk_range_get_has_origin (GTK_RANGE (scale)) != has_origin)
{
_gtk_range_set_has_origin (GTK_RANGE (scale), has_origin);
gtk_widget_queue_draw (GTK_WIDGET (scale));
g_object_notify (G_OBJECT (scale), "has-origin");
}
}
/**
* gtk_scale_get_has_origin:
* @scale: a #GtkScale
*
* Returns whether the scale has an origin.
*
* Returns: %TRUE if the scale has an origin.
*
* Since: 3.4
*/
gboolean
gtk_scale_get_has_origin (GtkScale *scale)
{
g_return_val_if_fail (GTK_IS_SCALE (scale), FALSE);
return _gtk_range_get_has_origin (GTK_RANGE (scale));
}
/**
* gtk_scale_set_value_pos:
* @scale: a #GtkScale

View File

@ -90,6 +90,9 @@ gint gtk_scale_get_digits (GtkScale *scale);
void gtk_scale_set_draw_value (GtkScale *scale,
gboolean draw_value);
gboolean gtk_scale_get_draw_value (GtkScale *scale);
void gtk_scale_set_has_origin (GtkScale *scale,
gboolean has_origin);
gboolean gtk_scale_get_has_origin (GtkScale *scale);
void gtk_scale_set_value_pos (GtkScale *scale,
GtkPositionType pos);
GtkPositionType gtk_scale_get_value_pos (GtkScale *scale);