1 | /* gtkellview.c |
2 | * Copyright (C) 2002, 2003 Kristian Rietveld <kris@gtk.org> |
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 "gtkcellview.h" |
21 | |
22 | #include "gtkbuildable.h" |
23 | #include "gtkcelllayout.h" |
24 | #include "gtkcellareabox.h" |
25 | #include "gtkcellrendererpixbuf.h" |
26 | #include "gtkcellrenderertext.h" |
27 | #include "gtkintl.h" |
28 | #include "gtkorientable.h" |
29 | #include "gtkprivate.h" |
30 | #include "gtkwidgetprivate.h" |
31 | |
32 | #include <gobject/gmarshal.h> |
33 | |
34 | #include <string.h> |
35 | |
36 | /** |
37 | * GtkCellView: |
38 | * |
39 | * A widget displaying a single row of a GtkTreeModel |
40 | * |
41 | * A `GtkCellView` displays a single row of a `GtkTreeModel` using a `GtkCellArea` |
42 | * and `GtkCellAreaContext`. A `GtkCellAreaContext` can be provided to the |
43 | * `GtkCellView` at construction time in order to keep the cellview in context |
44 | * of a group of cell views, this ensures that the renderers displayed will |
45 | * be properly aligned with each other (like the aligned cells in the menus |
46 | * of `GtkComboBox`). |
47 | * |
48 | * `GtkCellView` is `GtkOrientable` in order to decide in which orientation |
49 | * the underlying `GtkCellAreaContext` should be allocated. Taking the `GtkComboBox` |
50 | * menu as an example, cellviews should be oriented horizontally if the menus are |
51 | * listed top-to-bottom and thus all share the same width but may have separate |
52 | * individual heights (left-to-right menus should be allocated vertically since |
53 | * they all share the same height but may have variable widths). |
54 | * |
55 | * # CSS nodes |
56 | * |
57 | * GtkCellView has a single CSS node with name cellview. |
58 | */ |
59 | |
60 | static void gtk_cell_view_constructed (GObject *object); |
61 | static void gtk_cell_view_get_property (GObject *object, |
62 | guint param_id, |
63 | GValue *value, |
64 | GParamSpec *pspec); |
65 | static void gtk_cell_view_set_property (GObject *object, |
66 | guint param_id, |
67 | const GValue *value, |
68 | GParamSpec *pspec); |
69 | static void gtk_cell_view_finalize (GObject *object); |
70 | static void gtk_cell_view_dispose (GObject *object); |
71 | static void gtk_cell_view_size_allocate (GtkWidget *widget, |
72 | int width, |
73 | int height, |
74 | int baseline); |
75 | static void gtk_cell_view_snapshot (GtkWidget *widget, |
76 | GtkSnapshot *snapshot); |
77 | static void gtk_cell_view_set_value (GtkCellView *cell_view, |
78 | GtkCellRenderer *renderer, |
79 | const char *property, |
80 | GValue *value); |
81 | static void gtk_cell_view_set_cell_data (GtkCellView *cell_view); |
82 | |
83 | /* celllayout */ |
84 | static void gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface); |
85 | static GtkCellArea *gtk_cell_view_cell_layout_get_area (GtkCellLayout *layout); |
86 | |
87 | |
88 | /* buildable */ |
89 | static void gtk_cell_view_buildable_init (GtkBuildableIface *iface); |
90 | static gboolean gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable, |
91 | GtkBuilder *builder, |
92 | GObject *child, |
93 | const char *tagname, |
94 | GtkBuildableParser *parser, |
95 | gpointer *data); |
96 | static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable, |
97 | GtkBuilder *builder, |
98 | GObject *child, |
99 | const char *tagname, |
100 | gpointer data); |
101 | |
102 | static GtkSizeRequestMode gtk_cell_view_get_request_mode (GtkWidget *widget); |
103 | static void gtk_cell_view_measure (GtkWidget *widget, |
104 | GtkOrientation orientation, |
105 | int for_size, |
106 | int *minimum, |
107 | int *natural, |
108 | int *minimum_baseline, |
109 | int *natural_baseline); |
110 | static void context_size_changed_cb (GtkCellAreaContext *context, |
111 | GParamSpec *pspec, |
112 | GtkWidget *view); |
113 | static void row_changed_cb (GtkTreeModel *model, |
114 | GtkTreePath *path, |
115 | GtkTreeIter *iter, |
116 | GtkCellView *view); |
117 | |
118 | typedef struct _GtkCellViewClass GtkCellViewClass; |
119 | typedef struct _GtkCellViewPrivate GtkCellViewPrivate; |
120 | |
121 | struct _GtkCellView |
122 | { |
123 | GtkWidget parent_instance; |
124 | }; |
125 | |
126 | struct _GtkCellViewClass |
127 | { |
128 | GtkWidgetClass parent_class; |
129 | }; |
130 | |
131 | struct _GtkCellViewPrivate |
132 | { |
133 | GtkTreeModel *model; |
134 | GtkTreeRowReference *displayed_row; |
135 | |
136 | GtkCellArea *area; |
137 | GtkCellAreaContext *context; |
138 | |
139 | gulong size_changed_id; |
140 | gulong row_changed_id; |
141 | |
142 | GtkOrientation orientation; |
143 | |
144 | guint draw_sensitive : 1; |
145 | guint fit_model : 1; |
146 | }; |
147 | |
148 | static GtkBuildableIface *parent_buildable_iface; |
149 | |
150 | enum |
151 | { |
152 | PROP_0, |
153 | PROP_ORIENTATION, |
154 | PROP_MODEL, |
155 | PROP_CELL_AREA, |
156 | PROP_CELL_AREA_CONTEXT, |
157 | PROP_DRAW_SENSITIVE, |
158 | PROP_FIT_MODEL |
159 | }; |
160 | |
161 | G_DEFINE_TYPE_WITH_CODE (GtkCellView, gtk_cell_view, GTK_TYPE_WIDGET, |
162 | G_ADD_PRIVATE (GtkCellView) |
163 | G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT, |
164 | gtk_cell_view_cell_layout_init) |
165 | G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, |
166 | gtk_cell_view_buildable_init) |
167 | G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)) |
168 | |
169 | static void |
170 | gtk_cell_view_class_init (GtkCellViewClass *klass) |
171 | { |
172 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
173 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
174 | |
175 | gobject_class->constructed = gtk_cell_view_constructed; |
176 | gobject_class->get_property = gtk_cell_view_get_property; |
177 | gobject_class->set_property = gtk_cell_view_set_property; |
178 | gobject_class->finalize = gtk_cell_view_finalize; |
179 | gobject_class->dispose = gtk_cell_view_dispose; |
180 | |
181 | widget_class->snapshot = gtk_cell_view_snapshot; |
182 | widget_class->size_allocate = gtk_cell_view_size_allocate; |
183 | widget_class->get_request_mode = gtk_cell_view_get_request_mode; |
184 | widget_class->measure = gtk_cell_view_measure; |
185 | |
186 | /* properties */ |
187 | g_object_class_override_property (oclass: gobject_class, property_id: PROP_ORIENTATION, name: "orientation" ); |
188 | |
189 | /** |
190 | * GtkCellView:model: |
191 | * |
192 | * The model for cell view |
193 | * |
194 | * since 2.10 |
195 | */ |
196 | g_object_class_install_property (oclass: gobject_class, |
197 | property_id: PROP_MODEL, |
198 | pspec: g_param_spec_object (name: "model" , |
199 | P_("CellView model" ), |
200 | P_("The model for cell view" ), |
201 | GTK_TYPE_TREE_MODEL, |
202 | GTK_PARAM_READWRITE)); |
203 | |
204 | |
205 | /** |
206 | * GtkCellView:cell-area: |
207 | * |
208 | * The `GtkCellArea` rendering cells |
209 | * |
210 | * If no area is specified when creating the cell view with gtk_cell_view_new_with_context() |
211 | * a horizontally oriented `GtkCellArea`Box will be used. |
212 | * |
213 | * since 3.0 |
214 | */ |
215 | g_object_class_install_property (oclass: gobject_class, |
216 | property_id: PROP_CELL_AREA, |
217 | pspec: g_param_spec_object (name: "cell-area" , |
218 | P_("Cell Area" ), |
219 | P_("The GtkCellArea used to layout cells" ), |
220 | GTK_TYPE_CELL_AREA, |
221 | GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); |
222 | |
223 | /** |
224 | * GtkCellView:cell-area-context: |
225 | * |
226 | * The `GtkCellAreaContext` used to compute the geometry of the cell view. |
227 | * |
228 | * A group of cell views can be assigned the same context in order to |
229 | * ensure the sizes and cell alignments match across all the views with |
230 | * the same context. |
231 | * |
232 | * `GtkComboBox` menus uses this to assign the same context to all cell views |
233 | * in the menu items for a single menu (each submenu creates its own |
234 | * context since the size of each submenu does not depend on parent |
235 | * or sibling menus). |
236 | * |
237 | * since 3.0 |
238 | */ |
239 | g_object_class_install_property (oclass: gobject_class, |
240 | property_id: PROP_CELL_AREA_CONTEXT, |
241 | pspec: g_param_spec_object (name: "cell-area-context" , |
242 | P_("Cell Area Context" ), |
243 | P_("The GtkCellAreaContext used to " |
244 | "compute the geometry of the cell view" ), |
245 | GTK_TYPE_CELL_AREA_CONTEXT, |
246 | GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); |
247 | |
248 | /** |
249 | * GtkCellView:draw-sensitive: |
250 | * |
251 | * Whether all cells should be draw as sensitive for this view regardless |
252 | * of the actual cell properties (used to make menus with submenus appear |
253 | * sensitive when the items in submenus might be insensitive). |
254 | * |
255 | * since 3.0 |
256 | */ |
257 | g_object_class_install_property (oclass: gobject_class, |
258 | property_id: PROP_DRAW_SENSITIVE, |
259 | pspec: g_param_spec_boolean (name: "draw-sensitive" , |
260 | P_("Draw Sensitive" ), |
261 | P_("Whether to force cells to be drawn in a " |
262 | "sensitive state" ), |
263 | FALSE, |
264 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
265 | |
266 | /** |
267 | * GtkCellView:fit-model: |
268 | * |
269 | * Whether the view should request enough space to always fit |
270 | * the size of every row in the model (used by the combo box to |
271 | * ensure the combo box size doesn't change when different items |
272 | * are selected). |
273 | * |
274 | * since 3.0 |
275 | */ |
276 | g_object_class_install_property (oclass: gobject_class, |
277 | property_id: PROP_FIT_MODEL, |
278 | pspec: g_param_spec_boolean (name: "fit-model" , |
279 | P_("Fit Model" ), |
280 | P_("Whether to request enough space for " |
281 | "every row in the model" ), |
282 | FALSE, |
283 | GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); |
284 | |
285 | gtk_widget_class_set_css_name (widget_class, I_("cellview" )); |
286 | } |
287 | |
288 | static void |
289 | gtk_cell_view_buildable_add_child (GtkBuildable *buildable, |
290 | GtkBuilder *builder, |
291 | GObject *child, |
292 | const char *type) |
293 | { |
294 | if (GTK_IS_CELL_RENDERER (child)) |
295 | _gtk_cell_layout_buildable_add_child (buildable, builder, child, type); |
296 | else |
297 | parent_buildable_iface->add_child (buildable, builder, child, type); |
298 | } |
299 | |
300 | static void |
301 | gtk_cell_view_buildable_init (GtkBuildableIface *iface) |
302 | { |
303 | parent_buildable_iface = g_type_interface_peek_parent (g_iface: iface); |
304 | iface->add_child = gtk_cell_view_buildable_add_child; |
305 | iface->custom_tag_start = gtk_cell_view_buildable_custom_tag_start; |
306 | iface->custom_tag_end = gtk_cell_view_buildable_custom_tag_end; |
307 | } |
308 | |
309 | static void |
310 | gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface) |
311 | { |
312 | iface->get_area = gtk_cell_view_cell_layout_get_area; |
313 | } |
314 | |
315 | static void |
316 | gtk_cell_view_constructed (GObject *object) |
317 | { |
318 | GtkCellView *view = GTK_CELL_VIEW (object); |
319 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: view); |
320 | |
321 | G_OBJECT_CLASS (gtk_cell_view_parent_class)->constructed (object); |
322 | |
323 | if (!priv->area) |
324 | { |
325 | priv->area = gtk_cell_area_box_new (); |
326 | g_object_ref_sink (priv->area); |
327 | } |
328 | |
329 | if (!priv->context) |
330 | priv->context = gtk_cell_area_create_context (area: priv->area); |
331 | |
332 | priv->size_changed_id = |
333 | g_signal_connect (priv->context, "notify" , |
334 | G_CALLBACK (context_size_changed_cb), view); |
335 | } |
336 | |
337 | static void |
338 | gtk_cell_view_get_property (GObject *object, |
339 | guint param_id, |
340 | GValue *value, |
341 | GParamSpec *pspec) |
342 | { |
343 | GtkCellView *view = GTK_CELL_VIEW (object); |
344 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: view); |
345 | |
346 | switch (param_id) |
347 | { |
348 | case PROP_ORIENTATION: |
349 | g_value_set_enum (value, v_enum: priv->orientation); |
350 | break; |
351 | case PROP_MODEL: |
352 | g_value_set_object (value, v_object: priv->model); |
353 | break; |
354 | case PROP_CELL_AREA: |
355 | g_value_set_object (value, v_object: priv->area); |
356 | break; |
357 | case PROP_CELL_AREA_CONTEXT: |
358 | g_value_set_object (value, v_object: priv->context); |
359 | break; |
360 | case PROP_DRAW_SENSITIVE: |
361 | g_value_set_boolean (value, v_boolean: priv->draw_sensitive); |
362 | break; |
363 | case PROP_FIT_MODEL: |
364 | g_value_set_boolean (value, v_boolean: priv->fit_model); |
365 | break; |
366 | default: |
367 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
368 | break; |
369 | } |
370 | } |
371 | |
372 | static void |
373 | gtk_cell_view_set_property (GObject *object, |
374 | guint param_id, |
375 | const GValue *value, |
376 | GParamSpec *pspec) |
377 | { |
378 | GtkCellView *view = GTK_CELL_VIEW (object); |
379 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: view); |
380 | GtkCellArea *area; |
381 | GtkCellAreaContext *context; |
382 | |
383 | switch (param_id) |
384 | { |
385 | case PROP_ORIENTATION: |
386 | if (priv->orientation != g_value_get_enum (value)) |
387 | { |
388 | priv->orientation = g_value_get_enum (value); |
389 | if (priv->context) |
390 | gtk_cell_area_context_reset (context: priv->context); |
391 | gtk_widget_update_orientation (GTK_WIDGET (object), orientation: priv->orientation); |
392 | g_object_notify_by_pspec (object, pspec); |
393 | } |
394 | break; |
395 | case PROP_MODEL: |
396 | gtk_cell_view_set_model (cell_view: view, model: g_value_get_object (value)); |
397 | break; |
398 | case PROP_CELL_AREA: |
399 | /* Construct-only, can only be assigned once */ |
400 | area = g_value_get_object (value); |
401 | |
402 | if (area) |
403 | { |
404 | if (priv->area != NULL) |
405 | { |
406 | g_warning ("cell-area has already been set, ignoring construct property" ); |
407 | g_object_ref_sink (area); |
408 | g_object_unref (object: area); |
409 | } |
410 | else |
411 | priv->area = g_object_ref_sink (area); |
412 | } |
413 | break; |
414 | case PROP_CELL_AREA_CONTEXT: |
415 | /* Construct-only, can only be assigned once */ |
416 | context = g_value_get_object (value); |
417 | |
418 | if (context) |
419 | { |
420 | if (priv->context != NULL) |
421 | { |
422 | g_warning ("cell-area-context has already been set, ignoring construct property" ); |
423 | g_object_ref_sink (context); |
424 | g_object_unref (object: context); |
425 | } |
426 | else |
427 | priv->context = g_object_ref (context); |
428 | } |
429 | break; |
430 | |
431 | case PROP_DRAW_SENSITIVE: |
432 | gtk_cell_view_set_draw_sensitive (cell_view: view, draw_sensitive: g_value_get_boolean (value)); |
433 | break; |
434 | |
435 | case PROP_FIT_MODEL: |
436 | gtk_cell_view_set_fit_model (cell_view: view, fit_model: g_value_get_boolean (value)); |
437 | break; |
438 | |
439 | default: |
440 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
441 | break; |
442 | } |
443 | } |
444 | |
445 | static void |
446 | gtk_cell_view_init (GtkCellView *cellview) |
447 | { |
448 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
449 | |
450 | priv->orientation = GTK_ORIENTATION_HORIZONTAL; |
451 | } |
452 | |
453 | static void |
454 | gtk_cell_view_finalize (GObject *object) |
455 | { |
456 | GtkCellView *cellview = GTK_CELL_VIEW (object); |
457 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
458 | |
459 | if (priv->displayed_row) |
460 | gtk_tree_row_reference_free (reference: priv->displayed_row); |
461 | |
462 | G_OBJECT_CLASS (gtk_cell_view_parent_class)->finalize (object); |
463 | } |
464 | |
465 | static void |
466 | gtk_cell_view_dispose (GObject *object) |
467 | { |
468 | GtkCellView *cellview = GTK_CELL_VIEW (object); |
469 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
470 | |
471 | gtk_cell_view_set_model (cell_view: cellview, NULL); |
472 | |
473 | g_clear_object (&priv->area); |
474 | |
475 | if (priv->context) |
476 | { |
477 | g_signal_handler_disconnect (instance: priv->context, handler_id: priv->size_changed_id); |
478 | |
479 | g_object_unref (object: priv->context); |
480 | priv->context = NULL; |
481 | priv->size_changed_id = 0; |
482 | } |
483 | |
484 | G_OBJECT_CLASS (gtk_cell_view_parent_class)->dispose (object); |
485 | } |
486 | |
487 | static void |
488 | gtk_cell_view_size_allocate (GtkWidget *widget, |
489 | int width, |
490 | int height, |
491 | int baseline) |
492 | { |
493 | GtkCellView *cellview = GTK_CELL_VIEW (widget); |
494 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
495 | int alloc_width, alloc_height; |
496 | |
497 | gtk_cell_area_context_get_allocation (context: priv->context, width: &alloc_width, height: &alloc_height); |
498 | |
499 | /* The first cell view in context is responsible for allocating the context at |
500 | * allocate time (or the cellview has its own context and is not grouped with |
501 | * any other cell views) |
502 | * |
503 | * If the cellview is in "fit model" mode, we assume it's not in context and |
504 | * needs to allocate every time. |
505 | */ |
506 | if (priv->fit_model) |
507 | gtk_cell_area_context_allocate (context: priv->context, width, height); |
508 | else if (alloc_width != width && priv->orientation == GTK_ORIENTATION_HORIZONTAL) |
509 | gtk_cell_area_context_allocate (context: priv->context, width, height: -1); |
510 | else if (alloc_height != height && priv->orientation == GTK_ORIENTATION_VERTICAL) |
511 | gtk_cell_area_context_allocate (context: priv->context, width: -1, height); |
512 | } |
513 | |
514 | static void |
515 | gtk_cell_view_request_model (GtkCellView *cellview, |
516 | GtkTreeIter *parent, |
517 | GtkOrientation orientation, |
518 | int for_size, |
519 | int *minimum_size, |
520 | int *natural_size) |
521 | { |
522 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
523 | GtkTreeIter iter; |
524 | gboolean valid; |
525 | |
526 | if (!priv->model) |
527 | return; |
528 | |
529 | valid = gtk_tree_model_iter_children (tree_model: priv->model, iter: &iter, parent); |
530 | while (valid) |
531 | { |
532 | int min, nat; |
533 | |
534 | gtk_cell_area_apply_attributes (area: priv->area, tree_model: priv->model, iter: &iter, FALSE, FALSE); |
535 | |
536 | if (orientation == GTK_ORIENTATION_HORIZONTAL) |
537 | { |
538 | if (for_size < 0) |
539 | gtk_cell_area_get_preferred_width (area: priv->area, context: priv->context, |
540 | GTK_WIDGET (cellview), minimum_width: &min, natural_width: &nat); |
541 | else |
542 | gtk_cell_area_get_preferred_width_for_height (area: priv->area, context: priv->context, |
543 | GTK_WIDGET (cellview), height: for_size, minimum_width: &min, natural_width: &nat); |
544 | } |
545 | else |
546 | { |
547 | if (for_size < 0) |
548 | gtk_cell_area_get_preferred_height (area: priv->area, context: priv->context, |
549 | GTK_WIDGET (cellview), minimum_height: &min, natural_height: &nat); |
550 | else |
551 | gtk_cell_area_get_preferred_height_for_width (area: priv->area, context: priv->context, |
552 | GTK_WIDGET (cellview), width: for_size, minimum_height: &min, natural_height: &nat); |
553 | } |
554 | |
555 | *minimum_size = MAX (min, *minimum_size); |
556 | *natural_size = MAX (nat, *natural_size); |
557 | |
558 | /* Recurse into children when they exist */ |
559 | gtk_cell_view_request_model (cellview, parent: &iter, orientation, for_size, minimum_size, natural_size); |
560 | |
561 | valid = gtk_tree_model_iter_next (tree_model: priv->model, iter: &iter); |
562 | } |
563 | } |
564 | |
565 | static GtkSizeRequestMode |
566 | gtk_cell_view_get_request_mode (GtkWidget *widget) |
567 | { |
568 | GtkCellView *cellview = GTK_CELL_VIEW (widget); |
569 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
570 | |
571 | return gtk_cell_area_get_request_mode (area: priv->area); |
572 | } |
573 | |
574 | static void |
575 | gtk_cell_view_measure (GtkWidget *widget, |
576 | GtkOrientation orientation, |
577 | int for_size, |
578 | int *minimum, |
579 | int *natural, |
580 | int *minimum_baseline, |
581 | int *natural_baseline) |
582 | { |
583 | GtkCellView *cellview = GTK_CELL_VIEW (widget); |
584 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
585 | |
586 | g_signal_handler_block (instance: priv->context, handler_id: priv->size_changed_id); |
587 | |
588 | if (orientation == GTK_ORIENTATION_HORIZONTAL && for_size == -1) |
589 | { |
590 | if (priv->fit_model) |
591 | { |
592 | int min = 0, nat = 0; |
593 | gtk_cell_view_request_model (cellview, NULL, orientation: GTK_ORIENTATION_HORIZONTAL, for_size: -1, minimum_size: &min, natural_size: &nat); |
594 | } |
595 | else |
596 | { |
597 | if (priv->displayed_row) |
598 | gtk_cell_view_set_cell_data (cell_view: cellview); |
599 | |
600 | gtk_cell_area_get_preferred_width (area: priv->area, context: priv->context, widget, NULL, NULL); |
601 | } |
602 | |
603 | gtk_cell_area_context_get_preferred_width (context: priv->context, minimum_width: minimum, natural_width: natural); |
604 | } |
605 | else if (orientation == GTK_ORIENTATION_VERTICAL && for_size == -1) |
606 | { |
607 | if (priv->fit_model) |
608 | { |
609 | int min = 0, nat = 0; |
610 | gtk_cell_view_request_model (cellview, NULL, orientation: GTK_ORIENTATION_VERTICAL, for_size: -1, minimum_size: &min, natural_size: &nat); |
611 | } |
612 | else |
613 | { |
614 | if (priv->displayed_row) |
615 | gtk_cell_view_set_cell_data (cell_view: cellview); |
616 | |
617 | gtk_cell_area_get_preferred_height (area: priv->area, context: priv->context, widget, NULL, NULL); |
618 | } |
619 | |
620 | gtk_cell_area_context_get_preferred_height (context: priv->context, minimum_height: minimum, natural_height: natural); |
621 | } |
622 | else if (orientation == GTK_ORIENTATION_HORIZONTAL && for_size >= 0) |
623 | { |
624 | if (priv->fit_model) |
625 | { |
626 | int min = 0, nat = 0; |
627 | gtk_cell_view_request_model (cellview, NULL, orientation: GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size: &min, natural_size: &nat); |
628 | |
629 | *minimum = min; |
630 | *natural = nat; |
631 | } |
632 | else |
633 | { |
634 | if (priv->displayed_row) |
635 | gtk_cell_view_set_cell_data (cell_view: cellview); |
636 | |
637 | gtk_cell_area_get_preferred_width_for_height (area: priv->area, context: priv->context, widget, |
638 | height: for_size, minimum_width: minimum, natural_width: natural); |
639 | } |
640 | } |
641 | else |
642 | { |
643 | if (priv->fit_model) |
644 | { |
645 | int min = 0, nat = 0; |
646 | gtk_cell_view_request_model (cellview, NULL, orientation: GTK_ORIENTATION_VERTICAL, for_size, minimum_size: &min, natural_size: &nat); |
647 | |
648 | *minimum = min; |
649 | *natural = nat; |
650 | } |
651 | else |
652 | { |
653 | if (priv->displayed_row) |
654 | gtk_cell_view_set_cell_data (cell_view: cellview); |
655 | |
656 | gtk_cell_area_get_preferred_height_for_width (area: priv->area, context: priv->context, widget, |
657 | width: for_size, minimum_height: minimum, natural_height: natural); |
658 | } |
659 | } |
660 | |
661 | g_signal_handler_unblock (instance: priv->context, handler_id: priv->size_changed_id); |
662 | } |
663 | |
664 | static void |
665 | gtk_cell_view_snapshot (GtkWidget *widget, |
666 | GtkSnapshot *snapshot) |
667 | { |
668 | GtkCellView *cellview = GTK_CELL_VIEW (widget); |
669 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
670 | GdkRectangle area; |
671 | GtkCellRendererState state; |
672 | |
673 | /* render cells */ |
674 | area.x = 0; |
675 | area.y = 0; |
676 | area.width = gtk_widget_get_width (widget); |
677 | area.height = gtk_widget_get_height (widget); |
678 | |
679 | /* set cell data (if available) */ |
680 | if (priv->displayed_row) |
681 | gtk_cell_view_set_cell_data (cell_view: cellview); |
682 | else if (priv->model) |
683 | return; |
684 | |
685 | if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_PRELIGHT) |
686 | state = GTK_CELL_RENDERER_PRELIT; |
687 | else |
688 | state = 0; |
689 | |
690 | /* Render the cells */ |
691 | gtk_cell_area_snapshot (area: priv->area, context: priv->context, |
692 | widget, snapshot, background_area: &area, cell_area: &area, flags: state, FALSE); |
693 | |
694 | |
695 | } |
696 | |
697 | static void |
698 | gtk_cell_view_set_cell_data (GtkCellView *cell_view) |
699 | { |
700 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
701 | GtkTreeIter iter; |
702 | GtkTreePath *path; |
703 | |
704 | g_return_if_fail (priv->displayed_row != NULL); |
705 | |
706 | path = gtk_tree_row_reference_get_path (reference: priv->displayed_row); |
707 | if (!path) |
708 | return; |
709 | |
710 | gtk_tree_model_get_iter (tree_model: priv->model, iter: &iter, path); |
711 | gtk_tree_path_free (path); |
712 | |
713 | gtk_cell_area_apply_attributes (area: priv->area, |
714 | tree_model: priv->model, |
715 | iter: &iter, FALSE, FALSE); |
716 | |
717 | if (priv->draw_sensitive) |
718 | { |
719 | GList *l, *cells = |
720 | gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->area)); |
721 | |
722 | for (l = cells; l; l = l->next) |
723 | { |
724 | GObject *renderer = l->data; |
725 | |
726 | g_object_set (object: renderer, first_property_name: "sensitive" , TRUE, NULL); |
727 | } |
728 | g_list_free (list: cells); |
729 | } |
730 | } |
731 | |
732 | /* GtkCellLayout implementation */ |
733 | static GtkCellArea * |
734 | gtk_cell_view_cell_layout_get_area (GtkCellLayout *layout) |
735 | { |
736 | GtkCellView *cellview = GTK_CELL_VIEW (layout); |
737 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cellview); |
738 | |
739 | if (G_UNLIKELY (!priv->area)) |
740 | { |
741 | priv->area = gtk_cell_area_box_new (); |
742 | g_object_ref_sink (priv->area); |
743 | } |
744 | |
745 | return priv->area; |
746 | } |
747 | |
748 | /* GtkBuildable implementation */ |
749 | static gboolean |
750 | gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable, |
751 | GtkBuilder *builder, |
752 | GObject *child, |
753 | const char *tagname, |
754 | GtkBuildableParser *parser, |
755 | gpointer *data) |
756 | { |
757 | if (parent_buildable_iface->custom_tag_start && |
758 | parent_buildable_iface->custom_tag_start (buildable, builder, child, |
759 | tagname, parser, data)) |
760 | return TRUE; |
761 | |
762 | return _gtk_cell_layout_buildable_custom_tag_start (buildable, builder, child, |
763 | tagname, parser, data); |
764 | } |
765 | |
766 | static void |
767 | gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable, |
768 | GtkBuilder *builder, |
769 | GObject *child, |
770 | const char *tagname, |
771 | gpointer data) |
772 | { |
773 | if (_gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname, |
774 | data)) |
775 | return; |
776 | else if (parent_buildable_iface->custom_tag_end) |
777 | parent_buildable_iface->custom_tag_end (buildable, builder, child, tagname, |
778 | data); |
779 | } |
780 | |
781 | static void |
782 | context_size_changed_cb (GtkCellAreaContext *context, |
783 | GParamSpec *pspec, |
784 | GtkWidget *view) |
785 | { |
786 | if (!strcmp (s1: pspec->name, s2: "minimum-width" ) || |
787 | !strcmp (s1: pspec->name, s2: "natural-width" ) || |
788 | !strcmp (s1: pspec->name, s2: "minimum-height" ) || |
789 | !strcmp (s1: pspec->name, s2: "natural-height" )) |
790 | gtk_widget_queue_resize (widget: view); |
791 | } |
792 | |
793 | static void |
794 | row_changed_cb (GtkTreeModel *model, |
795 | GtkTreePath *path, |
796 | GtkTreeIter *iter, |
797 | GtkCellView *view) |
798 | { |
799 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: view); |
800 | GtkTreePath *row_path; |
801 | |
802 | if (priv->displayed_row) |
803 | { |
804 | row_path = gtk_tree_row_reference_get_path (reference: priv->displayed_row); |
805 | |
806 | if (row_path) |
807 | { |
808 | /* Resize everything in our context if our row changed */ |
809 | if (gtk_tree_path_compare (a: row_path, b: path) == 0) |
810 | gtk_cell_area_context_reset (context: priv->context); |
811 | |
812 | gtk_tree_path_free (path: row_path); |
813 | } |
814 | } |
815 | } |
816 | |
817 | /** |
818 | * gtk_cell_view_new: |
819 | * |
820 | * Creates a new `GtkCellView` widget. |
821 | * |
822 | * Returns: A newly created `GtkCellView` widget. |
823 | */ |
824 | GtkWidget * |
825 | gtk_cell_view_new (void) |
826 | { |
827 | GtkCellView *cellview; |
828 | |
829 | cellview = g_object_new (GTK_TYPE_CELL_VIEW, NULL); |
830 | |
831 | return GTK_WIDGET (cellview); |
832 | } |
833 | |
834 | |
835 | /** |
836 | * gtk_cell_view_new_with_context: |
837 | * @area: the `GtkCellArea` to layout cells |
838 | * @context: the `GtkCellAreaContext` in which to calculate cell geometry |
839 | * |
840 | * Creates a new `GtkCellView` widget with a specific `GtkCellArea` |
841 | * to layout cells and a specific `GtkCellAreaContext`. |
842 | * |
843 | * Specifying the same context for a handful of cells lets |
844 | * the underlying area synchronize the geometry for those cells, |
845 | * in this way alignments with cellviews for other rows are |
846 | * possible. |
847 | * |
848 | * Returns: A newly created `GtkCellView` widget. |
849 | */ |
850 | GtkWidget * |
851 | gtk_cell_view_new_with_context (GtkCellArea *area, |
852 | GtkCellAreaContext *context) |
853 | { |
854 | g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL); |
855 | g_return_val_if_fail (context == NULL || GTK_IS_CELL_AREA_CONTEXT (context), NULL); |
856 | |
857 | return (GtkWidget *)g_object_new (GTK_TYPE_CELL_VIEW, |
858 | first_property_name: "cell-area" , area, |
859 | "cell-area-context" , context, |
860 | NULL); |
861 | } |
862 | |
863 | /** |
864 | * gtk_cell_view_new_with_text: |
865 | * @text: the text to display in the cell view |
866 | * |
867 | * Creates a new `GtkCellView` widget, adds a `GtkCellRendererText` |
868 | * to it, and makes it show @text. |
869 | * |
870 | * Returns: A newly created `GtkCellView` widget. |
871 | */ |
872 | GtkWidget * |
873 | gtk_cell_view_new_with_text (const char *text) |
874 | { |
875 | GtkCellView *cellview; |
876 | GtkCellRenderer *renderer; |
877 | GValue value = G_VALUE_INIT; |
878 | |
879 | cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); |
880 | |
881 | renderer = gtk_cell_renderer_text_new (); |
882 | gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), |
883 | cell: renderer, TRUE); |
884 | |
885 | g_value_init (value: &value, G_TYPE_STRING); |
886 | g_value_set_string (value: &value, v_string: text); |
887 | gtk_cell_view_set_value (cell_view: cellview, renderer, property: "text" , value: &value); |
888 | g_value_unset (value: &value); |
889 | |
890 | return GTK_WIDGET (cellview); |
891 | } |
892 | |
893 | /** |
894 | * gtk_cell_view_new_with_markup: |
895 | * @markup: the text to display in the cell view |
896 | * |
897 | * Creates a new `GtkCellView` widget, adds a `GtkCellRendererText` |
898 | * to it, and makes it show @markup. The text can be marked up with |
899 | * the [Pango text markup language](https://docs.gtk.org/Pango/pango_markup.html). |
900 | * |
901 | * Returns: A newly created `GtkCellView` widget. |
902 | */ |
903 | GtkWidget * |
904 | gtk_cell_view_new_with_markup (const char *markup) |
905 | { |
906 | GtkCellView *cellview; |
907 | GtkCellRenderer *renderer; |
908 | GValue value = G_VALUE_INIT; |
909 | |
910 | cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); |
911 | |
912 | renderer = gtk_cell_renderer_text_new (); |
913 | gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), |
914 | cell: renderer, TRUE); |
915 | |
916 | g_value_init (value: &value, G_TYPE_STRING); |
917 | g_value_set_string (value: &value, v_string: markup); |
918 | gtk_cell_view_set_value (cell_view: cellview, renderer, property: "markup" , value: &value); |
919 | g_value_unset (value: &value); |
920 | |
921 | return GTK_WIDGET (cellview); |
922 | } |
923 | |
924 | /** |
925 | * gtk_cell_view_new_with_texture: |
926 | * @texture: the image to display in the cell view |
927 | * |
928 | * Creates a new `GtkCellView` widget, adds a `GtkCellRendererPixbuf` |
929 | * to it, and makes it show @texture. |
930 | * |
931 | * Returns: A newly created `GtkCellView` widget. |
932 | */ |
933 | GtkWidget * |
934 | gtk_cell_view_new_with_texture (GdkTexture *texture) |
935 | { |
936 | GtkCellView *cellview; |
937 | GtkCellRenderer *renderer; |
938 | GValue value = G_VALUE_INIT; |
939 | |
940 | cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); |
941 | |
942 | renderer = gtk_cell_renderer_pixbuf_new (); |
943 | gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), |
944 | cell: renderer, TRUE); |
945 | |
946 | g_value_init (value: &value, GDK_TYPE_TEXTURE); |
947 | g_value_set_object (value: &value, v_object: texture); |
948 | gtk_cell_view_set_value (cell_view: cellview, renderer, property: "texture" , value: &value); |
949 | g_value_unset (value: &value); |
950 | |
951 | return GTK_WIDGET (cellview); |
952 | } |
953 | |
954 | /** |
955 | * gtk_cell_view_set_value: |
956 | * @cell_view: a `GtkCellView` widget |
957 | * @renderer: one of the renderers of @cell_view |
958 | * @property: the name of the property of @renderer to set |
959 | * @value: the new value to set the property to |
960 | * |
961 | * Sets a property of a cell renderer of @cell_view, and |
962 | * makes sure the display of @cell_view is updated. |
963 | */ |
964 | static void |
965 | gtk_cell_view_set_value (GtkCellView *cell_view, |
966 | GtkCellRenderer *renderer, |
967 | const char *property, |
968 | GValue *value) |
969 | { |
970 | g_object_set_property (G_OBJECT (renderer), property_name: property, value); |
971 | |
972 | /* force resize and redraw */ |
973 | gtk_widget_queue_resize (GTK_WIDGET (cell_view)); |
974 | gtk_widget_queue_draw (GTK_WIDGET (cell_view)); |
975 | } |
976 | |
977 | /** |
978 | * gtk_cell_view_set_model: |
979 | * @cell_view: a `GtkCellView` |
980 | * @model: (nullable): a `GtkTreeModel` |
981 | * |
982 | * Sets the model for @cell_view. If @cell_view already has a model |
983 | * set, it will remove it before setting the new model. If @model is |
984 | * %NULL, then it will unset the old model. |
985 | */ |
986 | void |
987 | gtk_cell_view_set_model (GtkCellView *cell_view, |
988 | GtkTreeModel *model) |
989 | { |
990 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
991 | |
992 | g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); |
993 | g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model)); |
994 | |
995 | if (priv->model) |
996 | { |
997 | g_signal_handler_disconnect (instance: priv->model, handler_id: priv->row_changed_id); |
998 | priv->row_changed_id = 0; |
999 | |
1000 | if (priv->displayed_row) |
1001 | gtk_tree_row_reference_free (reference: priv->displayed_row); |
1002 | priv->displayed_row = NULL; |
1003 | |
1004 | g_object_unref (object: priv->model); |
1005 | } |
1006 | |
1007 | priv->model = model; |
1008 | |
1009 | if (priv->model) |
1010 | { |
1011 | g_object_ref (priv->model); |
1012 | |
1013 | priv->row_changed_id = |
1014 | g_signal_connect (priv->model, "row-changed" , |
1015 | G_CALLBACK (row_changed_cb), cell_view); |
1016 | } |
1017 | } |
1018 | |
1019 | /** |
1020 | * gtk_cell_view_get_model: |
1021 | * @cell_view: a `GtkCellView` |
1022 | * |
1023 | * Returns the model for @cell_view. If no model is used %NULL is |
1024 | * returned. |
1025 | * |
1026 | * Returns: (nullable) (transfer none): a `GtkTreeModel` used |
1027 | */ |
1028 | GtkTreeModel * |
1029 | gtk_cell_view_get_model (GtkCellView *cell_view) |
1030 | { |
1031 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1032 | |
1033 | g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), NULL); |
1034 | |
1035 | return priv->model; |
1036 | } |
1037 | |
1038 | /** |
1039 | * gtk_cell_view_set_displayed_row: |
1040 | * @cell_view: a `GtkCellView` |
1041 | * @path: (nullable): a `GtkTreePath` or %NULL to unset. |
1042 | * |
1043 | * Sets the row of the model that is currently displayed |
1044 | * by the `GtkCellView`. If the path is unset, then the |
1045 | * contents of the cellview “stick” at their last value; |
1046 | * this is not normally a desired result, but may be |
1047 | * a needed intermediate state if say, the model for |
1048 | * the `GtkCellView` becomes temporarily empty. |
1049 | **/ |
1050 | void |
1051 | gtk_cell_view_set_displayed_row (GtkCellView *cell_view, |
1052 | GtkTreePath *path) |
1053 | { |
1054 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1055 | |
1056 | g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); |
1057 | g_return_if_fail (GTK_IS_TREE_MODEL (priv->model)); |
1058 | |
1059 | if (priv->displayed_row) |
1060 | gtk_tree_row_reference_free (reference: priv->displayed_row); |
1061 | |
1062 | if (path) |
1063 | priv->displayed_row = gtk_tree_row_reference_new (model: priv->model, path); |
1064 | else |
1065 | priv->displayed_row = NULL; |
1066 | |
1067 | /* force resize and redraw */ |
1068 | gtk_widget_queue_resize (GTK_WIDGET (cell_view)); |
1069 | gtk_widget_queue_draw (GTK_WIDGET (cell_view)); |
1070 | } |
1071 | |
1072 | /** |
1073 | * gtk_cell_view_get_displayed_row: |
1074 | * @cell_view: a `GtkCellView` |
1075 | * |
1076 | * Returns a `GtkTreePath` referring to the currently |
1077 | * displayed row. If no row is currently displayed, |
1078 | * %NULL is returned. |
1079 | * |
1080 | * Returns: (nullable) (transfer full): the currently displayed row |
1081 | */ |
1082 | GtkTreePath * |
1083 | gtk_cell_view_get_displayed_row (GtkCellView *cell_view) |
1084 | { |
1085 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1086 | |
1087 | g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), NULL); |
1088 | |
1089 | if (!priv->displayed_row) |
1090 | return NULL; |
1091 | |
1092 | return gtk_tree_row_reference_get_path (reference: priv->displayed_row); |
1093 | } |
1094 | |
1095 | /** |
1096 | * gtk_cell_view_get_draw_sensitive: |
1097 | * @cell_view: a `GtkCellView` |
1098 | * |
1099 | * Gets whether @cell_view is configured to draw all of its |
1100 | * cells in a sensitive state. |
1101 | * |
1102 | * Returns: whether @cell_view draws all of its |
1103 | * cells in a sensitive state |
1104 | */ |
1105 | gboolean |
1106 | gtk_cell_view_get_draw_sensitive (GtkCellView *cell_view) |
1107 | { |
1108 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1109 | |
1110 | g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE); |
1111 | |
1112 | return priv->draw_sensitive; |
1113 | } |
1114 | |
1115 | /** |
1116 | * gtk_cell_view_set_draw_sensitive: |
1117 | * @cell_view: a `GtkCellView` |
1118 | * @draw_sensitive: whether to draw all cells in a sensitive state. |
1119 | * |
1120 | * Sets whether @cell_view should draw all of its |
1121 | * cells in a sensitive state, this is used by `GtkComboBox` menus |
1122 | * to ensure that rows with insensitive cells that contain |
1123 | * children appear sensitive in the parent menu item. |
1124 | */ |
1125 | void |
1126 | gtk_cell_view_set_draw_sensitive (GtkCellView *cell_view, |
1127 | gboolean draw_sensitive) |
1128 | { |
1129 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1130 | |
1131 | g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); |
1132 | |
1133 | if (priv->draw_sensitive != draw_sensitive) |
1134 | { |
1135 | priv->draw_sensitive = draw_sensitive; |
1136 | |
1137 | g_object_notify (G_OBJECT (cell_view), property_name: "draw-sensitive" ); |
1138 | } |
1139 | } |
1140 | |
1141 | /** |
1142 | * gtk_cell_view_get_fit_model: |
1143 | * @cell_view: a `GtkCellView` |
1144 | * |
1145 | * Gets whether @cell_view is configured to request space |
1146 | * to fit the entire `GtkTreeModel`. |
1147 | * |
1148 | * Returns: whether @cell_view requests space to fit |
1149 | * the entire `GtkTreeModel`. |
1150 | */ |
1151 | gboolean |
1152 | gtk_cell_view_get_fit_model (GtkCellView *cell_view) |
1153 | { |
1154 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1155 | |
1156 | g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE); |
1157 | |
1158 | return priv->fit_model; |
1159 | } |
1160 | |
1161 | /** |
1162 | * gtk_cell_view_set_fit_model: |
1163 | * @cell_view: a `GtkCellView` |
1164 | * @fit_model: whether @cell_view should request space for the whole model. |
1165 | * |
1166 | * Sets whether @cell_view should request space to fit the entire `GtkTreeModel`. |
1167 | * |
1168 | * This is used by `GtkComboBox` to ensure that the cell view displayed on |
1169 | * the combo box’s button always gets enough space and does not resize |
1170 | * when selection changes. |
1171 | */ |
1172 | void |
1173 | gtk_cell_view_set_fit_model (GtkCellView *cell_view, |
1174 | gboolean fit_model) |
1175 | { |
1176 | GtkCellViewPrivate *priv = gtk_cell_view_get_instance_private (self: cell_view); |
1177 | |
1178 | g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); |
1179 | |
1180 | if (priv->fit_model != fit_model) |
1181 | { |
1182 | priv->fit_model = fit_model; |
1183 | |
1184 | gtk_cell_area_context_reset (context: priv->context); |
1185 | |
1186 | g_object_notify (G_OBJECT (cell_view), property_name: "fit-model" ); |
1187 | } |
1188 | } |
1189 | |