Add a fake STEPPER function that is used for drawing scrollbar steppers,

Sun Apr 21 14:10:04 2002  Owen Taylor  <otaylor@redhat.com>

        * pixbuf-rc-style.c pixbuf.h pixbuf-draw.c: Add a fake STEPPER
        function that is used for drawing scrollbar steppers,
        so that themes that want to draw the button and arrow
        separately can override the default handling.

        * pixbuf-draw.c: Remove draw_polygon() since it was
        just a cut-and-paste of the default one. Remove
        some unused code.
This commit is contained in:
Owen Taylor 2002-04-21 19:00:52 +00:00 committed by Owen Taylor
parent 06008057b6
commit 1ffde0469e
4 changed files with 108 additions and 171 deletions

View File

@ -1,3 +1,14 @@
Sun Apr 21 14:10:04 2002 Owen Taylor <otaylor@redhat.com>
* pixbuf-rc-style.c pixbuf.h pixbuf-draw.c: Add a fake STEPPER
function that is used for drawing scrollbar steppers,
so that themes that want to draw the button and arrow
separately can override the default handling.
* pixbuf-draw.c: Remove draw_polygon() since it was
just a cut-and-paste of the default one. Remove
some unused code.
2002-03-07 James Henstridge <james@daa.com.au>
* Makefile.am (libpixmap_la_LIBADD): link pixbuf engine against

View File

