14561
|
1 /*
|
|
2 * @file gtkcellrendererexpander.c GTK+ Cell Renderer Expander
|
|
3 * @ingroup gtkui
|
|
4 *
|
|
5 * gaim
|
|
6 *
|
|
7 * Gaim is the legal property of its developers, whose names are too numerous
|
|
8 * to list here. Please refer to the COPYRIGHT file distributed with this
|
|
9 * source distribution.
|
|
10 *
|
|
11 * This program is free software; you can redistribute it and/or modify
|
|
12 * it under the terms of the GNU General Public License as published by
|
|
13 * the Free Software Foundation; either version 2 of the License, or
|
|
14 * (at your option) any later version.
|
|
15 *
|
|
16 * This program is distributed in the hope that it will be useful,
|
|
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 * GNU General Public License for more details.
|
|
20 *
|
|
21 * You should have received a copy of the GNU General Public License
|
|
22 * along with this program; if not, write to the Free Software
|
|
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
24 *
|
|
25 */
|
|
26
|
|
27 /* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by
|
|
28 * Jonathon Blandford <jrb@redhat.com> for RedHat, Inc.
|
|
29 */
|
|
30
|
|
31 #include <gtk/gtktreeview.h>
|
|
32 #include "gtkcellrendererexpander.h"
|
|
33
|
|
34 static void gaim_gtk_cell_renderer_expander_get_property (GObject *object,
|
|
35 guint param_id,
|
|
36 GValue *value,
|
|
37 GParamSpec *pspec);
|
|
38 static void gaim_gtk_cell_renderer_expander_set_property (GObject *object,
|
|
39 guint param_id,
|
|
40 const GValue *value,
|
|
41 GParamSpec *pspec);
|
|
42 static void gaim_gtk_cell_renderer_expander_init (GaimGtkCellRendererExpander *cellexpander);
|
|
43 static void gaim_gtk_cell_renderer_expander_class_init (GaimGtkCellRendererExpanderClass *class);
|
|
44 static void gaim_gtk_cell_renderer_expander_get_size (GtkCellRenderer *cell,
|
|
45 GtkWidget *widget,
|
|
46 GdkRectangle *cell_area,
|
|
47 gint *x_offset,
|
|
48 gint *y_offset,
|
|
49 gint *width,
|
|
50 gint *height);
|
|
51 static void gaim_gtk_cell_renderer_expander_render (GtkCellRenderer *cell,
|
|
52 GdkWindow *window,
|
|
53 GtkWidget *widget,
|
|
54 GdkRectangle *background_area,
|
|
55 GdkRectangle *cell_area,
|
|
56 GdkRectangle *expose_area,
|
|
57 guint flags);
|
|
58 static gboolean gaim_gtk_cell_renderer_expander_activate (GtkCellRenderer *cell,
|
|
59 GdkEvent *event,
|
|
60 GtkWidget *widget,
|
|
61 const gchar *path,
|
|
62 GdkRectangle *background_area,
|
|
63 GdkRectangle *cell_area,
|
|
64 guint flags);
|
|
65 static void gaim_gtk_cell_renderer_expander_finalize (GObject *gobject);
|
|
66
|
|
67 enum {
|
|
68 LAST_SIGNAL
|
|
69 };
|
|
70
|
|
71 enum {
|
|
72 PROP_0,
|
|
73 PROP_IS_EXPANDER
|
|
74 };
|
|
75
|
|
76 static gpointer parent_class;
|
|
77 /* static guint expander_cell_renderer_signals [LAST_SIGNAL]; */
|
|
78
|
|
79 GType gaim_gtk_cell_renderer_expander_get_type (void)
|
|
80 {
|
|
81 static GType cell_expander_type = 0;
|
|
82
|
|
83 if (!cell_expander_type)
|
|
84 {
|
|
85 static const GTypeInfo cell_expander_info =
|
|
86 {
|
|
87 sizeof (GaimGtkCellRendererExpanderClass),
|
|
88 NULL, /* base_init */
|
|
89 NULL, /* base_finalize */
|
|
90 (GClassInitFunc) gaim_gtk_cell_renderer_expander_class_init,
|
|
91 NULL, /* class_finalize */
|
|
92 NULL, /* class_data */
|
|
93 sizeof (GaimGtkCellRendererExpander),
|
|
94 0, /* n_preallocs */
|
|
95 (GInstanceInitFunc) gaim_gtk_cell_renderer_expander_init,
|
|
96 NULL /* value_table */
|
|
97 };
|
|
98
|
|
99 cell_expander_type =
|
|
100 g_type_register_static (GTK_TYPE_CELL_RENDERER,
|
|
101 "GaimGtkCellRendererExpander",
|
|
102 &cell_expander_info, 0);
|
|
103 }
|
|
104
|
|
105 return cell_expander_type;
|
|
106 }
|
|
107
|
|
108 static void gaim_gtk_cell_renderer_expander_init (GaimGtkCellRendererExpander *cellexpander)
|
|
109 {
|
|
110 GTK_CELL_RENDERER(cellexpander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
|
|
111 GTK_CELL_RENDERER(cellexpander)->xpad = 2;
|
|
112 GTK_CELL_RENDERER(cellexpander)->ypad = 2;
|
|
113 }
|
|
114
|
|
115 static void gaim_gtk_cell_renderer_expander_class_init (GaimGtkCellRendererExpanderClass *class)
|
|
116 {
|
|
117 GObjectClass *object_class = G_OBJECT_CLASS(class);
|
|
118 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
|
|
119
|
|
120 parent_class = g_type_class_peek_parent (class);
|
|
121 object_class->finalize = gaim_gtk_cell_renderer_expander_finalize;
|
|
122
|
|
123 object_class->get_property = gaim_gtk_cell_renderer_expander_get_property;
|
|
124 object_class->set_property = gaim_gtk_cell_renderer_expander_set_property;
|
|
125
|
|
126 cell_class->get_size = gaim_gtk_cell_renderer_expander_get_size;
|
|
127 cell_class->render = gaim_gtk_cell_renderer_expander_render;
|
|
128 cell_class->activate = gaim_gtk_cell_renderer_expander_activate;
|
|
129
|
|
130 g_object_class_install_property (object_class,
|
|
131 PROP_IS_EXPANDER,
|
|
132 g_param_spec_boolean ("expander-visible",
|
|
133 "Is Expander",
|
|
134 "True if the renderer should draw an expander",
|
|
135 FALSE,
|
|
136 G_PARAM_READWRITE));
|
|
137 }
|
|
138
|
|
139 static void gaim_gtk_cell_renderer_expander_finalize (GObject *object)
|
|
140 {
|
|
141 /*
|
|
142 GaimGtkCellRendererExpander *cellexpander = GAIM_GTK_CELL_RENDERER_EXPANDER(object);
|
|
143 */
|
|
144
|
|
145 (* G_OBJECT_CLASS (parent_class)->finalize) (object);
|
|
146 }
|
|
147
|
|
148 static void gaim_gtk_cell_renderer_expander_get_property (GObject *object,
|
|
149 guint param_id,
|
|
150 GValue *value,
|
|
151 GParamSpec *psec)
|
|
152 {
|
|
153 GaimGtkCellRendererExpander *cellexpander = GAIM_GTK_CELL_RENDERER_EXPANDER(object);
|
|
154
|
|
155 switch (param_id)
|
|
156 {
|
|
157 case PROP_IS_EXPANDER:
|
|
158 g_value_set_boolean(value, cellexpander->is_expander);
|
|
159 break;
|
|
160 default:
|
|
161 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec);
|
|
162 break;
|
|
163
|
|
164 }
|
|
165 }
|
|
166
|
|
167 static void gaim_gtk_cell_renderer_expander_set_property (GObject *object,
|
|
168 guint param_id,
|
|
169 const GValue *value,
|
|
170 GParamSpec *pspec)
|
|
171 {
|
|
172 GaimGtkCellRendererExpander *cellexpander = GAIM_GTK_CELL_RENDERER_EXPANDER (object);
|
|
173
|
|
174 switch (param_id)
|
|
175 {
|
|
176 case PROP_IS_EXPANDER:
|
|
177 cellexpander->is_expander = g_value_get_boolean(value);
|
|
178 break;
|
|
179 default:
|
|
180 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
|
|
181 break;
|
|
182 }
|
|
183 }
|
|
184
|
|
185 GtkCellRenderer *gaim_gtk_cell_renderer_expander_new(void)
|
|
186 {
|
|
187 return g_object_new(GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER, NULL);
|
|
188 }
|
|
189
|
|
190 static void gaim_gtk_cell_renderer_expander_get_size (GtkCellRenderer *cell,
|
|
191 GtkWidget *widget,
|
|
192 GdkRectangle *cell_area,
|
|
193 gint *x_offset,
|
|
194 gint *y_offset,
|
|
195 gint *width,
|
|
196 gint *height)
|
|
197 {
|
|
198 gint calc_width;
|
|
199 gint calc_height;
|
|
200 gint expander_size;
|
|
201
|
|
202 gtk_widget_style_get(widget, "expander-size", &expander_size, NULL);
|
|
203
|
|
204 calc_width = (gint) cell->xpad * 2 + expander_size;
|
|
205 calc_height = (gint) cell->ypad * 2 + expander_size;
|
|
206
|
|
207 if (width)
|
|
208 *width = calc_width;
|
|
209
|
|
210 if (height)
|
|
211 *height = calc_height;
|
|
212
|
|
213 if (cell_area)
|
|
214 {
|
|
215 if (x_offset)
|
|
216 {
|
|
217 *x_offset = cell->xalign * (cell_area->width - calc_width);
|
|
218 *x_offset = MAX (*x_offset, 0);
|
|
219 }
|
|
220 if (y_offset)
|
|
221 {
|
|
222 *y_offset = cell->yalign * (cell_area->height - calc_height);
|
|
223 *y_offset = MAX (*y_offset, 0);
|
|
224 }
|
|
225 }
|
|
226 }
|
|
227
|
|
228
|
|
229 static void gaim_gtk_cell_renderer_expander_render (GtkCellRenderer *cell,
|
|
230 GdkWindow *window,
|
|
231 GtkWidget *widget,
|
|
232 GdkRectangle *background_area,
|
|
233 GdkRectangle *cell_area,
|
|
234 GdkRectangle *expose_area,
|
|
235 guint flags)
|
|
236 {
|
|
237 GaimGtkCellRendererExpander *cellexpander = (GaimGtkCellRendererExpander *) cell;
|
|
238
|
|
239 gint width, height;
|
|
240 GtkStateType state;
|
|
241
|
|
242 if (!cellexpander->is_expander)
|
|
243 return;
|
|
244
|
|
245 width = cell_area->width;
|
|
246 height = cell_area->height;
|
|
247
|
|
248 if (!cell->sensitive)
|
|
249 state = GTK_STATE_INSENSITIVE;
|
|
250 else if (flags & GTK_CELL_RENDERER_PRELIT)
|
|
251 state = GTK_STATE_PRELIGHT;
|
|
252 else if (GTK_WIDGET_HAS_FOCUS (widget) && flags & GTK_CELL_RENDERER_SELECTED)
|
|
253 state = GTK_STATE_ACTIVE;
|
|
254 else
|
|
255 state = GTK_STATE_NORMAL;
|
|
256
|
|
257 width -= cell->xpad*2;
|
|
258 height -= cell->ypad*2;
|
|
259
|
|
260 gtk_paint_expander (widget->style,
|
|
261 window, state,
|
|
262 NULL, widget, "treeview",
|
|
263 cell_area->x + cell->xpad + (width / 2),
|
|
264 cell_area->y + cell->ypad + (height / 2),
|
|
265 cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
|
|
266 }
|
|
267
|
|
268 static gint gaim_gtk_cell_renderer_expander_activate(GtkCellRenderer *r,
|
|
269 GdkEvent *event,
|
|
270 GtkWidget *widget,
|
|
271 const gchar *p,
|
|
272 GdkRectangle *bg,
|
|
273 GdkRectangle *cell,
|
|
274 GtkCellRendererState flags)
|
|
275 {
|
|
276 GtkTreePath *path = gtk_tree_path_new_from_string(p);
|
|
277 printf("!! Activated!\n");
|
|
278 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
|
|
279 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
|
|
280 else
|
|
281 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget),path,FALSE);
|
|
282 gtk_tree_path_free(path);
|
|
283 }
|