]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-cell-renderer-expander.c
Updated Kannada translation
[empathy.git] / libempathy-gtk / empathy-cell-renderer-expander.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2006-2007 Imendio AB
4  * Copyright (C) 2007-2011 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA  02110-1301  USA
20  *
21  * Authors: Kristian Rietveld <kris@imendio.com>
22  */
23
24 #include "config.h"
25 #include "empathy-cell-renderer-expander.h"
26
27 #include "empathy-utils.h"
28
29 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyCellRendererExpander)
30 typedef struct {
31         GtkExpanderStyle     expander_style;
32         gint                 expander_size;
33
34         guint                activatable : 1;
35 } EmpathyCellRendererExpanderPriv;
36
37 enum {
38         PROP_0,
39         PROP_EXPANDER_STYLE,
40         PROP_EXPANDER_SIZE,
41         PROP_ACTIVATABLE
42 };
43
44 static void     empathy_cell_renderer_expander_get_property (GObject                         *object,
45                                                             guint                            param_id,
46                                                             GValue                          *value,
47                                                             GParamSpec                      *pspec);
48 static void     empathy_cell_renderer_expander_set_property (GObject                         *object,
49                                                             guint                            param_id,
50                                                             const GValue                    *value,
51                                                             GParamSpec                      *pspec);
52 static void     empathy_cell_renderer_expander_finalize     (GObject                         *object);
53 static void     empathy_cell_renderer_expander_get_size     (GtkCellRenderer                 *cell,
54                                                             GtkWidget                       *widget,
55                                                             const GdkRectangle              *cell_area,
56                                                             gint                            *x_offset,
57                                                             gint                            *y_offset,
58                                                             gint                            *width,
59                                                             gint                            *height);
60 static void     empathy_cell_renderer_expander_render       (GtkCellRenderer                 *cell,
61                                                             cairo_t *cr,
62                                                             GtkWidget                       *widget,
63                                                             const GdkRectangle              *background_area,
64                                                             const GdkRectangle              *cell_area,
65                                                             GtkCellRendererState             flags);
66 static gboolean empathy_cell_renderer_expander_activate     (GtkCellRenderer                 *cell,
67                                                             GdkEvent                        *event,
68                                                             GtkWidget                       *widget,
69                                                             const gchar                     *path,
70                                                             const GdkRectangle              *background_area,
71                                                             const GdkRectangle              *cell_area,
72                                                             GtkCellRendererState             flags);
73
74 G_DEFINE_TYPE (EmpathyCellRendererExpander, empathy_cell_renderer_expander, GTK_TYPE_CELL_RENDERER)
75
76 static void
77 empathy_cell_renderer_expander_init (EmpathyCellRendererExpander *expander)
78 {
79         EmpathyCellRendererExpanderPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (expander,
80                 EMPATHY_TYPE_CELL_RENDERER_EXPANDER, EmpathyCellRendererExpanderPriv);
81
82         expander->priv = priv;
83         priv->expander_style = GTK_EXPANDER_COLLAPSED;
84         priv->expander_size = 12;
85         priv->activatable = TRUE;
86
87         g_object_set (expander,
88                       "xpad", 2,
89                       "ypad", 2,
90                       "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
91                       NULL);
92 }
93
94 static void
95 empathy_cell_renderer_expander_class_init (EmpathyCellRendererExpanderClass *klass)
96 {
97         GObjectClass         *object_class;
98         GtkCellRendererClass *cell_class;
99
100         object_class  = G_OBJECT_CLASS (klass);
101         cell_class = GTK_CELL_RENDERER_CLASS (klass);
102
103         object_class->finalize = empathy_cell_renderer_expander_finalize;
104
105         object_class->get_property = empathy_cell_renderer_expander_get_property;
106         object_class->set_property = empathy_cell_renderer_expander_set_property;
107
108         cell_class->get_size = empathy_cell_renderer_expander_get_size;
109         cell_class->render = empathy_cell_renderer_expander_render;
110         cell_class->activate = empathy_cell_renderer_expander_activate;
111
112         g_object_class_install_property (object_class,
113                                          PROP_EXPANDER_STYLE,
114                                          g_param_spec_enum ("expander-style",
115                                                             "Expander Style",
116                                                             "Style to use when painting the expander",
117                                                             GTK_TYPE_EXPANDER_STYLE,
118                                                             GTK_EXPANDER_COLLAPSED,
119                                                             G_PARAM_READWRITE));
120
121         g_object_class_install_property (object_class,
122                                          PROP_EXPANDER_SIZE,
123                                          g_param_spec_int ("expander-size",
124                                                            "Expander Size",
125                                                            "The size of the expander",
126                                                            0,
127                                                            G_MAXINT,
128                                                            12,
129                                                            G_PARAM_READWRITE));
130
131         g_object_class_install_property (object_class,
132                                          PROP_ACTIVATABLE,
133                                          g_param_spec_boolean ("activatable",
134                                                                "Activatable",
135                                                                "The expander can be activated",
136                                                                TRUE,
137                                                                G_PARAM_READWRITE));
138
139         g_type_class_add_private (object_class, sizeof (EmpathyCellRendererExpanderPriv));
140 }
141
142 static void
143 empathy_cell_renderer_expander_get_property (GObject    *object,
144                                             guint       param_id,
145                                             GValue     *value,
146                                             GParamSpec *pspec)
147 {
148         EmpathyCellRendererExpander     *expander;
149         EmpathyCellRendererExpanderPriv *priv;
150
151         expander = EMPATHY_CELL_RENDERER_EXPANDER (object);
152         priv = GET_PRIV (expander);
153
154         switch (param_id) {
155         case PROP_EXPANDER_STYLE:
156                 g_value_set_enum (value, priv->expander_style);
157                 break;
158
159         case PROP_EXPANDER_SIZE:
160                 g_value_set_int (value, priv->expander_size);
161                 break;
162
163         case PROP_ACTIVATABLE:
164                 g_value_set_boolean (value, priv->activatable);
165                 break;
166
167         default:
168                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
169                 break;
170         }
171 }
172
173 static void
174 empathy_cell_renderer_expander_set_property (GObject      *object,
175                                             guint         param_id,
176                                             const GValue *value,
177                                             GParamSpec   *pspec)
178 {
179         EmpathyCellRendererExpander     *expander;
180         EmpathyCellRendererExpanderPriv *priv;
181
182         expander = EMPATHY_CELL_RENDERER_EXPANDER (object);
183         priv = GET_PRIV (expander);
184
185         switch (param_id) {
186         case PROP_EXPANDER_STYLE:
187                 priv->expander_style = g_value_get_enum (value);
188                 break;
189
190         case PROP_EXPANDER_SIZE:
191                 priv->expander_size = g_value_get_int (value);
192                 break;
193
194         case PROP_ACTIVATABLE:
195                 priv->activatable = g_value_get_boolean (value);
196                 break;
197
198         default:
199                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
200                 break;
201         }
202 }
203
204 static void
205 empathy_cell_renderer_expander_finalize (GObject *object)
206 {
207         (* G_OBJECT_CLASS (empathy_cell_renderer_expander_parent_class)->finalize) (object);
208 }
209
210 GtkCellRenderer *
211 empathy_cell_renderer_expander_new (void)
212 {
213         return g_object_new (EMPATHY_TYPE_CELL_RENDERER_EXPANDER, NULL);
214 }
215
216 static void
217 empathy_cell_renderer_expander_get_size (GtkCellRenderer    *cell,
218                                         GtkWidget          *widget,
219                                         const GdkRectangle *cell_area,
220                                         gint               *x_offset,
221                                         gint               *y_offset,
222                                         gint               *width,
223                                         gint               *height)
224 {
225         EmpathyCellRendererExpander     *expander;
226         EmpathyCellRendererExpanderPriv *priv;
227         gfloat xalign, yalign;
228         guint xpad, ypad;
229
230         expander = (EmpathyCellRendererExpander *) cell;
231         priv = GET_PRIV (expander);
232
233         g_object_get (cell,
234                       "xalign", &xalign,
235                       "yalign", &yalign,
236                       "xpad", &xpad,
237                       "ypad", &ypad,
238                       NULL);
239
240         if (cell_area) {
241                 if (x_offset) {
242                         *x_offset = xalign * (cell_area->width - (priv->expander_size + (2 * xpad)));
243                         *x_offset = MAX (*x_offset, 0);
244                 }
245
246                 if (y_offset) {
247                         *y_offset = yalign * (cell_area->height - (priv->expander_size + (2 * ypad)));
248                         *y_offset = MAX (*y_offset, 0);
249                 }
250         } else {
251                 if (x_offset)
252                         *x_offset = 0;
253
254                 if (y_offset)
255                         *y_offset = 0;
256         }
257
258         if (width)
259                 *width = xpad * 2 + priv->expander_size;
260
261         if (height)
262                 *height = ypad * 2 + priv->expander_size;
263 }
264
265 static void
266 empathy_cell_renderer_expander_render (GtkCellRenderer      *cell,
267                                       cairo_t *cr,
268                                       GtkWidget            *widget,
269                                       const GdkRectangle   *background_area,
270                                       const GdkRectangle   *cell_area,
271                                       GtkCellRendererState  flags)
272 {
273         EmpathyCellRendererExpander     *expander;
274         EmpathyCellRendererExpanderPriv *priv;
275         gint                            x_offset, y_offset;
276         guint                           xpad, ypad;
277         GtkStyleContext                 *style;
278         GtkStateFlags                    state;
279
280         expander = (EmpathyCellRendererExpander *) cell;
281         priv = GET_PRIV (expander);
282
283         empathy_cell_renderer_expander_get_size (cell, widget,
284                                                 (GdkRectangle *) cell_area,
285                                                 &x_offset, &y_offset,
286                                                 NULL, NULL);
287
288         g_object_get (cell,
289                       "xpad", &xpad,
290                       "ypad", &ypad,
291                       NULL);
292
293         style = gtk_widget_get_style_context (widget);
294
295         gtk_style_context_save (style);
296         gtk_style_context_add_class (style, GTK_STYLE_CLASS_EXPANDER);
297
298         state = gtk_cell_renderer_get_state (cell, widget, flags);
299
300         if (priv->expander_style == GTK_EXPANDER_COLLAPSED)
301                 state |= GTK_STATE_FLAG_NORMAL;
302         else
303                 state |= GTK_STATE_FLAG_ACTIVE;
304
305         gtk_style_context_set_state (style, state);
306
307         gtk_render_expander (style,
308                              cr,
309                              cell_area->x + x_offset + xpad,
310                              cell_area->y + y_offset + ypad,
311                              priv->expander_size,
312                              priv->expander_size);
313
314         gtk_style_context_restore (style);
315 }
316
317 static gboolean
318 empathy_cell_renderer_expander_activate (GtkCellRenderer      *cell,
319                                         GdkEvent             *event,
320                                         GtkWidget            *widget,
321                                         const gchar          *path_string,
322                                         const GdkRectangle   *background_area,
323                                         const GdkRectangle   *cell_area,
324                                         GtkCellRendererState  flags)
325 {
326         EmpathyCellRendererExpanderPriv *priv;
327         GtkTreePath                    *path;
328
329         priv = GET_PRIV (cell);
330
331         if (!GTK_IS_TREE_VIEW (widget) || !priv->activatable)
332                 return FALSE;
333
334         path = gtk_tree_path_new_from_string (path_string);
335
336         if (gtk_tree_path_get_depth (path) > 1) {
337                 gtk_tree_path_free (path);
338                 return TRUE;
339         }
340
341         if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget), path)) {
342                 gtk_tree_view_collapse_row (GTK_TREE_VIEW (widget), path);
343         } else {
344                 gtk_tree_view_expand_row (GTK_TREE_VIEW (widget), path, FALSE);
345         }
346
347         gtk_tree_path_free (path);
348
349         return TRUE;
350 }