@ -421,84 +421,48 @@ draw_shadow(GtkStyle *style,
x, y, width, height);
}
/* This function makes up for some brokeness in gtkrange.c
* where we never get the full arrow of the stepper button
* and the type of button in a single drawing function.
*
* It doesn't work correctly when the scrollbar is squished
* to the point we don't have room for full-sized steppers.
*/
static void
draw_polygon(GtkStyle * style,
GdkWindow * window,
GtkStateType state,
GtkShadowType shadow,
GdkRectangle * area,
GtkWidget * widget,
const gchar *detail,
GdkPoint * points,
gint npoints,
gint fill)
reverse_engineer_stepper_box (GtkWidget *range,
GtkArrowType arrow_type,
gint *x,
gint *y,
gint *width,
gint *height)
{
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif /* M_PI */
#ifndef M_PI_4
#define M_PI_4 0.78539816339744830962
#endif /* M_PI_4 */
gint slider_width = 14, stepper_size = 14;
gint box_width;
gint box_height;
static const gdouble pi_over_4 = M_PI_4;
static const gdouble pi_3_over_4 = M_PI_4 * 3;
GdkGC *gc3;
GdkGC *gc4;
gdouble angle;
gint i;
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
g_return_if_fail(points != NULL);
switch (shadow)
if (range)
{
case GTK_SHADOW_IN:
gc3 = style->light_gc[state];
gc4 = style->black_gc;
break;
case GTK_SHADOW_OUT:
gc3 = style->black_gc;
gc4 = style->light_gc[state];
break;
default:
return;
gtk_widget_style_get (range,
"slider_width", &slider_width,
"stepper_size", &stepper_size,
NULL);
}
if (area)
if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
{
gdk_gc_set_clip_rectangle(gc3, area);
gdk_gc_set_clip_rectangle(gc4, area);
box_width = slider_width;
box_height = stepper_size;
}
if (fill)
gdk_draw_polygon(window, style->bg_gc[state], TRUE, points, npoints);
npoints--;
for (i = 0; i < npoints; i++)
else
{
if ((points[i].x == points[i + 1].x) &&
(points[i].y == points[i + 1].y))
angle = 0;
else
angle = atan2(points[i + 1].y - points[i].y,
points[i + 1].x - points[i].x);
box_width = stepper_size;
box_height = slider_width;
}
if ((angle > -pi_3_over_4) && (angle < pi_over_4))
gdk_draw_line(window, gc3,
points[i].x, points[i].y,
points[i + 1].x, points[i + 1].y);
else
gdk_draw_line(window, gc4,
points[i].x, points[i].y,
points[i + 1].x, points[i + 1].y);
}
if (area)
{
gdk_gc_set_clip_rectangle(gc3, NULL);
gdk_gc_set_clip_rectangle(gc4, NULL);
}
*x = *x - (box_width - *width) / 2;
*y = *y - (box_height - *height) / 2;
*width = box_width;
*height = box_height;
}
static void
@ -521,6 +485,57 @@ draw_arrow (GtkStyle *style,
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
if (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0)
{
/* This is a hack to work around the fact that scrollbar steppers are drawn
* as a box + arrow, so we never have
*
* The full bounding box of the scrollbar
* The arrow direction
*
* At the same time. We simulate an extra paint function, "STEPPER", by doing
* nothing for the box, and then here, reverse engineering the box that
* was passed to draw box and using that
*/
gint box_x = x;
gint box_y = y;
gint box_width = width;
gint box_height = height;
reverse_engineer_stepper_box (widget, arrow_direction,
&box_x, &box_y, &box_width, &box_height);
match_data.function = TOKEN_D_STEPPER;
match_data.detail = (gchar *)detail;
match_data.flags = (THEME_MATCH_SHADOW |
THEME_MATCH_STATE |
THEME_MATCH_ARROW_DIRECTION);
match_data.shadow = shadow;
match_data.state = state;
match_data.arrow_direction = arrow_direction;
if (draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
box_x, box_y, box_width, box_height))
{
/* The theme included stepper images, we're done */
return;
}
/* Otherwise, draw the full box, and fall through to draw the arrow
*/
match_data.function = TOKEN_D_BOX;
match_data.detail = (gchar *)detail;
match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
match_data.shadow = shadow;
match_data.state = state;
if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
box_x, box_y, box_width, box_height))
parent_class->draw_box (style, window, state, shadow, area, widget, detail,
box_x, box_y, box_width, box_height);
}
match_data.function = TOKEN_D_ARROW;
match_data.detail = (gchar *)detail;
match_data.flags = (THEME_MATCH_SHADOW |
@ -565,37 +580,7 @@ draw_diamond (GtkStyle *style,
parent_class->draw_diamond (style, window, state, shadow, area, widget, detail,
x, y, width, height);
}
/*
static void
draw_oval (GtkStyle *style,
GdkWindow *window,
GtkStateType state,
GtkShadowType shadow,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
ThemeMatchData match_data;
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
match_data.function = TOKEN_D_OVAL;
match_data.detail = (gchar *)detail;
match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
match_data.shadow = shadow;
match_data.state = state;
if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
x, y, width, height))
parent_class->draw_oval (style, window, state, shadow, area, widget, detail,
x, y, width, height);
}
*/
static void
draw_string (GtkStyle * style,
GdkWindow * window,
@ -652,6 +637,12 @@ draw_box (GtkStyle *style,
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
if (strcmp (detail, "hscrollbar") == 0 || strcmp (detail, "vscrollbar") == 0)
{
/* We handle this in draw_arrow */
return;
}
match_data.function = TOKEN_D_BOX;
match_data.detail = (gchar *)detail;
match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
@ -755,69 +746,6 @@ draw_option (GtkStyle *style,
x, y, width, height);
}
/*
static void
draw_cross (GtkStyle *style,
GdkWindow *window,
GtkStateType state,
GtkShadowType shadow,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
ThemeMatchData match_data;
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
match_data.function = TOKEN_D_CROSS;
match_data.detail = (gchar *)detail;
match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
match_data.shadow = shadow;
match_data.state = state;
if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
x, y, width, height))
parent_class->draw_cross (style, window, state, shadow, area, widget, detail,
x, y, width, height);
}
static void
draw_ramp (GtkStyle *style,
GdkWindow *window,
GtkStateType state,
GtkShadowType shadow,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
GtkArrowType arrow_direction,
gint x,
gint y,
gint width,
gint height)
{
ThemeMatchData match_data;
g_return_if_fail(style != NULL);
g_return_if_fail(window != NULL);
match_data.function = TOKEN_D_RAMP;
match_data.detail = (gchar *)detail;
match_data.flags = THEME_MATCH_SHADOW | THEME_MATCH_STATE;
match_data.shadow = shadow;
match_data.state = state;
if (!draw_simple_image (style, window, area, widget, &match_data, TRUE, TRUE,
x, y, width, height))
parent_class->draw_ramp (style, window, state, shadow, area, widget, detail,
arrow_direction, x, y, width, height);
}
*/
static void
draw_tab (GtkStyle *style,
GdkWindow *window,
@ -1087,17 +1015,13 @@ pixbuf_style_class_init (PixbufStyleClass *klass)
style_class->draw_hline = draw_hline;
style_class->draw_vline = draw_vline;
style_class->draw_shadow = draw_shadow;
style_class->draw_polygon = draw_polygon;
style_class->draw_arrow = draw_arrow;
style_class->draw_diamond = draw_diamond;
/*style_class->draw_oval = draw_oval;*/
style_class->draw_string = draw_string;
style_class->draw_box = draw_box;
style_class->draw_flat_box = draw_flat_box;
style_class->draw_check = draw_check;
style_class->draw_option = draw_option;
/*style_class->draw_cross = draw_cross;*/
/*style_class->draw_ramp = draw_ramp;*/
style_class->draw_tab = draw_tab;
style_class->draw_shadow_gap = draw_shadow_gap;
style_class->draw_box_gap = draw_box_gap;

View File

@ -87,6 +87,7 @@ theme_symbols[] =
{ "SLIDER", TOKEN_D_SLIDER },
{ "ENTRY", TOKEN_D_ENTRY },
{ "HANDLE", TOKEN_D_HANDLE },
{ "STEPPER", TOKEN_D_STEPPER },
{ "TRUE", TOKEN_TRUE },
{ "FALSE", TOKEN_FALSE },
@ -331,7 +332,7 @@ theme_parse_function(GScanner * scanner,
return G_TOKEN_EQUAL_SIGN;
token = g_scanner_get_next_token(scanner);
if ((token >= TOKEN_D_HLINE) && (token <= TOKEN_D_HANDLE))
if ((token >= TOKEN_D_HLINE) && (token <= TOKEN_D_STEPPER))
data->match_data.function = token;
return G_TOKEN_NONE;

View File

@ -74,6 +74,7 @@ enum
TOKEN_D_SLIDER,
TOKEN_D_ENTRY,
TOKEN_D_HANDLE,
TOKEN_D_STEPPER,
TOKEN_TRUE,
TOKEN_FALSE,
TOKEN_TOP,