Fix for #104811, Padraig O'Briain:

Fri Feb 13 00:54:59 2004  Matthias Clasen  <maclas@gmx.de>

	Fix for #104811, Padraig O'Briain:

	* gtk/gtkscale.h:
	* gtk/gtkscale.c (_gtk_scale_clear_layout):
	* gtk/gtkscale.c (gtk_scale_get_layout_offsets):
	* gtk/gtkscale.c (gtk_scale_get_layout): New functions to determine the
	text and its position from a GtkScale, to make it more accessible.
	* gtk/gtkhscale.c (gtk_hscale_get_layout_offsets):
	* gtk/gtkvscale.c (gtk_vscale_get_layout_offsets): Implementations of the
	new GtkScale vfunc.
This commit is contained in:
Matthias Clasen
2004-02-12 23:58:46 +00:00
committed by Matthias Clasen
parent 0c4c9f0d1c
commit f6a32cf0d1
11 changed files with 365 additions and 108 deletions

View File

@ -1,3 +1,16 @@
Fri Feb 13 00:54:59 2004 Matthias Clasen <maclas@gmx.de>
Fix for #104811, Padraig O'Briain:
* gtk/gtkscale.h:
* gtk/gtkscale.c (_gtk_scale_clear_layout):
* gtk/gtkscale.c (gtk_scale_get_layout_offsets):
* gtk/gtkscale.c (gtk_scale_get_layout): New functions to determine the
text and its position from a GtkScale, to make it more accessible.
* gtk/gtkhscale.c (gtk_hscale_get_layout_offsets):
* gtk/gtkvscale.c (gtk_vscale_get_layout_offsets): Implementations of the
new GtkScale vfunc.
Thu Feb 12 17:59:52 2004 Owen Taylor <otaylor@redhat.com>
* gtk/gtkicontheme.c (gtk_icon_theme_get_search_path):

View File

@ -1,3 +1,16 @@
Fri Feb 13 00:54:59 2004 Matthias Clasen <maclas@gmx.de>
Fix for #104811, Padraig O'Briain:
* gtk/gtkscale.h:
* gtk/gtkscale.c (_gtk_scale_clear_layout):
* gtk/gtkscale.c (gtk_scale_get_layout_offsets):
* gtk/gtkscale.c (gtk_scale_get_layout): New functions to determine the
text and its position from a GtkScale, to make it more accessible.
* gtk/gtkhscale.c (gtk_hscale_get_layout_offsets):
* gtk/gtkvscale.c (gtk_vscale_get_layout_offsets): Implementations of the
new GtkScale vfunc.
Thu Feb 12 17:59:52 2004 Owen Taylor <otaylor@redhat.com>
* gtk/gtkicontheme.c (gtk_icon_theme_get_search_path):

View File

@ -1,3 +1,16 @@
Fri Feb 13 00:54:59 2004 Matthias Clasen <maclas@gmx.de>
Fix for #104811, Padraig O'Briain:
* gtk/gtkscale.h:
* gtk/gtkscale.c (_gtk_scale_clear_layout):
* gtk/gtkscale.c (gtk_scale_get_layout_offsets):
* gtk/gtkscale.c (gtk_scale_get_layout): New functions to determine the
text and its position from a GtkScale, to make it more accessible.
* gtk/gtkhscale.c (gtk_hscale_get_layout_offsets):
* gtk/gtkvscale.c (gtk_vscale_get_layout_offsets): Implementations of the
new GtkScale vfunc.
Thu Feb 12 17:59:52 2004 Owen Taylor <otaylor@redhat.com>
* gtk/gtkicontheme.c (gtk_icon_theme_get_search_path):

View File

@ -1,3 +1,16 @@
Fri Feb 13 00:54:59 2004 Matthias Clasen <maclas@gmx.de>
Fix for #104811, Padraig O'Briain:
* gtk/gtkscale.h:
* gtk/gtkscale.c (_gtk_scale_clear_layout):
* gtk/gtkscale.c (gtk_scale_get_layout_offsets):
* gtk/gtkscale.c (gtk_scale_get_layout): New functions to determine the
text and its position from a GtkScale, to make it more accessible.
* gtk/gtkhscale.c (gtk_hscale_get_layout_offsets):
* gtk/gtkvscale.c (gtk_vscale_get_layout_offsets): Implementations of the
new GtkScale vfunc.
Thu Feb 12 17:59:52 2004 Owen Taylor <otaylor@redhat.com>
* gtk/gtkicontheme.c (gtk_icon_theme_get_search_path):

