| 16 * |
16 * |
| 17 * This program is distributed in the hope that it will be useful, |
17 * This program is distributed in the hope that it will be useful, |
| 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 * GNU General Public License for more details. |
20 * GNU General Public License for more details. |
| 21 * |
21 * |
| 22 * You should have received a copy of the GNU General Public License |
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 |
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 |
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 25 * |
25 * |
| 26 */ |
26 */ |
| 27 |
27 |
| 28 /* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by |
28 /* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by |
| 29 * Jonathon Blandford <jrb@redhat.com> for RedHat, Inc. |
29 * Jonathon Blandford <jrb@redhat.com> for RedHat, Inc. |
| 30 */ |
30 */ |
| 31 |
31 |
| 32 #include <gtk/gtk.h> |
32 #include <gtk/gtk.h> |
| 33 #include <gtk/gtktreeview.h> |
33 #include <gtk/gtktreeview.h> |
| 72 |
72 |
| 73 enum { |
73 enum { |
| 74 PROP_0, |
74 PROP_0, |
| 75 PROP_IS_EXPANDER |
75 PROP_IS_EXPANDER |
| 76 }; |
76 }; |
| 77 |
77 |
| 78 static gpointer parent_class; |
78 static gpointer parent_class; |
| 79 /* static guint expander_cell_renderer_signals [LAST_SIGNAL]; */ |
79 /* static guint expander_cell_renderer_signals [LAST_SIGNAL]; */ |
| 80 |
80 |
| 81 GType pidgin_cell_renderer_expander_get_type (void) |
81 GType pidgin_cell_renderer_expander_get_type (void) |
| 82 { |
82 { |
| 83 static GType cell_expander_type = 0; |
83 static GType cell_expander_type = 0; |
| 84 |
84 |
| 85 if (!cell_expander_type) |
85 if (!cell_expander_type) |
| 86 { |
86 { |
| 87 static const GTypeInfo cell_expander_info = |
87 static const GTypeInfo cell_expander_info = |
| 88 { |
88 { |
| 89 sizeof (PidginCellRendererExpanderClass), |
89 sizeof (PidginCellRendererExpanderClass), |
| 95 sizeof (PidginCellRendererExpander), |
95 sizeof (PidginCellRendererExpander), |
| 96 0, /* n_preallocs */ |
96 0, /* n_preallocs */ |
| 97 (GInstanceInitFunc) pidgin_cell_renderer_expander_init, |
97 (GInstanceInitFunc) pidgin_cell_renderer_expander_init, |
| 98 NULL /* value_table */ |
98 NULL /* value_table */ |
| 99 }; |
99 }; |
| 100 |
100 |
| 101 cell_expander_type = |
101 cell_expander_type = |
| 102 g_type_register_static (GTK_TYPE_CELL_RENDERER, |
102 g_type_register_static (GTK_TYPE_CELL_RENDERER, |
| 103 "PidginCellRendererExpander", |
103 "PidginCellRendererExpander", |
| 104 &cell_expander_info, 0); |
104 &cell_expander_info, 0); |
| 105 } |
105 } |
| 106 |
106 |
| 107 return cell_expander_type; |
107 return cell_expander_type; |
| 108 } |
108 } |
| 109 |
109 |
| 110 static void pidgin_cell_renderer_expander_init (PidginCellRendererExpander *cellexpander) |
110 static void pidgin_cell_renderer_expander_init (PidginCellRendererExpander *cellexpander) |
| 111 { |
111 { |
| 116 |
116 |
| 117 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class) |
117 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class) |
| 118 { |
118 { |
| 119 GObjectClass *object_class = G_OBJECT_CLASS(class); |
119 GObjectClass *object_class = G_OBJECT_CLASS(class); |
| 120 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class); |
120 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class); |
| 121 |
121 |
| 122 parent_class = g_type_class_peek_parent (class); |
122 parent_class = g_type_class_peek_parent (class); |
| 123 object_class->finalize = pidgin_cell_renderer_expander_finalize; |
123 object_class->finalize = pidgin_cell_renderer_expander_finalize; |
| 124 |
124 |
| 125 object_class->get_property = pidgin_cell_renderer_expander_get_property; |
125 object_class->get_property = pidgin_cell_renderer_expander_get_property; |
| 126 object_class->set_property = pidgin_cell_renderer_expander_set_property; |
126 object_class->set_property = pidgin_cell_renderer_expander_set_property; |
| 127 |
127 |
| 128 cell_class->get_size = pidgin_cell_renderer_expander_get_size; |
128 cell_class->get_size = pidgin_cell_renderer_expander_get_size; |
| 129 cell_class->render = pidgin_cell_renderer_expander_render; |
129 cell_class->render = pidgin_cell_renderer_expander_render; |
| 130 cell_class->activate = pidgin_cell_renderer_expander_activate; |
130 cell_class->activate = pidgin_cell_renderer_expander_activate; |
| 131 |
131 |
| 132 g_object_class_install_property (object_class, |
132 g_object_class_install_property (object_class, |
| 133 PROP_IS_EXPANDER, |
133 PROP_IS_EXPANDER, |
| 134 g_param_spec_boolean ("expander-visible", |
134 g_param_spec_boolean ("expander-visible", |
| 135 "Is Expander", |
135 "Is Expander", |
| 136 "True if the renderer should draw an expander", |
136 "True if the renderer should draw an expander", |
| 160 g_value_set_boolean(value, cellexpander->is_expander); |
160 g_value_set_boolean(value, cellexpander->is_expander); |
| 161 break; |
161 break; |
| 162 default: |
162 default: |
| 163 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec); |
163 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec); |
| 164 break; |
164 break; |
| 165 |
165 |
| 166 } |
166 } |
| 167 } |
167 } |
| 168 |
168 |
| 169 static void pidgin_cell_renderer_expander_set_property (GObject *object, |
169 static void pidgin_cell_renderer_expander_set_property (GObject *object, |
| 170 guint param_id, |
170 guint param_id, |
| 197 gint *width, |
197 gint *width, |
| 198 gint *height) |
198 gint *height) |
| 199 { |
199 { |
| 200 gint calc_width; |
200 gint calc_width; |
| 201 gint calc_height; |
201 gint calc_height; |
| 202 gint expander_size; |
202 gint expander_size; |
| 203 |
203 |
| 204 gtk_widget_style_get(widget, "expander-size", &expander_size, NULL); |
204 gtk_widget_style_get(widget, "expander-size", &expander_size, NULL); |
| 205 |
205 |
| 206 calc_width = (gint) cell->xpad * 2 + expander_size; |
206 calc_width = (gint) cell->xpad * 2 + expander_size; |
| 207 calc_height = (gint) cell->ypad * 2 + expander_size; |
207 calc_height = (gint) cell->ypad * 2 + expander_size; |
| 208 |
208 |
| 209 if (width) |
209 if (width) |
| 210 *width = calc_width; |
210 *width = calc_width; |
| 211 |
211 |
| 212 if (height) |
212 if (height) |
| 213 *height = calc_height; |
213 *height = calc_height; |
| 214 |
214 |
| 215 if (cell_area) |
215 if (cell_area) |
| 216 { |
216 { |
| 217 if (x_offset) |
217 if (x_offset) |
| 218 { |
218 { |
| 219 *x_offset = cell->xalign * (cell_area->width - calc_width); |
219 *x_offset = cell->xalign * (cell_area->width - calc_width); |
| 226 } |
226 } |
| 227 } |
227 } |
| 228 } |
228 } |
| 229 |
229 |
| 230 |
230 |
| 231 static void pidgin_cell_renderer_expander_render (GtkCellRenderer *cell, |
231 static void pidgin_cell_renderer_expander_render(GtkCellRenderer *cell, |
| 232 GdkWindow *window, |
232 GdkWindow *window, |
| 233 GtkWidget *widget, |
233 GtkWidget *widget, |
| 234 GdkRectangle *background_area, |
234 GdkRectangle *background_area, |
| 235 GdkRectangle *cell_area, |
235 GdkRectangle *cell_area, |
| 236 GdkRectangle *expose_area, |
236 GdkRectangle *expose_area, |
| 237 guint flags) |
237 guint flags) |
| 238 { |
238 { |
| 239 PidginCellRendererExpander *cellexpander = (PidginCellRendererExpander *) cell; |
239 PidginCellRendererExpander *cellexpander = (PidginCellRendererExpander *) cell; |
| 240 |
240 gboolean set; |
| 241 gint width, height; |
241 gint width, height; |
| 242 GtkStateType state; |
242 GtkStateType state; |
| 243 |
243 |
| 244 if (!cellexpander->is_expander) |
244 if (!cellexpander->is_expander) |
| 245 return; |
245 return; |
| 246 |
246 |
| 247 width = cell_area->width; |
247 width = cell_area->width; |
| 248 height = cell_area->height; |
248 height = cell_area->height; |
| 249 |
249 |
| 250 #if GTK_CHECK_VERSION(2,6,0) |
250 #if GTK_CHECK_VERSION(2,6,0) |
| 251 if (!cell->sensitive) |
251 if (!cell->sensitive) |
| 252 state = GTK_STATE_INSENSITIVE; |
252 state = GTK_STATE_INSENSITIVE; |
| 253 #else |
253 #else |
| 254 if (GTK_WIDGET_STATE(widget) == GTK_STATE_INSENSITIVE) |
254 if (GTK_WIDGET_STATE(widget) == GTK_STATE_INSENSITIVE) |
| 268 window, state, |
268 window, state, |
| 269 NULL, widget, "treeview", |
269 NULL, widget, "treeview", |
| 270 cell_area->x + cell->xpad + (width / 2), |
270 cell_area->x + cell->xpad + (width / 2), |
| 271 cell_area->y + cell->ypad + (height / 2), |
271 cell_area->y + cell->ypad + (height / 2), |
| 272 cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED); |
272 cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED); |
| 273 if (cell->is_expanded) |
273 |
| 274 gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0, |
274 /* only draw the line if the color isn't set - this prevents a bug where the hline appears only under the expander */ |
| |
275 g_object_get(cellexpander, "cell-background-set", &set, NULL); |
| |
276 if (cell->is_expanded && !set) |
| |
277 gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0, |
| 275 widget->allocation.width, cell_area->y + cell_area->height); |
278 widget->allocation.width, cell_area->y + cell_area->height); |
| 276 } |
279 } |
| 277 |
280 |
| 278 static gboolean pidgin_cell_renderer_expander_activate(GtkCellRenderer *r, |
281 static gboolean pidgin_cell_renderer_expander_activate(GtkCellRenderer *r, |
| 279 GdkEvent *event, |
282 GdkEvent *event, |