1 | /* gtkcellrenderer.c |
2 | * Copyright (C) 2000 Red Hat, Inc. Jonathan Blandford |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Library General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Library General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Library General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | |
20 | #include "gtkcellrenderer.h" |
21 | |
22 | #include "gtkintl.h" |
23 | #include "gtkmarshalers.h" |
24 | #include "gtkprivate.h" |
25 | #include "gtksnapshot.h" |
26 | #include "gtkstylecontext.h" |
27 | #include "gtktreeprivate.h" |
28 | #include "gtktypebuiltins.h" |
29 | |
30 | /** |
31 | * GtkCellRenderer: |
32 | * |
33 | * An object for rendering a single cell |
34 | * |
35 | * The `GtkCellRenderer` is a base class of a set of objects used for |
36 | * rendering a cell to a `cairo_t`. These objects are used primarily by |
37 | * the `GtkTreeView` widget, though they aren’t tied to them in any |
38 | * specific way. It is worth noting that `GtkCellRenderer` is not a |
39 | * `GtkWidget` and cannot be treated as such. |
40 | * |
41 | * The primary use of a `GtkCellRenderer` is for drawing a certain graphical |
42 | * elements on a `cairo_t`. Typically, one cell renderer is used to |
43 | * draw many cells on the screen. To this extent, it isn’t expected that a |
44 | * CellRenderer keep any permanent state around. Instead, any state is set |
45 | * just prior to use using `GObject`s property system. Then, the |
46 | * cell is measured using gtk_cell_renderer_get_preferred_size(). Finally, the cell |
47 | * is rendered in the correct location using gtk_cell_renderer_snapshot(). |
48 | * |
49 | * There are a number of rules that must be followed when writing a new |
50 | * `GtkCellRenderer`. First and foremost, it’s important that a certain set |
51 | * of properties will always yield a cell renderer of the same size, |
52 | * barring a style change. The `GtkCellRenderer` also has a number of |
53 | * generic properties that are expected to be honored by all children. |
54 | * |
55 | * Beyond merely rendering a cell, cell renderers can optionally |
56 | * provide active user interface elements. A cell renderer can be |
57 | * “activatable” like `GtkCellRenderer`Toggle, |
58 | * which toggles when it gets activated by a mouse click, or it can be |
59 | * “editable” like `GtkCellRenderer`Text, which |
60 | * allows the user to edit the text using a widget implementing the |
61 | * `GtkCellEditable` interface, e.g. `GtkEntry`. |
62 | * To make a cell renderer activatable or editable, you have to |
63 | * implement the `GtkCellRenderer`Class.activate or |
64 | * `GtkCellRenderer`Class.start_editing virtual functions, respectively. |
65 | * |
66 | * Many properties of `GtkCellRenderer` and its subclasses have a |
67 | * corresponding “set” property, e.g. “cell-background-set” corresponds |
68 | * to “cell-background”. These “set” properties reflect whether a property |
69 | * has been set or not. You should not set them independently. |
70 | */ |
71 | |
72 | |
73 | #define DEBUG_CELL_SIZE_REQUEST 0 |
74 | |
75 | static void gtk_cell_renderer_init (GtkCellRenderer *cell); |
76 | static void gtk_cell_renderer_class_init (GtkCellRendererClass *class); |
77 | static void gtk_cell_renderer_get_property (GObject *object, |
78 | guint param_id, |
79 | GValue *value, |
80 | GParamSpec *pspec); |
81 | static void gtk_cell_renderer_set_property (GObject *object, |
82 | guint param_id, |
83 | const GValue *value, |
84 | GParamSpec *pspec); |
85 | static void set_cell_bg_color (GtkCellRenderer *cell, |
86 | GdkRGBA *rgba); |
87 | |
88 | static GtkSizeRequestMode gtk_cell_renderer_real_get_request_mode(GtkCellRenderer *cell); |
89 | static void gtk_cell_renderer_real_get_preferred_width (GtkCellRenderer *cell, |
90 | GtkWidget *widget, |
91 | int *minimum_size, |
92 | int *natural_size); |
93 | static void gtk_cell_renderer_real_get_preferred_height (GtkCellRenderer *cell, |
94 | GtkWidget *widget, |
95 | int *minimum_size, |
96 | int *natural_size); |
97 | static void gtk_cell_renderer_real_get_preferred_height_for_width(GtkCellRenderer *cell, |
98 | GtkWidget *widget, |
99 | int width, |
100 | int *minimum_height, |
101 | int *natural_height); |
102 | static void gtk_cell_renderer_real_get_preferred_width_for_height(GtkCellRenderer *cell, |
103 | GtkWidget *widget, |
104 | int height, |
105 | int *minimum_width, |
106 | int *natural_width); |
107 | static void gtk_cell_renderer_real_get_aligned_area (GtkCellRenderer *cell, |
108 | GtkWidget *widget, |
109 | GtkCellRendererState flags, |
110 | const GdkRectangle *cell_area, |
111 | GdkRectangle *aligned_area); |
112 | |
113 | |
114 | struct _GtkCellRendererPrivate |
115 | { |
116 | float xalign; |
117 | float yalign; |
118 | |
119 | int width; |
120 | int height; |
121 | |
122 | guint16 xpad; |
123 | guint16 ypad; |
124 | |
125 | guint mode : 2; |
126 | guint visible : 1; |
127 | guint is_expander : 1; |
128 | guint is_expanded : 1; |
129 | guint cell_background_set : 1; |
130 | guint sensitive : 1; |
131 | guint editing : 1; |
132 | |
133 | GdkRGBA cell_background; |
134 | }; |
135 | |
136 | enum { |
137 | PROP_0, |
138 | PROP_MODE, |
139 | PROP_VISIBLE, |
140 | PROP_SENSITIVE, |
141 | PROP_XALIGN, |
142 | PROP_YALIGN, |
143 | PROP_XPAD, |
144 | PROP_YPAD, |
145 | PROP_WIDTH, |
146 | PROP_HEIGHT, |
147 | PROP_IS_EXPANDER, |
148 | PROP_IS_EXPANDED, |
149 | PROP_CELL_BACKGROUND, |
150 | PROP_CELL_BACKGROUND_RGBA, |
151 | PROP_CELL_BACKGROUND_SET, |
152 | PROP_EDITING |
153 | }; |
154 | |
155 | /* Signal IDs */ |
156 | enum { |
157 | EDITING_CANCELED, |
158 | EDITING_STARTED, |
159 | LAST_SIGNAL |
160 | }; |
161 | |
162 | static int GtkCellRenderer_private_offset; |
163 | static guint cell_renderer_signals[LAST_SIGNAL] = { 0 }; |
164 | |
165 | static inline gpointer |
166 | gtk_cell_renderer_get_instance_private (GtkCellRenderer *self) |
167 | { |
168 | return (G_STRUCT_MEMBER_P (self, GtkCellRenderer_private_offset)); |
169 | } |
170 | |
171 | static void |
172 | gtk_cell_renderer_init (GtkCellRenderer *cell) |
173 | { |
174 | GtkCellRendererPrivate *priv; |
175 | |
176 | cell->priv = gtk_cell_renderer_get_instance_private (self: cell); |
177 | priv = cell->priv; |
178 | |
179 | priv->mode = GTK_CELL_RENDERER_MODE_INERT; |
180 | priv->visible = TRUE; |
181 | priv->width = -1; |
182 | priv->height = -1; |
183 | priv->xalign = 0.5; |
184 | priv->yalign = 0.5; |
185 | priv->xpad = 0; |
186 | priv->ypad = 0; |
187 | priv->sensitive = TRUE; |
188 | priv->is_expander = FALSE; |
189 | priv->is_expanded = FALSE; |
190 | priv->editing = FALSE; |
191 | } |
192 | |
193 | static void |
194 | gtk_cell_renderer_class_init (GtkCellRendererClass *class) |
195 | { |
196 | GObjectClass *object_class = G_OBJECT_CLASS (class); |
197 | |
198 | object_class->get_property = gtk_cell_renderer_get_property; |
199 | object_class->set_property = gtk_cell_renderer_set_property; |
200 | |
201 | class->snapshot = NULL; |
202 | class->get_request_mode = gtk_cell_renderer_real_get_request_mode; |
203 | class->get_preferred_width = gtk_cell_renderer_real_get_preferred_width; |
204 | class->get_preferred_height = gtk_cell_renderer_real_get_preferred_height; |
205 | class->get_preferred_width_for_height = gtk_cell_renderer_real_get_preferred_width_for_height; |
206 | class->get_preferred_height_for_width = gtk_cell_renderer_real_get_preferred_height_for_width; |
207 | class->get_aligned_area = gtk_cell_renderer_real_get_aligned_area; |
208 | |
209 | /** |
210 | * GtkCellRenderer::editing-canceled: |
211 | * @renderer: the object which received the signal |
212 | * |
213 | * This signal gets emitted when the user cancels the process of editing a |
214 | * cell. For example, an editable cell renderer could be written to cancel |
215 | * editing when the user presses Escape. |
216 | * |
217 | * See also: gtk_cell_renderer_stop_editing(). |
218 | */ |
219 | cell_renderer_signals[EDITING_CANCELED] = |
220 | g_signal_new (I_("editing-canceled" ), |
221 | G_OBJECT_CLASS_TYPE (object_class), |
222 | signal_flags: G_SIGNAL_RUN_FIRST, |
223 | G_STRUCT_OFFSET (GtkCellRendererClass, editing_canceled), |
224 | NULL, NULL, |
225 | NULL, |
226 | G_TYPE_NONE, n_params: 0); |
227 | |
228 | /** |
229 | * GtkCellRenderer::editing-started: |
230 | * @renderer: the object which received the signal |
231 | * @editable: the `GtkCellEditable` |
232 | * @path: the path identifying the edited cell |
233 | * |
234 | * This signal gets emitted when a cell starts to be edited. |
235 | * The intended use of this signal is to do special setup |
236 | * on @editable, e.g. adding a `GtkEntryCompletion` or setting |
237 | * up additional columns in a `GtkComboBox`. |
238 | * |
239 | * See gtk_cell_editable_start_editing() for information on the lifecycle of |
240 | * the @editable and a way to do setup that doesn’t depend on the @renderer. |
241 | * |
242 | * Note that GTK doesn't guarantee that cell renderers will |
243 | * continue to use the same kind of widget for editing in future |
244 | * releases, therefore you should check the type of @editable |
245 | * before doing any specific setup, as in the following example: |
246 | * |[<!-- language="C" --> |
247 | * static void |
248 | * text_editing_started (GtkCellRenderer *cell, |
249 | * GtkCellEditable *editable, |
250 | * const char *path, |
251 | * gpointer data) |
252 | * { |
253 | * if (GTK_IS_ENTRY (editable)) |
254 | * { |
255 | * GtkEntry *entry = GTK_ENTRY (editable); |
256 | * |
257 | * // ... create a GtkEntryCompletion |
258 | * |
259 | * gtk_entry_set_completion (entry, completion); |
260 | * } |
261 | * } |
262 | * ]| |
263 | */ |
264 | cell_renderer_signals[EDITING_STARTED] = |
265 | g_signal_new (I_("editing-started" ), |
266 | G_OBJECT_CLASS_TYPE (object_class), |
267 | signal_flags: G_SIGNAL_RUN_FIRST, |
268 | G_STRUCT_OFFSET (GtkCellRendererClass, editing_started), |
269 | NULL, NULL, |
270 | c_marshaller: _gtk_marshal_VOID__OBJECT_STRING, |
271 | G_TYPE_NONE, n_params: 2, |
272 | GTK_TYPE_CELL_EDITABLE, |
273 | G_TYPE_STRING); |
274 | g_signal_set_va_marshaller (cell_renderer_signals[EDITING_STARTED], |
275 | G_TYPE_FROM_CLASS (object_class), |
276 | _gtk_marshal_VOID__OBJECT_STRINGv); |
277 | |
278 | g_object_class_install_property (object_class, |
279 | PROP_MODE, |
280 | g_param_spec_enum ("mode" , |
281 | P_("mode" ), |
282 | P_("Editable mode of the CellRenderer" ), |
283 | GTK_TYPE_CELL_RENDERER_MODE, |
284 | GTK_CELL_RENDERER_MODE_INERT, |
285 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
286 | |
287 | g_object_class_install_property (oclass: object_class, |
288 | property_id: PROP_VISIBLE, |
289 | pspec: g_param_spec_boolean (name: "visible" , |
290 | P_("visible" ), |
291 | P_("Display the cell" ), |
292 | TRUE, |
293 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
294 | g_object_class_install_property (oclass: object_class, |
295 | property_id: PROP_SENSITIVE, |
296 | pspec: g_param_spec_boolean (name: "sensitive" , |
297 | P_("Sensitive" ), |
298 | P_("Display the cell sensitive" ), |
299 | TRUE, |
300 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
301 | |
302 | g_object_class_install_property (oclass: object_class, |
303 | property_id: PROP_XALIGN, |
304 | pspec: g_param_spec_float (name: "xalign" , |
305 | P_("xalign" ), |
306 | P_("The x-align" ), |
307 | minimum: 0.0, |
308 | maximum: 1.0, |
309 | default_value: 0.5, |
310 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
311 | |
312 | g_object_class_install_property (oclass: object_class, |
313 | property_id: PROP_YALIGN, |
314 | pspec: g_param_spec_float (name: "yalign" , |
315 | P_("yalign" ), |
316 | P_("The y-align" ), |
317 | minimum: 0.0, |
318 | maximum: 1.0, |
319 | default_value: 0.5, |
320 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
321 | |
322 | g_object_class_install_property (oclass: object_class, |
323 | property_id: PROP_XPAD, |
324 | pspec: g_param_spec_uint (name: "xpad" , |
325 | P_("xpad" ), |
326 | P_("The xpad" ), |
327 | minimum: 0, |
328 | G_MAXUINT, |
329 | default_value: 0, |
330 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
331 | |
332 | g_object_class_install_property (oclass: object_class, |
333 | property_id: PROP_YPAD, |
334 | pspec: g_param_spec_uint (name: "ypad" , |
335 | P_("ypad" ), |
336 | P_("The ypad" ), |
337 | minimum: 0, |
338 | G_MAXUINT, |
339 | default_value: 0, |
340 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
341 | |
342 | g_object_class_install_property (oclass: object_class, |
343 | property_id: PROP_WIDTH, |
344 | pspec: g_param_spec_int (name: "width" , |
345 | P_("width" ), |
346 | P_("The fixed width" ), |
347 | minimum: -1, |
348 | G_MAXINT, |
349 | default_value: -1, |
350 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
351 | |
352 | g_object_class_install_property (oclass: object_class, |
353 | property_id: PROP_HEIGHT, |
354 | pspec: g_param_spec_int (name: "height" , |
355 | P_("height" ), |
356 | P_("The fixed height" ), |
357 | minimum: -1, |
358 | G_MAXINT, |
359 | default_value: -1, |
360 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
361 | |
362 | g_object_class_install_property (oclass: object_class, |
363 | property_id: PROP_IS_EXPANDER, |
364 | pspec: g_param_spec_boolean (name: "is-expander" , |
365 | P_("Is Expander" ), |
366 | P_("Row has children" ), |
367 | FALSE, |
368 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
369 | |
370 | |
371 | g_object_class_install_property (oclass: object_class, |
372 | property_id: PROP_IS_EXPANDED, |
373 | pspec: g_param_spec_boolean (name: "is-expanded" , |
374 | P_("Is Expanded" ), |
375 | P_("Row is an expander row, and is expanded" ), |
376 | FALSE, |
377 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
378 | |
379 | g_object_class_install_property (oclass: object_class, |
380 | property_id: PROP_CELL_BACKGROUND, |
381 | pspec: g_param_spec_string (name: "cell-background" , |
382 | P_("Cell background color name" ), |
383 | P_("Cell background color as a string" ), |
384 | NULL, |
385 | GTK_PARAM_WRITABLE)); |
386 | |
387 | /** |
388 | * GtkCellRenderer:cell-background-rgba: |
389 | * |
390 | * Cell background as a `GdkRGBA` |
391 | */ |
392 | g_object_class_install_property (oclass: object_class, |
393 | property_id: PROP_CELL_BACKGROUND_RGBA, |
394 | pspec: g_param_spec_boxed (name: "cell-background-rgba" , |
395 | P_("Cell background RGBA color" ), |
396 | P_("Cell background color as a GdkRGBA" ), |
397 | GDK_TYPE_RGBA, |
398 | GTK_PARAM_READWRITE)); |
399 | |
400 | g_object_class_install_property (oclass: object_class, |
401 | property_id: PROP_EDITING, |
402 | pspec: g_param_spec_boolean (name: "editing" , |
403 | P_("Editing" ), |
404 | P_("Whether the cell renderer is currently in editing mode" ), |
405 | FALSE, |
406 | GTK_PARAM_READABLE)); |
407 | |
408 | |
409 | #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)) |
410 | |
411 | ADD_SET_PROP ("cell-background-set" , PROP_CELL_BACKGROUND_SET, |
412 | P_("Cell background set" ), |
413 | P_("Whether the cell background color is set" )); |
414 | |
415 | if (GtkCellRenderer_private_offset != 0) |
416 | g_type_class_adjust_private_offset (g_class: class, private_size_or_offset: &GtkCellRenderer_private_offset); |
417 | } |
418 | |
419 | GType |
420 | gtk_cell_renderer_get_type (void) |
421 | { |
422 | static GType cell_renderer_type = 0; |
423 | |
424 | if (G_UNLIKELY (cell_renderer_type == 0)) |
425 | { |
426 | const GTypeInfo cell_renderer_info = |
427 | { |
428 | sizeof (GtkCellRendererClass), |
429 | NULL, |
430 | NULL, |
431 | (GClassInitFunc) gtk_cell_renderer_class_init, |
432 | NULL, /* class_finalize */ |
433 | NULL, /* class_init */ |
434 | sizeof (GtkWidget), |
435 | 0, /* n_preallocs */ |
436 | (GInstanceInitFunc) gtk_cell_renderer_init, |
437 | NULL, /* value_table */ |
438 | }; |
439 | cell_renderer_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, type_name: "GtkCellRenderer" , |
440 | info: &cell_renderer_info, flags: G_TYPE_FLAG_ABSTRACT); |
441 | |
442 | GtkCellRenderer_private_offset = |
443 | g_type_add_instance_private (class_type: cell_renderer_type, private_size: sizeof (GtkCellRendererPrivate)); |
444 | } |
445 | |
446 | return cell_renderer_type; |
447 | } |
448 | |
449 | static void |
450 | gtk_cell_renderer_get_property (GObject *object, |
451 | guint param_id, |
452 | GValue *value, |
453 | GParamSpec *pspec) |
454 | { |
455 | GtkCellRenderer *cell = GTK_CELL_RENDERER (object); |
456 | GtkCellRendererPrivate *priv = cell->priv; |
457 | |
458 | switch (param_id) |
459 | { |
460 | case PROP_MODE: |
461 | g_value_set_enum (value, v_enum: priv->mode); |
462 | break; |
463 | case PROP_VISIBLE: |
464 | g_value_set_boolean (value, v_boolean: priv->visible); |
465 | break; |
466 | case PROP_SENSITIVE: |
467 | g_value_set_boolean (value, v_boolean: priv->sensitive); |
468 | break; |
469 | case PROP_EDITING: |
470 | g_value_set_boolean (value, v_boolean: priv->editing); |
471 | break; |
472 | case PROP_XALIGN: |
473 | g_value_set_float (value, v_float: priv->xalign); |
474 | break; |
475 | case PROP_YALIGN: |
476 | g_value_set_float (value, v_float: priv->yalign); |
477 | break; |
478 | case PROP_XPAD: |
479 | g_value_set_uint (value, v_uint: priv->xpad); |
480 | break; |
481 | case PROP_YPAD: |
482 | g_value_set_uint (value, v_uint: priv->ypad); |
483 | break; |
484 | case PROP_WIDTH: |
485 | g_value_set_int (value, v_int: priv->width); |
486 | break; |
487 | case PROP_HEIGHT: |
488 | g_value_set_int (value, v_int: priv->height); |
489 | break; |
490 | case PROP_IS_EXPANDER: |
491 | g_value_set_boolean (value, v_boolean: priv->is_expander); |
492 | break; |
493 | case PROP_IS_EXPANDED: |
494 | g_value_set_boolean (value, v_boolean: priv->is_expanded); |
495 | break; |
496 | case PROP_CELL_BACKGROUND_RGBA: |
497 | g_value_set_boxed (value, v_boxed: &priv->cell_background); |
498 | break; |
499 | case PROP_CELL_BACKGROUND_SET: |
500 | g_value_set_boolean (value, v_boolean: priv->cell_background_set); |
501 | break; |
502 | case PROP_CELL_BACKGROUND: |
503 | default: |
504 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
505 | break; |
506 | } |
507 | |
508 | } |
509 | |
510 | static void |
511 | gtk_cell_renderer_set_property (GObject *object, |
512 | guint param_id, |
513 | const GValue *value, |
514 | GParamSpec *pspec) |
515 | { |
516 | GtkCellRenderer *cell = GTK_CELL_RENDERER (object); |
517 | GtkCellRendererPrivate *priv = cell->priv; |
518 | |
519 | switch (param_id) |
520 | { |
521 | case PROP_MODE: |
522 | if (priv->mode != g_value_get_enum (value)) |
523 | { |
524 | priv->mode = g_value_get_enum (value); |
525 | g_object_notify_by_pspec (object, pspec); |
526 | } |
527 | break; |
528 | case PROP_VISIBLE: |
529 | if (priv->visible != g_value_get_boolean (value)) |
530 | { |
531 | priv->visible = g_value_get_boolean (value); |
532 | g_object_notify_by_pspec (object, pspec); |
533 | } |
534 | break; |
535 | case PROP_SENSITIVE: |
536 | if (priv->sensitive != g_value_get_boolean (value)) |
537 | { |
538 | priv->sensitive = g_value_get_boolean (value); |
539 | g_object_notify_by_pspec (object, pspec); |
540 | } |
541 | break; |
542 | case PROP_XALIGN: |
543 | if (priv->xalign != g_value_get_float (value)) |
544 | { |
545 | priv->xalign = g_value_get_float (value); |
546 | g_object_notify_by_pspec (object, pspec); |
547 | } |
548 | break; |
549 | case PROP_YALIGN: |
550 | if (priv->yalign != g_value_get_float (value)) |
551 | { |
552 | priv->yalign = g_value_get_float (value); |
553 | g_object_notify_by_pspec (object, pspec); |
554 | } |
555 | break; |
556 | case PROP_XPAD: |
557 | if (priv->xpad != g_value_get_uint (value)) |
558 | { |
559 | priv->xpad = g_value_get_uint (value); |
560 | g_object_notify_by_pspec (object, pspec); |
561 | } |
562 | break; |
563 | case PROP_YPAD: |
564 | if (priv->ypad != g_value_get_uint (value)) |
565 | { |
566 | priv->ypad = g_value_get_uint (value); |
567 | g_object_notify_by_pspec (object, pspec); |
568 | } |
569 | break; |
570 | case PROP_WIDTH: |
571 | if (priv->width != g_value_get_int (value)) |
572 | { |
573 | priv->width = g_value_get_int (value); |
574 | g_object_notify_by_pspec (object, pspec); |
575 | } |
576 | break; |
577 | case PROP_HEIGHT: |
578 | if (priv->height != g_value_get_int (value)) |
579 | { |
580 | priv->height = g_value_get_int (value); |
581 | g_object_notify_by_pspec (object, pspec); |
582 | } |
583 | break; |
584 | case PROP_IS_EXPANDER: |
585 | if (priv->is_expander != g_value_get_boolean (value)) |
586 | { |
587 | priv->is_expander = g_value_get_boolean (value); |
588 | g_object_notify_by_pspec (object, pspec); |
589 | } |
590 | break; |
591 | case PROP_IS_EXPANDED: |
592 | if (priv->is_expanded != g_value_get_boolean (value)) |
593 | { |
594 | priv->is_expanded = g_value_get_boolean (value); |
595 | g_object_notify_by_pspec (object, pspec); |
596 | } |
597 | break; |
598 | case PROP_CELL_BACKGROUND: |
599 | { |
600 | GdkRGBA rgba; |
601 | |
602 | if (!g_value_get_string (value)) |
603 | set_cell_bg_color (cell, NULL); |
604 | else if (gdk_rgba_parse (rgba: &rgba, spec: g_value_get_string (value))) |
605 | set_cell_bg_color (cell, rgba: &rgba); |
606 | else |
607 | g_warning ("Don't know color '%s'" , g_value_get_string (value)); |
608 | |
609 | g_object_notify (object, property_name: "cell-background" ); |
610 | } |
611 | break; |
612 | case PROP_CELL_BACKGROUND_RGBA: |
613 | set_cell_bg_color (cell, rgba: g_value_get_boxed (value)); |
614 | break; |
615 | case PROP_CELL_BACKGROUND_SET: |
616 | if (priv->cell_background_set != g_value_get_boolean (value)) |
617 | { |
618 | priv->cell_background_set = g_value_get_boolean (value); |
619 | g_object_notify (object, property_name: "cell-background-set" ); |
620 | } |
621 | break; |
622 | default: |
623 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
624 | break; |
625 | } |
626 | } |
627 | |
628 | static void |
629 | set_cell_bg_color (GtkCellRenderer *cell, |
630 | GdkRGBA *rgba) |
631 | { |
632 | GtkCellRendererPrivate *priv = cell->priv; |
633 | |
634 | if (rgba) |
635 | { |
636 | if (!priv->cell_background_set) |
637 | { |
638 | priv->cell_background_set = TRUE; |
639 | g_object_notify (G_OBJECT (cell), property_name: "cell-background-set" ); |
640 | } |
641 | |
642 | priv->cell_background = *rgba; |
643 | } |
644 | else |
645 | { |
646 | if (priv->cell_background_set) |
647 | { |
648 | priv->cell_background_set = FALSE; |
649 | g_object_notify (G_OBJECT (cell), property_name: "cell-background-set" ); |
650 | } |
651 | } |
652 | g_object_notify (G_OBJECT (cell), property_name: "cell-background-rgba" ); |
653 | } |
654 | |
655 | /** |
656 | * gtk_cell_renderer_snapshot: |
657 | * @cell: a `GtkCellRenderer` |
658 | * @snapshot: a `GtkSnapshot` to draw to |
659 | * @widget: the widget owning @window |
660 | * @background_area: entire cell area (including tree expanders and maybe |
661 | * padding on the sides) |
662 | * @cell_area: area normally rendered by a cell renderer |
663 | * @flags: flags that affect rendering |
664 | * |
665 | * Invokes the virtual render function of the `GtkCellRenderer`. The three |
666 | * passed-in rectangles are areas in @cr. Most renderers will draw within |
667 | * @cell_area; the xalign, yalign, xpad, and ypad fields of the `GtkCellRenderer` |
668 | * should be honored with respect to @cell_area. @background_area includes the |
669 | * blank space around the cell, and also the area containing the tree expander; |
670 | * so the @background_area rectangles for all cells tile to cover the entire |
671 | * @window. |
672 | **/ |
673 | void |
674 | gtk_cell_renderer_snapshot (GtkCellRenderer *cell, |
675 | GtkSnapshot *snapshot, |
676 | GtkWidget *widget, |
677 | const GdkRectangle *background_area, |
678 | const GdkRectangle *cell_area, |
679 | GtkCellRendererState flags) |
680 | { |
681 | gboolean selected = FALSE; |
682 | GtkCellRendererPrivate *priv = cell->priv; |
683 | GtkStyleContext *context; |
684 | GtkStateFlags state; |
685 | |
686 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
687 | g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot != NULL); |
688 | g_return_if_fail (snapshot != NULL); |
689 | |
690 | selected = (flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED; |
691 | |
692 | gtk_snapshot_push_debug (snapshot, message: "%s" , G_OBJECT_TYPE_NAME (cell)); |
693 | |
694 | if (priv->cell_background_set && !selected) |
695 | { |
696 | gtk_snapshot_append_color (snapshot, |
697 | color: &priv->cell_background, |
698 | bounds: &GRAPHENE_RECT_INIT ( |
699 | background_area->x, background_area->y, |
700 | background_area->width, background_area->height |
701 | )); |
702 | } |
703 | |
704 | gtk_snapshot_push_clip (snapshot, |
705 | bounds: &GRAPHENE_RECT_INIT ( |
706 | background_area->x, background_area->y, |
707 | background_area->width, background_area->height |
708 | )); |
709 | |
710 | context = gtk_widget_get_style_context (widget); |
711 | |
712 | gtk_style_context_save (context); |
713 | gtk_style_context_add_class (context, class_name: "cell" ); |
714 | |
715 | state = gtk_cell_renderer_get_state (cell, widget, cell_state: flags); |
716 | gtk_style_context_set_state (context, flags: state); |
717 | |
718 | GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot (cell, |
719 | snapshot, |
720 | widget, |
721 | background_area, |
722 | cell_area, |
723 | flags); |
724 | gtk_style_context_restore (context); |
725 | gtk_snapshot_pop (snapshot); |
726 | gtk_snapshot_pop (snapshot); |
727 | } |
728 | |
729 | /** |
730 | * gtk_cell_renderer_activate: |
731 | * @cell: a `GtkCellRenderer` |
732 | * @event: a `GdkEvent` |
733 | * @widget: widget that received the event |
734 | * @path: widget-dependent string representation of the event location; |
735 | * e.g. for `GtkTreeView`, a string representation of `GtkTreePath` |
736 | * @background_area: background area as passed to gtk_cell_renderer_render() |
737 | * @cell_area: cell area as passed to gtk_cell_renderer_render() |
738 | * @flags: render flags |
739 | * |
740 | * Passes an activate event to the cell renderer for possible processing. |
741 | * Some cell renderers may use events; for example, `GtkCellRendererToggle` |
742 | * toggles when it gets a mouse click. |
743 | * |
744 | * Returns: %TRUE if the event was consumed/handled |
745 | **/ |
746 | gboolean |
747 | gtk_cell_renderer_activate (GtkCellRenderer *cell, |
748 | GdkEvent *event, |
749 | GtkWidget *widget, |
750 | const char *path, |
751 | const GdkRectangle *background_area, |
752 | const GdkRectangle *cell_area, |
753 | GtkCellRendererState flags) |
754 | { |
755 | GtkCellRendererPrivate *priv; |
756 | |
757 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
758 | |
759 | priv = cell->priv; |
760 | |
761 | if (priv->mode != GTK_CELL_RENDERER_MODE_ACTIVATABLE) |
762 | return FALSE; |
763 | |
764 | if (GTK_CELL_RENDERER_GET_CLASS (cell)->activate == NULL) |
765 | return FALSE; |
766 | |
767 | return GTK_CELL_RENDERER_GET_CLASS (cell)->activate (cell, |
768 | event, |
769 | widget, |
770 | path, |
771 | (GdkRectangle *) background_area, |
772 | (GdkRectangle *) cell_area, |
773 | flags); |
774 | } |
775 | |
776 | /** |
777 | * gtk_cell_renderer_start_editing: |
778 | * @cell: a `GtkCellRenderer` |
779 | * @event: (nullable): a `GdkEvent` |
780 | * @widget: widget that received the event |
781 | * @path: widget-dependent string representation of the event location; |
782 | * e.g. for `GtkTreeView`, a string representation of `GtkTreePath` |
783 | * @background_area: background area as passed to gtk_cell_renderer_render() |
784 | * @cell_area: cell area as passed to gtk_cell_renderer_render() |
785 | * @flags: render flags |
786 | * |
787 | * Starts editing the contents of this @cell, through a new `GtkCellEditable` |
788 | * widget created by the `GtkCellRenderer`Class.start_editing virtual function. |
789 | * |
790 | * Returns: (nullable) (transfer none): A new `GtkCellEditable` for editing this |
791 | * @cell, or %NULL if editing is not possible |
792 | **/ |
793 | GtkCellEditable * |
794 | gtk_cell_renderer_start_editing (GtkCellRenderer *cell, |
795 | GdkEvent *event, |
796 | GtkWidget *widget, |
797 | const char *path, |
798 | const GdkRectangle *background_area, |
799 | const GdkRectangle *cell_area, |
800 | GtkCellRendererState flags) |
801 | |
802 | { |
803 | GtkCellRendererPrivate *priv; |
804 | GtkCellEditable *editable; |
805 | |
806 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), NULL); |
807 | |
808 | priv = cell->priv; |
809 | |
810 | if (priv->mode != GTK_CELL_RENDERER_MODE_EDITABLE) |
811 | return NULL; |
812 | |
813 | if (GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing == NULL) |
814 | return NULL; |
815 | |
816 | editable = GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing (cell, |
817 | event, |
818 | widget, |
819 | path, |
820 | (GdkRectangle *) background_area, |
821 | (GdkRectangle *) cell_area, |
822 | flags); |
823 | if (editable == NULL) |
824 | return NULL; |
825 | |
826 | gtk_widget_add_css_class (GTK_WIDGET (editable), css_class: "cell" ); |
827 | |
828 | g_signal_emit (instance: cell, |
829 | signal_id: cell_renderer_signals[EDITING_STARTED], detail: 0, |
830 | editable, path); |
831 | |
832 | priv->editing = TRUE; |
833 | |
834 | return editable; |
835 | } |
836 | |
837 | /** |
838 | * gtk_cell_renderer_set_fixed_size: |
839 | * @cell: A `GtkCellRenderer` |
840 | * @width: the width of the cell renderer, or -1 |
841 | * @height: the height of the cell renderer, or -1 |
842 | * |
843 | * Sets the renderer size to be explicit, independent of the properties set. |
844 | **/ |
845 | void |
846 | gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell, |
847 | int width, |
848 | int height) |
849 | { |
850 | GtkCellRendererPrivate *priv; |
851 | |
852 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
853 | g_return_if_fail (width >= -1 && height >= -1); |
854 | |
855 | priv = cell->priv; |
856 | |
857 | if ((width != priv->width) || (height != priv->height)) |
858 | { |
859 | g_object_freeze_notify (G_OBJECT (cell)); |
860 | |
861 | if (width != priv->width) |
862 | { |
863 | priv->width = width; |
864 | g_object_notify (G_OBJECT (cell), property_name: "width" ); |
865 | } |
866 | |
867 | if (height != priv->height) |
868 | { |
869 | priv->height = height; |
870 | g_object_notify (G_OBJECT (cell), property_name: "height" ); |
871 | } |
872 | |
873 | g_object_thaw_notify (G_OBJECT (cell)); |
874 | } |
875 | } |
876 | |
877 | /** |
878 | * gtk_cell_renderer_get_fixed_size: |
879 | * @cell: A `GtkCellRenderer` |
880 | * @width: (out) (optional): location to fill in with the fixed width of the cell |
881 | * @height: (out) (optional): location to fill in with the fixed height of the cell |
882 | * |
883 | * Fills in @width and @height with the appropriate size of @cell. |
884 | */ |
885 | void |
886 | gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell, |
887 | int *width, |
888 | int *height) |
889 | { |
890 | GtkCellRendererPrivate *priv; |
891 | |
892 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
893 | |
894 | priv = cell->priv; |
895 | |
896 | if (width) |
897 | *width = priv->width; |
898 | if (height) |
899 | *height = priv->height; |
900 | } |
901 | |
902 | /** |
903 | * gtk_cell_renderer_set_alignment: |
904 | * @cell: A `GtkCellRenderer` |
905 | * @xalign: the x alignment of the cell renderer |
906 | * @yalign: the y alignment of the cell renderer |
907 | * |
908 | * Sets the renderer’s alignment within its available space. |
909 | **/ |
910 | void |
911 | gtk_cell_renderer_set_alignment (GtkCellRenderer *cell, |
912 | float xalign, |
913 | float yalign) |
914 | { |
915 | GtkCellRendererPrivate *priv; |
916 | |
917 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
918 | g_return_if_fail (xalign >= 0.0 && xalign <= 1.0); |
919 | g_return_if_fail (yalign >= 0.0 && yalign <= 1.0); |
920 | |
921 | priv = cell->priv; |
922 | |
923 | if ((xalign != priv->xalign) || (yalign != priv->yalign)) |
924 | { |
925 | g_object_freeze_notify (G_OBJECT (cell)); |
926 | |
927 | if (xalign != priv->xalign) |
928 | { |
929 | priv->xalign = xalign; |
930 | g_object_notify (G_OBJECT (cell), property_name: "xalign" ); |
931 | } |
932 | |
933 | if (yalign != priv->yalign) |
934 | { |
935 | priv->yalign = yalign; |
936 | g_object_notify (G_OBJECT (cell), property_name: "yalign" ); |
937 | } |
938 | |
939 | g_object_thaw_notify (G_OBJECT (cell)); |
940 | } |
941 | } |
942 | |
943 | /** |
944 | * gtk_cell_renderer_get_alignment: |
945 | * @cell: A `GtkCellRenderer` |
946 | * @xalign: (out) (optional): location to fill in with the x alignment of the cell |
947 | * @yalign: (out) (optional): location to fill in with the y alignment of the cell |
948 | * |
949 | * Fills in @xalign and @yalign with the appropriate values of @cell. |
950 | */ |
951 | void |
952 | gtk_cell_renderer_get_alignment (GtkCellRenderer *cell, |
953 | float *xalign, |
954 | float *yalign) |
955 | { |
956 | GtkCellRendererPrivate *priv; |
957 | |
958 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
959 | |
960 | priv = cell->priv; |
961 | |
962 | if (xalign) |
963 | *xalign = priv->xalign; |
964 | if (yalign) |
965 | *yalign = priv->yalign; |
966 | } |
967 | |
968 | /** |
969 | * gtk_cell_renderer_set_padding: |
970 | * @cell: A `GtkCellRenderer` |
971 | * @xpad: the x padding of the cell renderer |
972 | * @ypad: the y padding of the cell renderer |
973 | * |
974 | * Sets the renderer’s padding. |
975 | **/ |
976 | void |
977 | gtk_cell_renderer_set_padding (GtkCellRenderer *cell, |
978 | int xpad, |
979 | int ypad) |
980 | { |
981 | GtkCellRendererPrivate *priv; |
982 | |
983 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
984 | g_return_if_fail (xpad >= 0 && ypad >= 0); |
985 | |
986 | priv = cell->priv; |
987 | |
988 | if ((xpad != priv->xpad) || (ypad != priv->ypad)) |
989 | { |
990 | g_object_freeze_notify (G_OBJECT (cell)); |
991 | |
992 | if (xpad != priv->xpad) |
993 | { |
994 | priv->xpad = xpad; |
995 | g_object_notify (G_OBJECT (cell), property_name: "xpad" ); |
996 | } |
997 | |
998 | if (ypad != priv->ypad) |
999 | { |
1000 | priv->ypad = ypad; |
1001 | g_object_notify (G_OBJECT (cell), property_name: "ypad" ); |
1002 | } |
1003 | |
1004 | g_object_thaw_notify (G_OBJECT (cell)); |
1005 | } |
1006 | } |
1007 | |
1008 | /** |
1009 | * gtk_cell_renderer_get_padding: |
1010 | * @cell: A `GtkCellRenderer` |
1011 | * @xpad: (out) (optional): location to fill in with the x padding of the cell |
1012 | * @ypad: (out) (optional): location to fill in with the y padding of the cell |
1013 | * |
1014 | * Fills in @xpad and @ypad with the appropriate values of @cell. |
1015 | */ |
1016 | void |
1017 | gtk_cell_renderer_get_padding (GtkCellRenderer *cell, |
1018 | int *xpad, |
1019 | int *ypad) |
1020 | { |
1021 | GtkCellRendererPrivate *priv; |
1022 | |
1023 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1024 | |
1025 | priv = cell->priv; |
1026 | |
1027 | if (xpad) |
1028 | *xpad = priv->xpad; |
1029 | if (ypad) |
1030 | *ypad = priv->ypad; |
1031 | } |
1032 | |
1033 | /** |
1034 | * gtk_cell_renderer_set_visible: |
1035 | * @cell: A `GtkCellRenderer` |
1036 | * @visible: the visibility of the cell |
1037 | * |
1038 | * Sets the cell renderer’s visibility. |
1039 | **/ |
1040 | void |
1041 | gtk_cell_renderer_set_visible (GtkCellRenderer *cell, |
1042 | gboolean visible) |
1043 | { |
1044 | GtkCellRendererPrivate *priv; |
1045 | |
1046 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1047 | |
1048 | priv = cell->priv; |
1049 | |
1050 | if (priv->visible != visible) |
1051 | { |
1052 | priv->visible = visible ? TRUE : FALSE; |
1053 | g_object_notify (G_OBJECT (cell), property_name: "visible" ); |
1054 | } |
1055 | } |
1056 | |
1057 | /** |
1058 | * gtk_cell_renderer_get_visible: |
1059 | * @cell: A `GtkCellRenderer` |
1060 | * |
1061 | * Returns the cell renderer’s visibility. |
1062 | * |
1063 | * Returns: %TRUE if the cell renderer is visible |
1064 | */ |
1065 | gboolean |
1066 | gtk_cell_renderer_get_visible (GtkCellRenderer *cell) |
1067 | { |
1068 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
1069 | |
1070 | return cell->priv->visible; |
1071 | } |
1072 | |
1073 | /** |
1074 | * gtk_cell_renderer_set_sensitive: |
1075 | * @cell: A `GtkCellRenderer` |
1076 | * @sensitive: the sensitivity of the cell |
1077 | * |
1078 | * Sets the cell renderer’s sensitivity. |
1079 | **/ |
1080 | void |
1081 | gtk_cell_renderer_set_sensitive (GtkCellRenderer *cell, |
1082 | gboolean sensitive) |
1083 | { |
1084 | GtkCellRendererPrivate *priv; |
1085 | |
1086 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1087 | |
1088 | priv = cell->priv; |
1089 | |
1090 | if (priv->sensitive != sensitive) |
1091 | { |
1092 | priv->sensitive = sensitive ? TRUE : FALSE; |
1093 | g_object_notify (G_OBJECT (cell), property_name: "sensitive" ); |
1094 | } |
1095 | } |
1096 | |
1097 | /** |
1098 | * gtk_cell_renderer_get_sensitive: |
1099 | * @cell: A `GtkCellRenderer` |
1100 | * |
1101 | * Returns the cell renderer’s sensitivity. |
1102 | * |
1103 | * Returns: %TRUE if the cell renderer is sensitive |
1104 | */ |
1105 | gboolean |
1106 | gtk_cell_renderer_get_sensitive (GtkCellRenderer *cell) |
1107 | { |
1108 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
1109 | |
1110 | return cell->priv->sensitive; |
1111 | } |
1112 | |
1113 | |
1114 | /** |
1115 | * gtk_cell_renderer_is_activatable: |
1116 | * @cell: A `GtkCellRenderer` |
1117 | * |
1118 | * Checks whether the cell renderer can do something when activated. |
1119 | * |
1120 | * Returns: %TRUE if the cell renderer can do anything when activated |
1121 | */ |
1122 | gboolean |
1123 | gtk_cell_renderer_is_activatable (GtkCellRenderer *cell) |
1124 | { |
1125 | GtkCellRendererPrivate *priv; |
1126 | |
1127 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
1128 | |
1129 | priv = cell->priv; |
1130 | |
1131 | return (priv->visible && |
1132 | (priv->mode == GTK_CELL_RENDERER_MODE_EDITABLE || |
1133 | priv->mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)); |
1134 | } |
1135 | |
1136 | |
1137 | /** |
1138 | * gtk_cell_renderer_stop_editing: |
1139 | * @cell: A `GtkCellRenderer` |
1140 | * @canceled: %TRUE if the editing has been canceled |
1141 | * |
1142 | * Informs the cell renderer that the editing is stopped. |
1143 | * If @canceled is %TRUE, the cell renderer will emit the |
1144 | * `GtkCellRenderer`::editing-canceled signal. |
1145 | * |
1146 | * This function should be called by cell renderer implementations |
1147 | * in response to the `GtkCellEditable::editing-done` signal of |
1148 | * `GtkCellEditable`. |
1149 | **/ |
1150 | void |
1151 | gtk_cell_renderer_stop_editing (GtkCellRenderer *cell, |
1152 | gboolean canceled) |
1153 | { |
1154 | GtkCellRendererPrivate *priv; |
1155 | |
1156 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1157 | |
1158 | priv = cell->priv; |
1159 | |
1160 | if (priv->editing) |
1161 | { |
1162 | priv->editing = FALSE; |
1163 | if (canceled) |
1164 | g_signal_emit (instance: cell, signal_id: cell_renderer_signals[EDITING_CANCELED], detail: 0); |
1165 | } |
1166 | } |
1167 | |
1168 | static void |
1169 | gtk_cell_renderer_real_get_preferred_size (GtkCellRenderer *cell, |
1170 | GtkWidget *widget, |
1171 | GtkOrientation orientation, |
1172 | int *minimum_size, |
1173 | int *natural_size) |
1174 | { |
1175 | GtkRequisition min_req; |
1176 | |
1177 | min_req.width = 0; |
1178 | min_req.height = 0; |
1179 | |
1180 | if (orientation == GTK_ORIENTATION_HORIZONTAL) |
1181 | { |
1182 | if (minimum_size) |
1183 | *minimum_size = min_req.width; |
1184 | |
1185 | if (natural_size) |
1186 | *natural_size = min_req.width; |
1187 | } |
1188 | else |
1189 | { |
1190 | if (minimum_size) |
1191 | *minimum_size = min_req.height; |
1192 | |
1193 | if (natural_size) |
1194 | *natural_size = min_req.height; |
1195 | } |
1196 | } |
1197 | |
1198 | static GtkSizeRequestMode |
1199 | gtk_cell_renderer_real_get_request_mode (GtkCellRenderer *cell) |
1200 | { |
1201 | /* By default cell renderers are height-for-width. */ |
1202 | return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; |
1203 | } |
1204 | |
1205 | static void |
1206 | gtk_cell_renderer_real_get_preferred_width (GtkCellRenderer *cell, |
1207 | GtkWidget *widget, |
1208 | int *minimum_size, |
1209 | int *natural_size) |
1210 | { |
1211 | gtk_cell_renderer_real_get_preferred_size (cell, widget, orientation: GTK_ORIENTATION_HORIZONTAL, |
1212 | minimum_size, natural_size); |
1213 | } |
1214 | |
1215 | static void |
1216 | gtk_cell_renderer_real_get_preferred_height (GtkCellRenderer *cell, |
1217 | GtkWidget *widget, |
1218 | int *minimum_size, |
1219 | int *natural_size) |
1220 | { |
1221 | gtk_cell_renderer_real_get_preferred_size (cell, widget, orientation: GTK_ORIENTATION_VERTICAL, |
1222 | minimum_size, natural_size); |
1223 | } |
1224 | |
1225 | |
1226 | static void |
1227 | gtk_cell_renderer_real_get_preferred_height_for_width (GtkCellRenderer *cell, |
1228 | GtkWidget *widget, |
1229 | int width, |
1230 | int *minimum_height, |
1231 | int *natural_height) |
1232 | { |
1233 | gtk_cell_renderer_get_preferred_height (cell, widget, minimum_size: minimum_height, natural_size: natural_height); |
1234 | } |
1235 | |
1236 | static void |
1237 | gtk_cell_renderer_real_get_preferred_width_for_height (GtkCellRenderer *cell, |
1238 | GtkWidget *widget, |
1239 | int height, |
1240 | int *minimum_width, |
1241 | int *natural_width) |
1242 | { |
1243 | gtk_cell_renderer_get_preferred_width (cell, widget, minimum_size: minimum_width, natural_size: natural_width); |
1244 | } |
1245 | |
1246 | |
1247 | /* Default implementation assumes that a cell renderer will never use more |
1248 | * space than its natural size (this is fine for toggles and pixbufs etc |
1249 | * but needs to be overridden from wrapping/ellipsizing text renderers) */ |
1250 | static void |
1251 | gtk_cell_renderer_real_get_aligned_area (GtkCellRenderer *cell, |
1252 | GtkWidget *widget, |
1253 | GtkCellRendererState flags, |
1254 | const GdkRectangle *cell_area, |
1255 | GdkRectangle *aligned_area) |
1256 | { |
1257 | int opposite_size, x_offset, y_offset; |
1258 | int natural_size; |
1259 | |
1260 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1261 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
1262 | g_return_if_fail (cell_area != NULL); |
1263 | g_return_if_fail (aligned_area != NULL); |
1264 | |
1265 | *aligned_area = *cell_area; |
1266 | |
1267 | /* Trim up the aligned size */ |
1268 | if (gtk_cell_renderer_get_request_mode (cell) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH) |
1269 | { |
1270 | gtk_cell_renderer_get_preferred_width (cell, widget, |
1271 | NULL, natural_size: &natural_size); |
1272 | |
1273 | aligned_area->width = MIN (aligned_area->width, natural_size); |
1274 | |
1275 | gtk_cell_renderer_get_preferred_height_for_width (cell, widget, |
1276 | width: aligned_area->width, |
1277 | NULL, natural_height: &opposite_size); |
1278 | |
1279 | aligned_area->height = MIN (opposite_size, aligned_area->height); |
1280 | } |
1281 | else |
1282 | { |
1283 | gtk_cell_renderer_get_preferred_height (cell, widget, |
1284 | NULL, natural_size: &natural_size); |
1285 | |
1286 | aligned_area->height = MIN (aligned_area->width, natural_size); |
1287 | |
1288 | gtk_cell_renderer_get_preferred_width_for_height (cell, widget, |
1289 | height: aligned_area->height, |
1290 | NULL, natural_width: &opposite_size); |
1291 | |
1292 | aligned_area->width = MIN (opposite_size, aligned_area->width); |
1293 | } |
1294 | |
1295 | /* offset the cell position */ |
1296 | _gtk_cell_renderer_calc_offset (cell, cell_area, |
1297 | direction: gtk_widget_get_direction (widget), |
1298 | width: aligned_area->width, |
1299 | height: aligned_area->height, |
1300 | x_offset: &x_offset, y_offset: &y_offset); |
1301 | |
1302 | aligned_area->x += x_offset; |
1303 | aligned_area->y += y_offset; |
1304 | } |
1305 | |
1306 | |
1307 | /* An internal convenience function for some containers to peek at the |
1308 | * cell alignment in a target allocation (used to draw focus and align |
1309 | * cells in the icon view). |
1310 | * |
1311 | * Note this is only a trivial “align * (allocation - request)” operation. |
1312 | */ |
1313 | void |
1314 | _gtk_cell_renderer_calc_offset (GtkCellRenderer *cell, |
1315 | const GdkRectangle *cell_area, |
1316 | GtkTextDirection direction, |
1317 | int width, |
1318 | int height, |
1319 | int *x_offset, |
1320 | int *y_offset) |
1321 | { |
1322 | GtkCellRendererPrivate *priv; |
1323 | |
1324 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1325 | g_return_if_fail (cell_area != NULL); |
1326 | g_return_if_fail (x_offset || y_offset); |
1327 | |
1328 | priv = cell->priv; |
1329 | |
1330 | if (x_offset) |
1331 | { |
1332 | *x_offset = (((direction == GTK_TEXT_DIR_RTL) ? |
1333 | (1.0 - priv->xalign) : priv->xalign) * |
1334 | (cell_area->width - width)); |
1335 | *x_offset = MAX (*x_offset, 0); |
1336 | } |
1337 | if (y_offset) |
1338 | { |
1339 | *y_offset = (priv->yalign * |
1340 | (cell_area->height - height)); |
1341 | *y_offset = MAX (*y_offset, 0); |
1342 | } |
1343 | } |
1344 | |
1345 | /** |
1346 | * gtk_cell_renderer_get_request_mode: |
1347 | * @cell: a `GtkCellRenderer` instance |
1348 | * |
1349 | * Gets whether the cell renderer prefers a height-for-width layout |
1350 | * or a width-for-height layout. |
1351 | * |
1352 | * Returns: The `GtkSizeRequestMode` preferred by this renderer. |
1353 | */ |
1354 | GtkSizeRequestMode |
1355 | gtk_cell_renderer_get_request_mode (GtkCellRenderer *cell) |
1356 | { |
1357 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
1358 | |
1359 | return GTK_CELL_RENDERER_GET_CLASS (cell)->get_request_mode (cell); |
1360 | } |
1361 | |
1362 | /** |
1363 | * gtk_cell_renderer_get_preferred_width: |
1364 | * @cell: a `GtkCellRenderer` instance |
1365 | * @widget: the `GtkWidget` this cell will be rendering to |
1366 | * @minimum_size: (out) (optional): location to store the minimum size |
1367 | * @natural_size: (out) (optional): location to store the natural size |
1368 | * |
1369 | * Retrieves a renderer’s natural size when rendered to @widget. |
1370 | */ |
1371 | void |
1372 | gtk_cell_renderer_get_preferred_width (GtkCellRenderer *cell, |
1373 | GtkWidget *widget, |
1374 | int *minimum_size, |
1375 | int *natural_size) |
1376 | { |
1377 | GtkCellRendererClass *klass; |
1378 | int width; |
1379 | |
1380 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1381 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
1382 | g_return_if_fail (NULL != minimum_size || NULL != natural_size); |
1383 | |
1384 | gtk_cell_renderer_get_fixed_size (GTK_CELL_RENDERER (cell), width: &width, NULL); |
1385 | |
1386 | if (width < 0) |
1387 | { |
1388 | klass = GTK_CELL_RENDERER_GET_CLASS (cell); |
1389 | klass->get_preferred_width (cell, widget, minimum_size, natural_size); |
1390 | } |
1391 | else |
1392 | { |
1393 | if (minimum_size) |
1394 | *minimum_size = width; |
1395 | if (natural_size) |
1396 | *natural_size = width; |
1397 | } |
1398 | |
1399 | #if DEBUG_CELL_SIZE_REQUEST |
1400 | g_message ("%s returning minimum width: %d and natural width: %d" , |
1401 | G_OBJECT_TYPE_NAME (cell), |
1402 | minimum_size ? *minimum_size : 20000, |
1403 | natural_size ? *natural_size : 20000); |
1404 | #endif |
1405 | } |
1406 | |
1407 | |
1408 | /** |
1409 | * gtk_cell_renderer_get_preferred_height: |
1410 | * @cell: a `GtkCellRenderer` instance |
1411 | * @widget: the `GtkWidget` this cell will be rendering to |
1412 | * @minimum_size: (out) (optional): location to store the minimum size |
1413 | * @natural_size: (out) (optional): location to store the natural size |
1414 | * |
1415 | * Retrieves a renderer’s natural size when rendered to @widget. |
1416 | */ |
1417 | void |
1418 | gtk_cell_renderer_get_preferred_height (GtkCellRenderer *cell, |
1419 | GtkWidget *widget, |
1420 | int *minimum_size, |
1421 | int *natural_size) |
1422 | { |
1423 | GtkCellRendererClass *klass; |
1424 | int height; |
1425 | |
1426 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1427 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
1428 | g_return_if_fail (NULL != minimum_size || NULL != natural_size); |
1429 | |
1430 | gtk_cell_renderer_get_fixed_size (GTK_CELL_RENDERER (cell), NULL, height: &height); |
1431 | |
1432 | if (height < 0) |
1433 | { |
1434 | klass = GTK_CELL_RENDERER_GET_CLASS (cell); |
1435 | klass->get_preferred_height (cell, widget, minimum_size, natural_size); |
1436 | } |
1437 | else |
1438 | { |
1439 | if (minimum_size) |
1440 | *minimum_size = height; |
1441 | if (natural_size) |
1442 | *natural_size = height; |
1443 | } |
1444 | |
1445 | #if DEBUG_CELL_SIZE_REQUEST |
1446 | g_message ("%s returning minimum height: %d and natural height: %d" , |
1447 | G_OBJECT_TYPE_NAME (cell), |
1448 | minimum_size ? *minimum_size : 20000, |
1449 | natural_size ? *natural_size : 20000); |
1450 | #endif |
1451 | } |
1452 | |
1453 | |
1454 | /** |
1455 | * gtk_cell_renderer_get_preferred_width_for_height: |
1456 | * @cell: a `GtkCellRenderer` instance |
1457 | * @widget: the `GtkWidget` this cell will be rendering to |
1458 | * @height: the size which is available for allocation |
1459 | * @minimum_width: (out) (optional): location for storing the minimum size |
1460 | * @natural_width: (out) (optional): location for storing the preferred size |
1461 | * |
1462 | * Retrieves a cell renderers’s minimum and natural width if it were rendered to |
1463 | * @widget with the specified @height. |
1464 | */ |
1465 | void |
1466 | gtk_cell_renderer_get_preferred_width_for_height (GtkCellRenderer *cell, |
1467 | GtkWidget *widget, |
1468 | int height, |
1469 | int *minimum_width, |
1470 | int *natural_width) |
1471 | { |
1472 | GtkCellRendererClass *klass; |
1473 | int width; |
1474 | |
1475 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1476 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
1477 | g_return_if_fail (NULL != minimum_width || NULL != natural_width); |
1478 | |
1479 | gtk_cell_renderer_get_fixed_size (GTK_CELL_RENDERER (cell), width: &width, NULL); |
1480 | |
1481 | if (width < 0) |
1482 | { |
1483 | klass = GTK_CELL_RENDERER_GET_CLASS (cell); |
1484 | klass->get_preferred_width_for_height (cell, widget, height, minimum_width, natural_width); |
1485 | } |
1486 | else |
1487 | { |
1488 | if (minimum_width) |
1489 | *minimum_width = width; |
1490 | if (natural_width) |
1491 | *natural_width = width; |
1492 | } |
1493 | |
1494 | #if DEBUG_CELL_SIZE_REQUEST |
1495 | g_message ("%s width for height: %d is minimum %d and natural: %d" , |
1496 | G_OBJECT_TYPE_NAME (cell), height, |
1497 | minimum_width ? *minimum_width : 20000, |
1498 | natural_width ? *natural_width : 20000); |
1499 | #endif |
1500 | } |
1501 | |
1502 | /** |
1503 | * gtk_cell_renderer_get_preferred_height_for_width: |
1504 | * @cell: a `GtkCellRenderer` instance |
1505 | * @widget: the `GtkWidget` this cell will be rendering to |
1506 | * @width: the size which is available for allocation |
1507 | * @minimum_height: (out) (optional): location for storing the minimum size |
1508 | * @natural_height: (out) (optional): location for storing the preferred size |
1509 | * |
1510 | * Retrieves a cell renderers’s minimum and natural height if it were rendered to |
1511 | * @widget with the specified @width. |
1512 | */ |
1513 | void |
1514 | gtk_cell_renderer_get_preferred_height_for_width (GtkCellRenderer *cell, |
1515 | GtkWidget *widget, |
1516 | int width, |
1517 | int *minimum_height, |
1518 | int *natural_height) |
1519 | { |
1520 | GtkCellRendererClass *klass; |
1521 | int height; |
1522 | |
1523 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1524 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
1525 | g_return_if_fail (NULL != minimum_height || NULL != natural_height); |
1526 | |
1527 | gtk_cell_renderer_get_fixed_size (GTK_CELL_RENDERER (cell), NULL, height: &height); |
1528 | |
1529 | if (height < 0) |
1530 | { |
1531 | klass = GTK_CELL_RENDERER_GET_CLASS (cell); |
1532 | klass->get_preferred_height_for_width (cell, widget, width, minimum_height, natural_height); |
1533 | } |
1534 | else |
1535 | { |
1536 | if (minimum_height) |
1537 | *minimum_height = height; |
1538 | if (natural_height) |
1539 | *natural_height = height; |
1540 | } |
1541 | |
1542 | #if DEBUG_CELL_SIZE_REQUEST |
1543 | g_message ("%s height for width: %d is minimum %d and natural: %d" , |
1544 | G_OBJECT_TYPE_NAME (cell), width, |
1545 | minimum_height ? *minimum_height : 20000, |
1546 | natural_height ? *natural_height : 20000); |
1547 | #endif |
1548 | } |
1549 | |
1550 | /** |
1551 | * gtk_cell_renderer_get_preferred_size: |
1552 | * @cell: a `GtkCellRenderer` instance |
1553 | * @widget: the `GtkWidget` this cell will be rendering to |
1554 | * @minimum_size: (out) (optional): location for storing the minimum size |
1555 | * @natural_size: (out) (optional): location for storing the natural size |
1556 | * |
1557 | * Retrieves the minimum and natural size of a cell taking |
1558 | * into account the widget’s preference for height-for-width management. |
1559 | */ |
1560 | void |
1561 | gtk_cell_renderer_get_preferred_size (GtkCellRenderer *cell, |
1562 | GtkWidget *widget, |
1563 | GtkRequisition *minimum_size, |
1564 | GtkRequisition *natural_size) |
1565 | { |
1566 | int min_width, nat_width; |
1567 | int min_height, nat_height; |
1568 | |
1569 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1570 | |
1571 | if (gtk_cell_renderer_get_request_mode (cell) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH) |
1572 | { |
1573 | gtk_cell_renderer_get_preferred_width (cell, widget, minimum_size: &min_width, natural_size: &nat_width); |
1574 | |
1575 | if (minimum_size) |
1576 | { |
1577 | minimum_size->width = min_width; |
1578 | gtk_cell_renderer_get_preferred_height_for_width (cell, widget, width: min_width, |
1579 | minimum_height: &minimum_size->height, NULL); |
1580 | } |
1581 | |
1582 | if (natural_size) |
1583 | { |
1584 | natural_size->width = nat_width; |
1585 | gtk_cell_renderer_get_preferred_height_for_width (cell, widget, width: nat_width, |
1586 | NULL, natural_height: &natural_size->height); |
1587 | } |
1588 | } |
1589 | else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */ |
1590 | { |
1591 | gtk_cell_renderer_get_preferred_height (cell, widget, minimum_size: &min_height, natural_size: &nat_height); |
1592 | |
1593 | if (minimum_size) |
1594 | { |
1595 | minimum_size->height = min_height; |
1596 | gtk_cell_renderer_get_preferred_width_for_height (cell, widget, height: min_height, |
1597 | minimum_width: &minimum_size->width, NULL); |
1598 | } |
1599 | |
1600 | if (natural_size) |
1601 | { |
1602 | natural_size->height = nat_height; |
1603 | gtk_cell_renderer_get_preferred_width_for_height (cell, widget, height: nat_height, |
1604 | NULL, natural_width: &natural_size->width); |
1605 | } |
1606 | } |
1607 | } |
1608 | |
1609 | /** |
1610 | * gtk_cell_renderer_get_aligned_area: |
1611 | * @cell: a `GtkCellRenderer` instance |
1612 | * @widget: the `GtkWidget` this cell will be rendering to |
1613 | * @flags: render flags |
1614 | * @cell_area: cell area which would be passed to gtk_cell_renderer_render() |
1615 | * @aligned_area: (out): the return location for the space inside @cell_area |
1616 | * that would actually be used to render. |
1617 | * |
1618 | * Gets the aligned area used by @cell inside @cell_area. Used for finding |
1619 | * the appropriate edit and focus rectangle. |
1620 | */ |
1621 | void |
1622 | gtk_cell_renderer_get_aligned_area (GtkCellRenderer *cell, |
1623 | GtkWidget *widget, |
1624 | GtkCellRendererState flags, |
1625 | const GdkRectangle *cell_area, |
1626 | GdkRectangle *aligned_area) |
1627 | { |
1628 | GtkCellRendererClass *klass; |
1629 | |
1630 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1631 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
1632 | g_return_if_fail (cell_area != NULL); |
1633 | g_return_if_fail (aligned_area != NULL); |
1634 | |
1635 | klass = GTK_CELL_RENDERER_GET_CLASS (cell); |
1636 | klass->get_aligned_area (cell, widget, flags, cell_area, aligned_area); |
1637 | |
1638 | g_assert (aligned_area->x >= cell_area->x && aligned_area->x <= cell_area->x + cell_area->width); |
1639 | g_assert (aligned_area->y >= cell_area->y && aligned_area->y <= cell_area->y + cell_area->height); |
1640 | g_assert ((aligned_area->x - cell_area->x) + aligned_area->width <= cell_area->width); |
1641 | g_assert ((aligned_area->y - cell_area->y) + aligned_area->height <= cell_area->height); |
1642 | } |
1643 | |
1644 | /** |
1645 | * gtk_cell_renderer_get_state: |
1646 | * @cell: (nullable): a `GtkCellRenderer` |
1647 | * @widget: (nullable): a `GtkWidget` |
1648 | * @cell_state: cell renderer state |
1649 | * |
1650 | * Translates the cell renderer state to `GtkStateFlags`, |
1651 | * based on the cell renderer and widget sensitivity, and |
1652 | * the given `GtkCellRenderer`State. |
1653 | * |
1654 | * Returns: the widget state flags applying to @cell |
1655 | **/ |
1656 | GtkStateFlags |
1657 | gtk_cell_renderer_get_state (GtkCellRenderer *cell, |
1658 | GtkWidget *widget, |
1659 | GtkCellRendererState cell_state) |
1660 | { |
1661 | GtkStateFlags state = 0; |
1662 | |
1663 | g_return_val_if_fail (!cell || GTK_IS_CELL_RENDERER (cell), 0); |
1664 | g_return_val_if_fail (!widget || GTK_IS_WIDGET (widget), 0); |
1665 | |
1666 | if (widget) |
1667 | state |= gtk_widget_get_state_flags (widget); |
1668 | |
1669 | state &= ~(GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_DROP_ACTIVE); |
1670 | |
1671 | if ((state & GTK_STATE_FLAG_INSENSITIVE) != 0 || |
1672 | (cell && !gtk_cell_renderer_get_sensitive (cell)) || |
1673 | (cell_state & GTK_CELL_RENDERER_INSENSITIVE) != 0) |
1674 | { |
1675 | state |= GTK_STATE_FLAG_INSENSITIVE; |
1676 | } |
1677 | else |
1678 | { |
1679 | if ((widget && gtk_widget_has_focus (widget)) && |
1680 | (cell_state & GTK_CELL_RENDERER_FOCUSED) != 0) |
1681 | state |= GTK_STATE_FLAG_FOCUSED; |
1682 | |
1683 | if ((cell_state & GTK_CELL_RENDERER_PRELIT) != 0) |
1684 | state |= GTK_STATE_FLAG_PRELIGHT; |
1685 | } |
1686 | |
1687 | if ((cell_state & GTK_CELL_RENDERER_SELECTED) != 0) |
1688 | state |= GTK_STATE_FLAG_SELECTED; |
1689 | |
1690 | return state; |
1691 | } |
1692 | |
1693 | /** |
1694 | * gtk_cell_renderer_set_is_expander: |
1695 | * @cell: a `GtkCellRenderer` |
1696 | * @is_expander: whether @cell is an expander |
1697 | * |
1698 | * Sets whether the given `GtkCellRenderer` is an expander. |
1699 | */ |
1700 | void |
1701 | gtk_cell_renderer_set_is_expander (GtkCellRenderer *cell, |
1702 | gboolean is_expander) |
1703 | { |
1704 | GtkCellRendererPrivate *priv = gtk_cell_renderer_get_instance_private (self: cell); |
1705 | |
1706 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1707 | |
1708 | is_expander = !!is_expander; |
1709 | |
1710 | if (is_expander != priv->is_expander) |
1711 | { |
1712 | priv->is_expander = is_expander; |
1713 | |
1714 | g_object_notify (G_OBJECT (cell), property_name: "is-expander" ); |
1715 | } |
1716 | } |
1717 | |
1718 | /** |
1719 | * gtk_cell_renderer_get_is_expander: |
1720 | * @cell: a `GtkCellRenderer` |
1721 | * |
1722 | * Checks whether the given `GtkCellRenderer` is an expander. |
1723 | * |
1724 | * Returns: %TRUE if @cell is an expander, and %FALSE otherwise |
1725 | */ |
1726 | gboolean |
1727 | gtk_cell_renderer_get_is_expander (GtkCellRenderer *cell) |
1728 | { |
1729 | GtkCellRendererPrivate *priv = gtk_cell_renderer_get_instance_private (self: cell); |
1730 | |
1731 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
1732 | |
1733 | return priv->is_expander; |
1734 | } |
1735 | |
1736 | /** |
1737 | * gtk_cell_renderer_set_is_expanded: |
1738 | * @cell: a `GtkCellRenderer` |
1739 | * @is_expanded: whether @cell should be expanded |
1740 | * |
1741 | * Sets whether the given `GtkCellRenderer` is expanded. |
1742 | */ |
1743 | void |
1744 | gtk_cell_renderer_set_is_expanded (GtkCellRenderer *cell, |
1745 | gboolean is_expanded) |
1746 | { |
1747 | GtkCellRendererPrivate *priv = gtk_cell_renderer_get_instance_private (self: cell); |
1748 | |
1749 | g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); |
1750 | |
1751 | is_expanded = !!is_expanded; |
1752 | |
1753 | if (is_expanded != priv->is_expanded) |
1754 | { |
1755 | priv->is_expanded = is_expanded; |
1756 | |
1757 | g_object_notify (G_OBJECT (cell), property_name: "is-expanded" ); |
1758 | } |
1759 | } |
1760 | |
1761 | /** |
1762 | * gtk_cell_renderer_get_is_expanded: |
1763 | * @cell: a `GtkCellRenderer` |
1764 | * |
1765 | * Checks whether the given `GtkCellRenderer` is expanded. |
1766 | * |
1767 | * Returns: %TRUE if the cell renderer is expanded |
1768 | */ |
1769 | gboolean |
1770 | gtk_cell_renderer_get_is_expanded (GtkCellRenderer *cell) |
1771 | { |
1772 | GtkCellRendererPrivate *priv = gtk_cell_renderer_get_instance_private (self: cell); |
1773 | |
1774 | g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); |
1775 | |
1776 | return priv->is_expanded; |
1777 | } |
1778 | |