2 * @file gtkcellrendererexpander.c GTK+ Cell Renderer Expander
8 * Pidgin is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
28 /* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by
29 * Jonathon Blandford <jrb@redhat.com> for RedHat, Inc.
33 #include "gtkcellrendererexpander.h"
35 static void pidgin_cell_renderer_expander_get_property (GObject
*object
,
39 static void pidgin_cell_renderer_expander_set_property (GObject
*object
,
43 static void pidgin_cell_renderer_expander_init (PidginCellRendererExpander
*cellexpander
);
44 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass
*class);
45 static void pidgin_cell_renderer_expander_get_size (GtkCellRenderer
*cell
,
47 GdkRectangle
*cell_area
,
52 static void pidgin_cell_renderer_expander_render (GtkCellRenderer
*cell
,
55 GdkRectangle
*background_area
,
56 GdkRectangle
*cell_area
,
57 GdkRectangle
*expose_area
,
59 static gboolean
pidgin_cell_renderer_expander_activate (GtkCellRenderer
*r
,
65 GtkCellRendererState flags
);
66 static void pidgin_cell_renderer_expander_finalize (GObject
*gobject
);
77 static gpointer parent_class
;
78 /* static guint expander_cell_renderer_signals [LAST_SIGNAL]; */
80 GType
pidgin_cell_renderer_expander_get_type (void)
82 static GType cell_expander_type
= 0;
84 if (!cell_expander_type
)
86 static const GTypeInfo cell_expander_info
=
88 sizeof (PidginCellRendererExpanderClass
),
90 NULL
, /* base_finalize */
91 (GClassInitFunc
) pidgin_cell_renderer_expander_class_init
,
92 NULL
, /* class_finalize */
93 NULL
, /* class_data */
94 sizeof (PidginCellRendererExpander
),
96 (GInstanceInitFunc
) pidgin_cell_renderer_expander_init
,
97 NULL
/* value_table */
101 g_type_register_static (GTK_TYPE_CELL_RENDERER
,
102 "PidginCellRendererExpander",
103 &cell_expander_info
, 0);
106 return cell_expander_type
;
109 static void pidgin_cell_renderer_expander_init (PidginCellRendererExpander
*cellexpander
)
111 GTK_CELL_RENDERER(cellexpander
)->mode
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
;
112 GTK_CELL_RENDERER(cellexpander
)->xpad
= 0;
113 GTK_CELL_RENDERER(cellexpander
)->ypad
= 2;
116 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass
*class)
118 GObjectClass
*object_class
= G_OBJECT_CLASS(class);
119 GtkCellRendererClass
*cell_class
= GTK_CELL_RENDERER_CLASS(class);
121 parent_class
= g_type_class_peek_parent (class);
122 object_class
->finalize
= pidgin_cell_renderer_expander_finalize
;
124 object_class
->get_property
= pidgin_cell_renderer_expander_get_property
;
125 object_class
->set_property
= pidgin_cell_renderer_expander_set_property
;
127 cell_class
->get_size
= pidgin_cell_renderer_expander_get_size
;
128 cell_class
->render
= pidgin_cell_renderer_expander_render
;
129 cell_class
->activate
= pidgin_cell_renderer_expander_activate
;
131 g_object_class_install_property (object_class
,
133 g_param_spec_boolean ("expander-visible",
135 "True if the renderer should draw an expander",
140 static void pidgin_cell_renderer_expander_finalize (GObject
*object
)
143 PidginCellRendererExpander *cellexpander = PIDGIN_CELL_RENDERER_EXPANDER(object);
146 (* G_OBJECT_CLASS (parent_class
)->finalize
) (object
);
149 static void pidgin_cell_renderer_expander_get_property (GObject
*object
,
154 PidginCellRendererExpander
*cellexpander
= PIDGIN_CELL_RENDERER_EXPANDER(object
);
158 case PROP_IS_EXPANDER
:
159 g_value_set_boolean(value
, cellexpander
->is_expander
);
162 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, psec
);
168 static void pidgin_cell_renderer_expander_set_property (GObject
*object
,
173 PidginCellRendererExpander
*cellexpander
= PIDGIN_CELL_RENDERER_EXPANDER (object
);
177 case PROP_IS_EXPANDER
:
178 cellexpander
->is_expander
= g_value_get_boolean(value
);
181 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, param_id
, pspec
);
186 GtkCellRenderer
*pidgin_cell_renderer_expander_new(void)
188 return g_object_new(PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER
, NULL
);
191 static void pidgin_cell_renderer_expander_get_size (GtkCellRenderer
*cell
,
193 GdkRectangle
*cell_area
,
203 gtk_widget_style_get(widget
, "expander-size", &expander_size
, NULL
);
205 calc_width
= (gint
) cell
->xpad
* 2 + expander_size
;
206 calc_height
= (gint
) cell
->ypad
* 2 + expander_size
;
212 *height
= calc_height
;
218 *x_offset
= cell
->xalign
* (cell_area
->width
- calc_width
);
219 *x_offset
= MAX (*x_offset
, 0);
223 *y_offset
= cell
->yalign
* (cell_area
->height
- calc_height
);
224 *y_offset
= MAX (*y_offset
, 0);
230 static void pidgin_cell_renderer_expander_render(GtkCellRenderer
*cell
,
233 GdkRectangle
*background_area
,
234 GdkRectangle
*cell_area
,
235 GdkRectangle
*expose_area
,
238 PidginCellRendererExpander
*cellexpander
= (PidginCellRendererExpander
*) cell
;
243 if (!cellexpander
->is_expander
)
246 width
= cell_area
->width
;
247 height
= cell_area
->height
;
249 if (!cell
->sensitive
)
250 state
= GTK_STATE_INSENSITIVE
;
251 else if (flags
& GTK_CELL_RENDERER_PRELIT
)
252 state
= GTK_STATE_PRELIGHT
;
253 else if (GTK_WIDGET_HAS_FOCUS (widget
) && flags
& GTK_CELL_RENDERER_SELECTED
)
254 state
= GTK_STATE_ACTIVE
;
256 state
= GTK_STATE_NORMAL
;
258 width
-= cell
->xpad
*2;
259 height
-= cell
->ypad
*2;
261 gtk_paint_expander (widget
->style
,
263 NULL
, widget
, "treeview",
264 cell_area
->x
+ cell
->xpad
+ (width
/ 2),
265 cell_area
->y
+ cell
->ypad
+ (height
/ 2),
266 cell
->is_expanded
? GTK_EXPANDER_EXPANDED
: GTK_EXPANDER_COLLAPSED
);
268 /* only draw the line if the color isn't set - this prevents a bug where the hline appears only under the expander */
269 g_object_get(cellexpander
, "cell-background-set", &set
, NULL
);
270 if (cell
->is_expanded
&& !set
)
271 gtk_paint_hline (widget
->style
, window
, state
, NULL
, widget
, NULL
, 0,
272 widget
->allocation
.width
, cell_area
->y
+ cell_area
->height
);
275 static gboolean
pidgin_cell_renderer_expander_activate(GtkCellRenderer
*r
,
281 GtkCellRendererState flags
)
283 GtkTreePath
*path
= gtk_tree_path_new_from_string(p
);
284 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget
), path
))
285 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget
), path
);
287 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget
),path
,FALSE
);
288 gtk_tree_path_free(path
);