aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2011-09-30 23:34:38 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-09-30 23:44:21 +0800
commitb73a8f243ea4446f39012d7a64c107c25ff6d854 (patch)
tree1fce505e0670540cff0fd9ede4a822e75b89e20c
parent6b1663a63d6d49fa9a74420a61c126a3f7ab390a (diff)
downloadgsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.tar
gsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.tar.gz
gsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.tar.bz2
gsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.tar.lz
gsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.tar.xz
gsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.tar.zst
gsoc2013-evolution-b73a8f243ea4446f39012d7a64c107c25ff6d854.zip
ETableHeader: Rework the header button drawing code for GTK+ 3
The code in ETable that draws the button headers is outdated, and uses deprecated gtk_paint_* functions mixed with cairo. Port the code to use the GtkStyleContext API, which allows themes to give the header the same appearance of a regular GtkTreeView header.
-rw-r--r--widgets/table/e-table-field-chooser-item.c36
-rw-r--r--widgets/table/e-table-header-item.c49
-rw-r--r--widgets/table/e-table-header-utils.c119
-rw-r--r--widgets/table/e-table-header-utils.h4
-rw-r--r--widgets/table/e-table-utils.c5
5 files changed, 93 insertions, 120 deletions
diff --git a/widgets/table/e-table-field-chooser-item.c b/widgets/table/e-table-field-chooser-item.c
index ecc414853c..67fe22968f 100644
--- a/widgets/table/e-table-field-chooser-item.c
+++ b/widgets/table/e-table-field-chooser-item.c
@@ -491,17 +491,12 @@ etfci_draw (GnomeCanvasItem *item,
gint rows;
gint y1, y2;
gint row;
- GtkStyle *style;
- GtkStateType state;
if (etfci->combined_header == NULL)
return;
rows = e_table_header_count (etfci->combined_header);
- style = gtk_widget_get_style (GTK_WIDGET (canvas));
- state = gtk_widget_get_state (GTK_WIDGET (canvas));
-
y1 = y2 = 0;
for (row = 0; row < rows; row++, y1 = y2) {
ETableCol *ecol;
@@ -519,17 +514,12 @@ etfci_draw (GnomeCanvasItem *item,
if (y2 < y)
continue;
- cairo_save (cr);
-
e_table_header_draw_button (cr, ecol,
- style, state,
GTK_WIDGET (canvas),
-x, y1 - y,
width, height,
etfci->width, y2 - y1,
E_TABLE_COL_ARROW_NONE);
-
- cairo_restore (cr);
}
}
@@ -567,15 +557,11 @@ etfci_start_drag (ETableFieldChooserItem *etfci,
GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas);
GtkTargetList *list;
GdkDragContext *context;
- GdkWindow *window;
- GtkStyle *style;
- GtkStateType state;
ETableCol *ecol;
cairo_surface_t *cs;
cairo_t *cr;
gint drag_col;
gint button_height;
- GdkPixbuf *pixbuf;
GtkTargetEntry etfci_drag_types[] = {
{ (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
@@ -604,28 +590,18 @@ etfci_start_drag (ETableFieldChooserItem *etfci,
g_free ((gpointer) etfci_drag_types[0].target);
button_height = e_table_header_compute_height (ecol, widget);
- window = gtk_widget_get_window (widget);
- cs = gdk_window_create_similar_surface (
- window, CAIRO_CONTENT_COLOR, etfci->width, button_height);
-
- style = gtk_widget_get_style (widget);
- state = gtk_widget_get_state (widget);
-
+ cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ etfci->width, button_height);
cr = cairo_create (cs);
+
e_table_header_draw_button (
- cr, ecol, style,
- state, widget, 0, 0,
+ cr, ecol,
+ widget, 0, 0,
etfci->width, button_height,
etfci->width, button_height,
E_TABLE_COL_ARROW_NONE);
- pixbuf = gdk_pixbuf_get_from_window (window, 0, 0, etfci->width, button_height);
- gtk_drag_set_icon_pixbuf (
- context,
- pixbuf,
- etfci->width / 2,
- button_height / 2);
- g_object_unref (pixbuf);
+ gtk_drag_set_icon_surface (context, cs);
cairo_surface_destroy (cs);
cairo_destroy (cr);
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index 11d8f31f81..b8aa55f369 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -996,9 +996,7 @@ ethi_draw (GnomeCanvasItem *item,
gint x1, x2;
gint col;
GHashTable *arrows = g_hash_table_new (NULL, NULL);
- GtkStyle *style;
-
- style = gtk_widget_get_style (GTK_WIDGET (canvas));
+ GtkStyleContext *context;
if (ethi->sort_info) {
gint length;
@@ -1040,10 +1038,13 @@ ethi_draw (GnomeCanvasItem *item,
ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width;
x1 = x2 = 0;
x2 += ethi->group_indent_width;
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (canvas));
+
for (col = 0; col < cols; col++, x1 = x2) {
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
- GtkStateType state;
gint col_width;
+ GtkRegionFlags flags = 0;
col_width = ecol->width;
@@ -1058,15 +1059,29 @@ ethi_draw (GnomeCanvasItem *item,
if (x2 <= x1)
continue;
- state = gtk_widget_get_state (GTK_WIDGET (canvas));
+ if (((col + 1) % 2) == 0)
+ flags |= GTK_REGION_EVEN;
+ else
+ flags |= GTK_REGION_ODD;
+
+ if (col == 0)
+ flags |= GTK_REGION_FIRST;
+
+ if (col + 1 == cols)
+ flags |= GTK_REGION_LAST;
+
+ gtk_style_context_save (context);
+ gtk_style_context_add_region (
+ context, GTK_STYLE_REGION_COLUMN_HEADER, flags);
e_table_header_draw_button (
- cr, ecol,
- style, state, GTK_WIDGET (canvas),
+ cr, ecol, GTK_WIDGET (canvas),
x1 - x, -y, width, height,
x2 - x1, ethi->height,
(ETableColArrow) g_hash_table_lookup (
arrows, GINT_TO_POINTER (ecol->col_idx)));
+
+ gtk_style_context_restore (context);
}
g_hash_table_destroy (arrows);
@@ -1209,22 +1224,16 @@ ethi_start_drag (ETableHeaderItem *ethi,
ETableCol *ecol;
gint col_width;
cairo_surface_t *s;
- GdkPixbuf *pixbuf;
cairo_t *cr;
gint group_indent = 0;
GHashTable *arrows = g_hash_table_new (NULL, NULL);
- GtkStateType state;
- GtkStyle *style;
GtkTargetEntry ethi_drag_types[] = {
{ (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
- state = gtk_widget_get_state (widget);
- style = gtk_widget_get_style (widget);
-
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
@@ -1269,27 +1278,17 @@ ethi_start_drag (ETableHeaderItem *ethi,
ecol = e_table_header_get_column (ethi->eth, ethi->drag_col);
col_width = ecol->width;
- s = cairo_image_surface_create (CAIRO_FORMAT_A1, col_width, ethi->height);
+ s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, col_width, ethi->height);
cr = cairo_create (s);
- pixbuf = gdk_pixbuf_get_from_surface (
- s, 0, 0, col_width, ethi->height);
-
- state = gtk_widget_get_state (widget);
e_table_header_draw_button (
cr, ecol,
- style, state,
widget, 0, 0,
col_width, ethi->height,
col_width, ethi->height,
(ETableColArrow) g_hash_table_lookup (
arrows, GINT_TO_POINTER (ecol->col_idx)));
- gtk_drag_set_icon_pixbuf (
- context,
- pixbuf,
- col_width / 2,
- ethi->height / 2);
- g_object_unref (pixbuf);
+ gtk_drag_set_icon_surface (context, s);
cairo_surface_destroy (s);
ethi->maybe_drag = FALSE;
diff --git a/widgets/table/e-table-header-utils.c b/widgets/table/e-table-header-utils.c
index 34f93a701b..431009016f 100644
--- a/widgets/table/e-table-header-utils.c
+++ b/widgets/table/e-table-header-utils.c
@@ -60,6 +60,23 @@ build_header_layout (GtkWidget *widget,
return layout;
}
+static void
+get_button_padding (GtkWidget *widget,
+ GtkBorder *padding)
+{
+ GtkStyleContext *context;
+ GtkStateFlags state_flags;
+
+ context = gtk_widget_get_style_context (widget);
+ state_flags = gtk_widget_get_state_flags (widget);
+
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
+ gtk_style_context_get_padding (context, state_flags, padding);
+
+ gtk_style_context_restore (context);
+}
+
/**
* e_table_header_compute_height:
* @ecol: Table column description.
@@ -73,15 +90,15 @@ gdouble
e_table_header_compute_height (ETableCol *ecol,
GtkWidget *widget)
{
- gint ythick;
gint height;
PangoLayout *layout;
+ GtkBorder padding;
g_return_val_if_fail (ecol != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_COL (ecol), -1);
g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
- ythick = gtk_widget_get_style (widget)->ythickness;
+ get_button_padding (widget, &padding);
layout = build_header_layout (widget, ecol->text);
@@ -93,8 +110,7 @@ e_table_header_compute_height (ETableCol *ecol,
}
height = MAX (height, MIN_ARROW_SIZE);
-
- height += 2 * (ythick + HEADER_PADDING);
+ height += padding.top + padding.bottom + 2 * HEADER_PADDING;
g_object_unref (layout);
@@ -102,11 +118,12 @@ e_table_header_compute_height (ETableCol *ecol,
}
gdouble
-e_table_header_width_extras (GtkStyle *style)
+e_table_header_width_extras (GtkWidget *widget)
{
- g_return_val_if_fail (style != NULL, -1);
+ GtkBorder padding;
- return 2 * (style->xthickness + HEADER_PADDING);
+ get_button_padding (widget, &padding);
+ return padding.left + padding.right + 2 * HEADER_PADDING;
}
/* Creates a pixmap that is a composite of a background color and the upper-left
@@ -233,8 +250,6 @@ make_composite_pixmap (GdkDrawable *drawable,
* e_table_header_draw_button:
* @drawable: Destination drawable.
* @ecol: Table column for the header information.
- * @style: Style to use for drawing the button.
- * @state: State of the table widget.
* @widget: The table widget.
* @x: Leftmost coordinate of the button.
* @y: Topmost coordinate of the button.
@@ -249,8 +264,6 @@ make_composite_pixmap (GdkDrawable *drawable,
void
e_table_header_draw_button (cairo_t *cr,
ETableCol *ecol,
- GtkStyle *style,
- GtkStateType state,
GtkWidget *widget,
gint x,
gint y,
@@ -260,58 +273,49 @@ e_table_header_draw_button (cairo_t *cr,
gint button_height,
ETableColArrow arrow)
{
- gint xthick, ythick;
gint inner_x, inner_y;
gint inner_width, inner_height;
gint arrow_width = 0, arrow_height = 0;
PangoLayout *layout;
- static gpointer g_label = NULL;
+ GtkStyleContext *context;
+ GtkBorder padding;
+ GtkStateFlags state_flags;
g_return_if_fail (cr != NULL);
g_return_if_fail (ecol != NULL);
g_return_if_fail (E_IS_TABLE_COL (ecol));
- g_return_if_fail (style != NULL);
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (button_width > 0 && button_height > 0);
- if (g_label == NULL) {
- GtkWidget *button = gtk_button_new_with_label("Hi");
- GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_container_add (GTK_CONTAINER (window), button);
- gtk_widget_ensure_style (window);
- gtk_widget_ensure_style (button);
- g_label = gtk_bin_get_child (GTK_BIN (button));
- g_object_add_weak_pointer (G_OBJECT (g_label), &g_label);
- gtk_widget_ensure_style (g_label);
- gtk_widget_realize (g_label);
- }
-
- cairo_save (cr);
- gdk_cairo_set_source_color (
- cr, &gtk_widget_get_style (GTK_WIDGET (g_label))->fg[state]);
+ /* Button bevel */
+ context = gtk_widget_get_style_context (widget);
+ state_flags = gtk_widget_get_state_flags (widget);
- xthick = style->xthickness;
- ythick = style->ythickness;
+ gtk_style_context_save (context);
+ gtk_style_context_set_state (context, state_flags);
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
- /* Button bevel */
+ gtk_style_context_get_padding (context, state_flags, &padding);
- gtk_paint_box (style, cr, state, GTK_SHADOW_OUT,
- widget, "button",
- x, y, button_width, button_height);
+ gtk_render_background (
+ context, cr, x, y,
+ button_width, button_height);
+ gtk_render_frame (
+ context, cr, x, y,
+ button_width, button_height);
/* Inside area */
- inner_width = button_width - 2 * (xthick + HEADER_PADDING);
- inner_height = button_height - 2 * (ythick + HEADER_PADDING);
+ inner_width = button_width - (padding.left + padding.right + 2 * HEADER_PADDING);
+ inner_height = button_height - (padding.top + padding.bottom + 2 * HEADER_PADDING);
if (inner_width < 1 || inner_height < 1) {
- cairo_restore (cr);
return; /* nothing fits */
}
- inner_x = x + xthick + HEADER_PADDING;
- inner_y = y + ythick + HEADER_PADDING;
+ inner_x = x + padding.left + HEADER_PADDING;
+ inner_y = y + padding.top + HEADER_PADDING;
/* Arrow space */
@@ -328,12 +332,11 @@ e_table_header_draw_button (cairo_t *cr,
inner_width -= arrow_width + HEADER_PADDING;
break;
default:
- cairo_restore (cr);
g_return_if_reached ();
}
if (inner_width < 1) {
- cairo_restore (cr);
+ gtk_style_context_restore (context);
return; /* nothing else fits */
}
@@ -370,18 +373,19 @@ e_table_header_draw_button (cairo_t *cr,
layout, (inner_width - (xpos - inner_x)) *
PANGO_SCALE);
- cairo_move_to (cr, xpos + pwidth + 1, ypos);
- pango_cairo_show_layout (cr, layout);
+ gtk_render_layout (
+ context, cr, xpos + pwidth + 1,
+ ypos, layout);
}
- gdk_cairo_set_source_pixbuf (cr, ecol->pixbuf,
- xpos, inner_y + (inner_height - clip_height) / 2);
- cairo_paint (cr);
+ gtk_render_icon (
+ context, cr, ecol->pixbuf, xpos,
+ inner_y + (inner_height - clip_height) / 2);
+
} else {
pango_layout_set_width (layout, inner_width * PANGO_SCALE);
- cairo_move_to (cr, inner_x, inner_y);
- pango_cairo_show_layout (cr, layout);
+ gtk_render_layout (context, cr, inner_x, inner_y, layout);
}
switch (arrow) {
@@ -393,21 +397,20 @@ e_table_header_draw_button (cairo_t *cr,
if (ecol->icon_name == NULL)
inner_width += arrow_width + HEADER_PADDING;
- gtk_paint_arrow (style, cr, state,
- GTK_SHADOW_NONE, widget, "header",
- (arrow == E_TABLE_COL_ARROW_UP) ? GTK_ARROW_UP : GTK_ARROW_DOWN,
- (ecol->icon_name == NULL),
- inner_x + inner_width - arrow_width,
- inner_y + (inner_height - arrow_height) / 2,
- arrow_width, arrow_height);
+ gtk_render_arrow (
+ context, cr,
+ (arrow == E_TABLE_COL_ARROW_UP) ? 0 : G_PI,
+ inner_x + inner_width - arrow_width,
+ inner_y + (inner_height - arrow_height) / 2,
+ MAX (arrow_width, arrow_height));
+
break;
}
default:
- cairo_restore (cr);
g_return_if_reached ();
}
g_object_unref (layout);
- cairo_restore (cr);
+ gtk_style_context_restore (context);
}
diff --git a/widgets/table/e-table-header-utils.h b/widgets/table/e-table-header-utils.h
index c3b2de89c7..e6d2aaba1d 100644
--- a/widgets/table/e-table-header-utils.h
+++ b/widgets/table/e-table-header-utils.h
@@ -32,11 +32,9 @@ G_BEGIN_DECLS
gdouble e_table_header_compute_height (ETableCol *ecol,
GtkWidget *widget);
-gdouble e_table_header_width_extras (GtkStyle *style);
+gdouble e_table_header_width_extras (GtkWidget *widget);
void e_table_header_draw_button (cairo_t *cr,
ETableCol *ecol,
- GtkStyle *style,
- GtkStateType state,
GtkWidget *widget,
gint x,
gint y,
diff --git a/widgets/table/e-table-utils.c b/widgets/table/e-table-utils.c
index 007803585e..a534f22f07 100644
--- a/widgets/table/e-table-utils.c
+++ b/widgets/table/e-table-utils.c
@@ -40,7 +40,6 @@ e_table_state_to_header (GtkWidget *widget,
ETableState *state)
{
ETableHeader *nh;
- GtkStyle *style;
const gint max_cols = e_table_header_count (full_header);
gint column;
GValue *val = g_new0 (GValue, 1);
@@ -49,11 +48,9 @@ e_table_state_to_header (GtkWidget *widget,
g_return_val_if_fail (full_header, NULL);
g_return_val_if_fail (state, NULL);
- style = gtk_widget_get_style (widget);
-
nh = e_table_header_new ();
g_value_init (val, G_TYPE_DOUBLE);
- g_value_set_double (val, e_table_header_width_extras (style));
+ g_value_set_double (val, e_table_header_width_extras (widget));
g_object_set_property (G_OBJECT(nh), "width_extras", val);
g_free (val);