View File

@ -1,3 +1,16 @@
Fri Feb 13 00:54:59 2004 Matthias Clasen <maclas@gmx.de>
Fix for #104811, Padraig O'Briain:
* gtk/gtkscale.h:
* gtk/gtkscale.c (_gtk_scale_clear_layout):
* gtk/gtkscale.c (gtk_scale_get_layout_offsets):
* gtk/gtkscale.c (gtk_scale_get_layout): New functions to determine the
text and its position from a GtkScale, to make it more accessible.
* gtk/gtkhscale.c (gtk_hscale_get_layout_offsets):
* gtk/gtkvscale.c (gtk_vscale_get_layout_offsets): Implementations of the
new GtkScale vfunc.
Thu Feb 12 17:59:52 2004 Owen Taylor <otaylor@redhat.com>
* gtk/gtkicontheme.c (gtk_icon_theme_get_search_path):

View File

@ -1,3 +1,8 @@
Fri Feb 13 00:54:24 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtk-sections.txt: Add gtk_scale_get_layout
and gtk_scale_get_layout_offsets.
Thu Feb 12 23:56:12 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtk-sections.txt: Add gtk_tooltips_get_info_from_tip_window.

View File

@ -2476,6 +2476,8 @@ gtk_scale_set_value_pos
gtk_scale_get_digits
gtk_scale_get_draw_value
gtk_scale_get_value_pos
gtk_scale_get_layout
gtk_scale_get_layout_offsets
<SUBSECTION Standard>
GTK_SCALE
GTK_IS_SCALE

View File

@ -37,6 +37,10 @@ static void gtk_hscale_init (GtkHScale *hscale);
static gboolean gtk_hscale_expose (GtkWidget *widget,
GdkEventExpose *event);
static void gtk_hscale_get_layout_offsets (GtkScale *scale,
gint *x,
gint *y);
GType
gtk_hscale_get_type (void)
{
@ -69,13 +73,17 @@ gtk_hscale_class_init (GtkHScaleClass *class)
{
GtkWidgetClass *widget_class;
GtkRangeClass *range_class;
GtkScaleClass *scale_class;
widget_class = GTK_WIDGET_CLASS (class);
range_class = GTK_RANGE_CLASS (class);
scale_class = GTK_SCALE_CLASS (class);
parent_class = g_type_class_peek_parent (class);
range_class->slider_detail = "hscale";
scale_class->get_layout_offsets = gtk_hscale_get_layout_offsets;
widget_class->expose_event = gtk_hscale_expose;
}
@ -145,13 +153,9 @@ static gboolean
gtk_hscale_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GtkRange *range;
GtkHScale *hscale;
GtkScale *scale;
range = GTK_RANGE (widget);
scale = GTK_SCALE (widget);
hscale = GTK_HSCALE (widget);
/* We need to chain up _first_ so the various geometry members of
* GtkRange struct are updated.
@ -162,58 +166,12 @@ gtk_hscale_expose (GtkWidget *widget,
if (scale->draw_value)
{
PangoLayout *layout;
PangoRectangle logical_rect;
gchar *txt;
gint x, y;
GtkStateType state_type;
gint value_spacing;
gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
txt = _gtk_scale_format_value (scale,
GTK_RANGE (scale)->adjustment->value);
layout = gtk_widget_create_pango_layout (widget, txt);
g_free (txt);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
switch (scale->value_pos)
{
case GTK_POS_LEFT:
x = range->range_rect.x - value_spacing - logical_rect.width;
y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
break;
case GTK_POS_RIGHT:
x = range->range_rect.x + range->range_rect.width + value_spacing;
y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
break;
case GTK_POS_TOP:
x = range->slider_start +
(range->slider_end - range->slider_start - logical_rect.width) / 2;
x = CLAMP (x, 0, widget->allocation.width - logical_rect.width);
y = range->range_rect.y - logical_rect.height - value_spacing;
break;
case GTK_POS_BOTTOM:
x = range->slider_start +
(range->slider_end - range->slider_start - logical_rect.width) / 2;
x = CLAMP (x, 0, widget->allocation.width - logical_rect.width);
y = range->range_rect.y + range->range_rect.height + value_spacing;
break;
layout = gtk_scale_get_layout (scale);
gtk_scale_get_layout_offsets (scale, &x, &y);
default:
g_return_val_if_reached (FALSE);
x = 0;
y = 0;
break;
}
x += widget->allocation.x;
y += widget->allocation.y;
state_type = GTK_STATE_NORMAL;
if (!GTK_WIDGET_IS_SENSITIVE (scale))
state_type = GTK_STATE_INSENSITIVE;
@ -228,8 +186,74 @@ gtk_hscale_expose (GtkWidget *widget,
x, y,
layout);
g_object_unref (layout);
}
return FALSE;
}
static void
gtk_hscale_get_layout_offsets (GtkScale *scale,
gint *x,
gint *y)
{
GtkWidget *widget;
GtkRange *range;
GtkScale *scale;
PangoLayout *layout;
PangoRectangle logical_rect;
gint value_spacing;
widget = GTK_WIDGET (scale);
layout = gtk_scale_get_layout (scale);
if (!layout)
{
*x = 0;
*y = 0;
return;
}
gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
range = GTK_RANGE (widget);
scale = GTK_SCALE (widget);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
switch (scale->value_pos)
{
case GTK_POS_LEFT:
*x = range->range_rect.x - value_spacing - logical_rect.width;
*y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
break;
case GTK_POS_RIGHT:
*x = range->range_rect.x + range->range_rect.width + value_spacing;
*y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
break;
case GTK_POS_TOP:
*x = range->slider_start +
(range->slider_end - range->slider_start - logical_rect.width) / 2;
*x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width);
*y = range->range_rect.y - logical_rect.height - value_spacing;
break;
case GTK_POS_BOTTOM:
*x = range->slider_start +
(range->slider_end - range->slider_start - logical_rect.width) / 2;
*x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width);
*y = range->range_rect.y + range->range_rect.height + value_spacing;
break;
default:
g_return_val_if_reached (FALSE);
*x = 0;
*y = 0;
break;
}
*x += widget->allocation.x;
*y += widget->allocation.y;
}

View File

@ -39,6 +39,15 @@
* unrelated code portions otherwise
*/
#define GTK_SCALE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_SCALE, GtkScalePrivate))
typedef struct _GtkScalePrivate GtkScalePrivate;
struct _GtkScalePrivate
{
PangoLayout *layout;
};
enum {
PROP_0,
PROP_DIGITS,
@ -68,6 +77,9 @@ static void gtk_scale_style_set (GtkWidget *widget,
GtkStyle *previous);
static void gtk_scale_get_range_border (GtkRange *range,
GtkBorder *border);
static void gtk_scale_finalize (GObject *object);
static void gtk_scale_screen_changed (GtkWidget *widget,
GdkScreen *old_screen);
GType
gtk_scale_get_type (void)
@ -135,8 +147,10 @@ gtk_scale_class_init (GtkScaleClass *class)
gobject_class->set_property = gtk_scale_set_property;
gobject_class->get_property = gtk_scale_get_property;
gobject_class->finalize = gtk_scale_finalize;
widget_class->style_set = gtk_scale_style_set;
widget_class->screen_changed = gtk_scale_screen_changed;
range_class->get_range_border = gtk_scale_get_range_border;
@ -312,6 +326,8 @@ gtk_scale_class_init (GtkScaleClass *class)
add_slider_binding (binding_set, GDK_KP_End, 0,
GTK_SCROLL_END);
g_type_class_add_private (gobject_class, sizeof (GtkScalePrivate));
}
static void
@ -407,6 +423,7 @@ gtk_scale_set_digits (GtkScale *scale,
if (scale->draw_value)
range->round_digits = digits;
_gtk_scale_clear_layout (scale);
gtk_widget_queue_resize (GTK_WIDGET (scale));
g_object_notify (G_OBJECT (scale), "digits");
@ -437,6 +454,8 @@ gtk_scale_set_draw_value (GtkScale *scale,
else
GTK_RANGE (scale)->round_digits = -1;
_gtk_scale_clear_layout (scale);
gtk_widget_queue_resize (GTK_WIDGET (scale));
g_object_notify (G_OBJECT (scale), "draw_value");
@ -461,6 +480,7 @@ gtk_scale_set_value_pos (GtkScale *scale,
{
scale->value_pos = pos;
_gtk_scale_clear_layout (scale);
if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
gtk_widget_queue_resize (GTK_WIDGET (scale));
@ -586,9 +606,17 @@ gtk_scale_style_set (GtkWidget *widget,
range->min_slider_size = slider_length;
_gtk_scale_clear_layout (GTK_SCALE (widget));
(* GTK_WIDGET_CLASS (parent_class)->style_set) (widget, previous);
}
static void
gtk_scale_screen_changed (GtkWidget *widget,
GdkScreen *old_screen)
{
_gtk_scale_clear_layout (GTK_SCALE (widget));
}
/**
* _gtk_scale_format_value:
@ -618,3 +646,103 @@ _gtk_scale_format_value (GtkScale *scale,
return g_strdup_printf ("%0.*f", scale->digits,
value);
}
static void
gtk_scale_finalize (GObject *object)
{
GtkScale *scale;
g_return_if_fail (GTK_IS_SCALE (object));
scale = GTK_SCALE (object);
_gtk_scale_clear_layout (scale);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* gtk_scale_get_layout:
* @scale: A #GtkScale
*
* Gets the #PangoLayout used to display the scale. The returned object
* is owned by the scale so does not need to be freed by the caller.
*
* Return value: the #PangoLayout for this scale, or %NULL if the draw_value property
* is %FALSE.
*
* Since: 2.4
**/
PangoLayout *
gtk_scale_get_layout (GtkScale *scale)
{
GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale);
gchar *txt;
g_return_val_if_fail (GTK_IS_SCALE (scale), NULL);
if (!priv->layout)
{
if (scale->draw_value)
priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
}
if (scale->draw_value)
{
txt = _gtk_scale_format_value (scale,
GTK_RANGE (scale)->adjustment->value);
pango_layout_set_text (priv->layout, txt, -1);
g_free (txt);
}
return priv->layout;
}
/**
* gtk_scale_get_layout_offsets:
* @scale: a #GtkScale
* @x: location to store X offset of layout, or %NULL
* @y: location to store Y offset of layout, or %NULL
*
* Obtains the coordinates where the scale will draw the #PangoLayout
* representing the text in the scale. Remember
* when using the #PangoLayout function you need to convert to
* and from pixels using PANGO_PIXELS() or #PANGO_SCALE.
*
* If the draw_value property is %FALSE, the return values are
* undefined.
*
* Since: 2.4
**/
void
gtk_scale_get_layout_offsets (GtkScale *scale,
gint *x,
gint *y)
{
gint local_x, local_y;
g_return_val_if_fail (GTK_IS_SCALE (scale), NULL);
if (GTK_SCALE_GET_CLASS (scale)->get_layout_offsets)
(GTK_SCALE_GET_CLASS (scale)->get_layout_offsets) (scale, &local_x, &local_y);
if (x)
*x = local_x;
if (y)
*y = local_y;
}
void _gtk_scale_clear_layout (GtkScale *scale)
{
GtkScalePrivate *priv = GTK_SCALE_GET_PRIVATE (scale);
g_return_if_fail (GTK_IS_SCALE (scale));
if (priv->layout)
{
g_object_unref (priv->layout);
priv->layout = NULL;
}
}

View File

@ -66,8 +66,10 @@ struct _GtkScaleClass
void (* draw_value) (GtkScale *scale);
void (* get_layout_offsets) (GtkScale *scale,
gint *x,
gint *y);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
@ -85,12 +87,18 @@ void gtk_scale_set_value_pos (GtkScale *scale,
GtkPositionType pos);
GtkPositionType gtk_scale_get_value_pos (GtkScale *scale);
PangoLayout *gtk_scale_get_layout (GtkScale *scale);
void gtk_scale_get_layout_offsets (GtkScale *scale,
gint *x,
gint *y);
void _gtk_scale_clear_layout (GtkScale *scale);
void _gtk_scale_get_value_size (GtkScale *scale,
gint *width,
gint *height);
gchar *_gtk_scale_format_value (GtkScale *scale,
gdouble value);
gchar *_gtk_scale_format_value (GtkScale *scale,
gdouble value);
#ifdef __cplusplus
}

View File

@ -39,6 +39,10 @@ static void gtk_vscale_init (GtkVScale *vscale);
static gboolean gtk_vscale_expose (GtkWidget *widget,
GdkEventExpose *event);
static void gtk_vscale_get_layout_offsets (GtkScale *scale,
gint *x,
gint *y);
GType
gtk_vscale_get_type (void)
{
@ -71,14 +75,18 @@ gtk_vscale_class_init (GtkVScaleClass *class)
{
GtkWidgetClass *widget_class;
GtkRangeClass *range_class;
GtkScaleClass *scale_class;
widget_class = GTK_WIDGET_CLASS (class);
range_class = GTK_RANGE_CLASS (class);
scale_class = GTK_SCALE_CLASS (class);
parent_class = g_type_class_peek_parent (class);
range_class->slider_detail = "vscale";
scale_class->get_layout_offsets = gtk_vscale_get_layout_offsets;
widget_class->expose_event = gtk_vscale_expose;
}
@ -147,13 +155,9 @@ static gboolean
gtk_vscale_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GtkRange *range;
GtkVScale *vscale;
GtkScale *scale;
range = GTK_RANGE (widget);
scale = GTK_SCALE (widget);
vscale = GTK_VSCALE (widget);
/* We need to chain up _first_ so the various geometry members of
* GtkRange struct are updated.
@ -164,56 +168,12 @@ gtk_vscale_expose (GtkWidget *widget,
if (scale->draw_value)
{
PangoLayout *layout;
PangoRectangle logical_rect;
gchar *txt;
gint x, y;
GtkStateType state_type;
gint value_spacing;
gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
txt = _gtk_scale_format_value (scale,
GTK_RANGE (scale)->adjustment->value);
layout = gtk_widget_create_pango_layout (widget, txt);
g_free (txt);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
switch (scale->value_pos)
{
case GTK_POS_LEFT:
x = range->range_rect.x - logical_rect.width - value_spacing;
y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
y = CLAMP (y, 0, widget->allocation.height - logical_rect.height);
break;
case GTK_POS_RIGHT:
x = range->range_rect.x + range->range_rect.width + value_spacing;
y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
y = CLAMP (y, 0, widget->allocation.height - logical_rect.height);
break;
case GTK_POS_TOP:
x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
y = range->range_rect.y - logical_rect.height - value_spacing;
break;
case GTK_POS_BOTTOM:
x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
y = range->range_rect.y + range->range_rect.height + value_spacing;
break;
layout = gtk_scale_get_layout (widget);
gtk_scale_get_layout_offsets (widget, &x, &y);
default:
g_return_val_if_reached (FALSE);
x = 0;
y = 0;
break;
}
x += widget->allocation.x;
y += widget->allocation.y;
state_type = GTK_STATE_NORMAL;
if (!GTK_WIDGET_IS_SENSITIVE (scale))
state_type = GTK_STATE_INSENSITIVE;
@ -227,9 +187,74 @@ gtk_vscale_expose (GtkWidget *widget,
"vscale",
x, y,
layout);
g_object_unref (layout);
}
return FALSE;
}
static void
gtk_vscale_get_layout_offsets (GtkScale *scale,
gint *x,
gint *y)
{
GtkWidget *widget;
GtkRange *range;
GtkScale *scale;
PangoLayout *layout;
PangoRectangle logical_rect;
gint value_spacing;
widget = GTK_WIDGET (scale);
layout = gtk_scale_get_layout (scale);
if (!layout)
{
*x = 0;
*y = 0;
return;
}
range = GTK_RANGE (widget);
scale = GTK_SCALE (widget);
gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
switch (scale->value_pos)
{
case GTK_POS_LEFT:
*x = range->range_rect.x - logical_rect.width - value_spacing;
*y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
*y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height);
break;
case GTK_POS_RIGHT:
*x = range->range_rect.x + range->range_rect.width + value_spacing;
*y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
*y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height);
break;
case GTK_POS_TOP:
*x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
*y = range->range_rect.y - logical_rect.height - value_spacing;
break;
case GTK_POS_BOTTOM:
*x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
*y = range->range_rect.y + range->range_rect.height + value_spacing;
break;
default:
g_return_val_if_reached (FALSE);
*x = 0;
*y = 0;
break;
}
*x += widget->allocation.x;
*y += widget->allocation.y;
}