1 /*
2 * Copyright (C) 2018 Purism SPC
3 *
4 * SPDX-License-Identifier: LGPL-2.1+
5 */
6
7 #include "config.h"
8 #include "hdy-expander-row.h"
9
10 #include <glib/gi18n-lib.h>
11 #include "hdy-action-row.h"
12
13 /**
14 * SECTION:hdy-expander-row
15 * @short_description: A #GtkListBox row used to reveal widgets.
16 * @Title: HdyExpanderRow
17 *
18 * The #HdyExpanderRow allows the user to reveal or hide widgets below it. It
19 * also allows the user to enable the expansion of the row, allowing to disable
20 * all that the row contains.
21 *
22 * It also supports adding a child as an action widget by specifying “action” as
23 * the “type” attribute of a <child> element. It also supports setting a
24 * child as a prefix widget by specifying “prefix” as the “type” attribute of a
25 * <child> element.
26 *
27 * # CSS nodes
28 *
29 * #HdyExpanderRow has a main CSS node with name row, and the .expander style
30 * class. It has the .empty style class when it contains no children.
31 *
32 * It contains the subnodes row.header for its main embedded row, list.nested
33 * for the list it can expand, and image.expander-row-arrow for its arrow.
34 *
35 * When expanded, #HdyExpanderRow will add the
36 * .checked-expander-row-previous-sibling style class to its previous sibling,
37 * and remove it when retracted.
38 *
39 * Since: 0.0.6
40 */
41
42 typedef struct
43 {
44 GtkBox *box;
45 GtkBox *actions;
46 GtkBox *prefixes;
47 GtkListBox *list;
48 HdyActionRow *action_row;
49 GtkSwitch *enable_switch;
50 GtkImage *image;
51
52 gboolean expanded;
53 gboolean enable_expansion;
54 gboolean show_enable_switch;
55 } HdyExpanderRowPrivate;
56
57 static void hdy_expander_row_buildable_init (GtkBuildableIface *iface);
58
59 G_DEFINE_TYPE_WITH_CODE (HdyExpanderRow, hdy_expander_row, HDY_TYPE_PREFERENCES_ROW,
60 G_ADD_PRIVATE (HdyExpanderRow)
61 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
62 hdy_expander_row_buildable_init))
63
64 static GtkBuildableIface *parent_buildable_iface;
65
66 enum {
67 PROP_0,
68 PROP_SUBTITLE,
69 PROP_USE_UNDERLINE,
70 PROP_ICON_NAME,
71 PROP_EXPANDED,
72 PROP_ENABLE_EXPANSION,
73 PROP_SHOW_ENABLE_SWITCH,
74 LAST_PROP,
75 };
76
77 static GParamSpec *props[LAST_PROP];
78
79 static void
update_arrow(HdyExpanderRow * self)80 update_arrow (HdyExpanderRow *self)
81 {
82 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
83 GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self));
84 GtkWidget *previous_sibling = NULL;
85
86 if (parent) {
87 g_autoptr (GList) siblings = gtk_container_get_children (GTK_CONTAINER (parent));
88 GList *l;
89
90 for (l = siblings; l != NULL && l->next != NULL && l->next->data != self; l = l->next);
91
92 if (l && l->next && l->next->data == self)
93 previous_sibling = l->data;
94 }
95
96 if (priv->expanded)
97 gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_CHECKED, FALSE);
98 else
99 gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_CHECKED);
100
101 if (previous_sibling) {
102 GtkStyleContext *previous_sibling_context = gtk_widget_get_style_context (previous_sibling);
103
104 if (priv->expanded)
105 gtk_style_context_add_class (previous_sibling_context, "checked-expander-row-previous-sibling");
106 else
107 gtk_style_context_remove_class (previous_sibling_context, "checked-expander-row-previous-sibling");
108 }
109 }
110
111 static void
hdy_expander_row_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)112 hdy_expander_row_get_property (GObject *object,
113 guint prop_id,
114 GValue *value,
115 GParamSpec *pspec)
116 {
117 HdyExpanderRow *self = HDY_EXPANDER_ROW (object);
118
119 switch (prop_id) {
120 case PROP_SUBTITLE:
121 g_value_set_string (value, hdy_expander_row_get_subtitle (self));
122 break;
123 case PROP_USE_UNDERLINE:
124 g_value_set_boolean (value, hdy_expander_row_get_use_underline (self));
125 break;
126 case PROP_ICON_NAME:
127 g_value_set_string (value, hdy_expander_row_get_icon_name (self));
128 break;
129 case PROP_EXPANDED:
130 g_value_set_boolean (value, hdy_expander_row_get_expanded (self));
131 break;
132 case PROP_ENABLE_EXPANSION:
133 g_value_set_boolean (value, hdy_expander_row_get_enable_expansion (self));
134 break;
135 case PROP_SHOW_ENABLE_SWITCH:
136 g_value_set_boolean (value, hdy_expander_row_get_show_enable_switch (self));
137 break;
138 default:
139 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
140 }
141 }
142
143 static void
hdy_expander_row_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)144 hdy_expander_row_set_property (GObject *object,
145 guint prop_id,
146 const GValue *value,
147 GParamSpec *pspec)
148 {
149 HdyExpanderRow *self = HDY_EXPANDER_ROW (object);
150
151 switch (prop_id) {
152 case PROP_SUBTITLE:
153 hdy_expander_row_set_subtitle (self, g_value_get_string (value));
154 break;
155 case PROP_USE_UNDERLINE:
156 hdy_expander_row_set_use_underline (self, g_value_get_boolean (value));
157 break;
158 case PROP_ICON_NAME:
159 hdy_expander_row_set_icon_name (self, g_value_get_string (value));
160 break;
161 case PROP_EXPANDED:
162 hdy_expander_row_set_expanded (self, g_value_get_boolean (value));
163 break;
164 case PROP_ENABLE_EXPANSION:
165 hdy_expander_row_set_enable_expansion (self, g_value_get_boolean (value));
166 break;
167 case PROP_SHOW_ENABLE_SWITCH:
168 hdy_expander_row_set_show_enable_switch (self, g_value_get_boolean (value));
169 break;
170 default:
171 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
172 }
173 }
174
175 static void
hdy_expander_row_forall(GtkContainer * container,gboolean include_internals,GtkCallback callback,gpointer callback_data)176 hdy_expander_row_forall (GtkContainer *container,
177 gboolean include_internals,
178 GtkCallback callback,
179 gpointer callback_data)
180 {
181 HdyExpanderRow *self = HDY_EXPANDER_ROW (container);
182 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
183
184 if (include_internals)
185 GTK_CONTAINER_CLASS (hdy_expander_row_parent_class)->forall (container,
186 include_internals,
187 callback,
188 callback_data);
189 else {
190 if (priv->prefixes)
191 gtk_container_foreach (GTK_CONTAINER (priv->prefixes), callback, callback_data);
192 if (priv->actions)
193 gtk_container_foreach (GTK_CONTAINER (priv->actions), callback, callback_data);
194 if (priv->list)
195 gtk_container_foreach (GTK_CONTAINER (priv->list), callback, callback_data);
196 }
197 }
198
199 static void
activate_cb(HdyExpanderRow * self)200 activate_cb (HdyExpanderRow *self)
201 {
202 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
203
204 hdy_expander_row_set_expanded (self, !priv->expanded);
205 }
206
207 static void
count_children_cb(GtkWidget * widget,gint * count)208 count_children_cb (GtkWidget *widget,
209 gint *count)
210 {
211 (*count)++;
212 }
213
214 static void
list_children_changed_cb(HdyExpanderRow * self)215 list_children_changed_cb (HdyExpanderRow *self)
216 {
217 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
218 GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (self));
219 gint count = 0;
220
221 gtk_container_foreach (GTK_CONTAINER (priv->list), (GtkCallback) count_children_cb, &count);
222
223 if (count == 0)
224 gtk_style_context_add_class (context, "empty");
225 else
226 gtk_style_context_remove_class (context, "empty");
227 }
228
229 static void
hdy_expander_row_add(GtkContainer * container,GtkWidget * child)230 hdy_expander_row_add (GtkContainer *container,
231 GtkWidget *child)
232 {
233 HdyExpanderRow *self = HDY_EXPANDER_ROW (container);
234 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
235
236 /* When constructing the widget, we want the box to be added as the child of
237 * the GtkListBoxRow, as an implementation detail.
238 */
239 if (priv->box == NULL)
240 GTK_CONTAINER_CLASS (hdy_expander_row_parent_class)->add (container, child);
241 else
242 gtk_container_add (GTK_CONTAINER (priv->list), child);
243 }
244
245 static void
hdy_expander_row_remove(GtkContainer * container,GtkWidget * child)246 hdy_expander_row_remove (GtkContainer *container,
247 GtkWidget *child)
248 {
249 HdyExpanderRow *self = HDY_EXPANDER_ROW (container);
250 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
251
252 if (child == GTK_WIDGET (priv->box))
253 GTK_CONTAINER_CLASS (hdy_expander_row_parent_class)->remove (container, child);
254 else if (gtk_widget_get_parent (child) == GTK_WIDGET (priv->actions))
255 gtk_container_remove (GTK_CONTAINER (priv->actions), child);
256 else if (gtk_widget_get_parent (child) == GTK_WIDGET (priv->prefixes))
257 gtk_container_remove (GTK_CONTAINER (priv->prefixes), child);
258 else
259 gtk_container_remove (GTK_CONTAINER (priv->list), child);
260 }
261
262 static void
hdy_expander_row_class_init(HdyExpanderRowClass * klass)263 hdy_expander_row_class_init (HdyExpanderRowClass *klass)
264 {
265 GObjectClass *object_class = G_OBJECT_CLASS (klass);
266 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
267 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
268
269 object_class->get_property = hdy_expander_row_get_property;
270 object_class->set_property = hdy_expander_row_set_property;
271
272 container_class->add = hdy_expander_row_add;
273 container_class->remove = hdy_expander_row_remove;
274 container_class->forall = hdy_expander_row_forall;
275
276 /**
277 * HdyExpanderRow:subtitle:
278 *
279 * The subtitle for this row.
280 *
281 * Since: 1.0
282 */
283 props[PROP_SUBTITLE] =
284 g_param_spec_string ("subtitle",
285 _("Subtitle"),
286 _("The subtitle for this row"),
287 "",
288 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
289
290 /**
291 * HdyExpanderRow:use-underline:
292 *
293 * Whether an embedded underline in the text of the title and subtitle labels
294 * indicates a mnemonic.
295 *
296 * Since: 1.0
297 */
298 props[PROP_USE_UNDERLINE] =
299 g_param_spec_boolean ("use-underline",
300 _("Use underline"),
301 _("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
302 FALSE,
303 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
304
305 /**
306 * HdyExpanderRow:icon-name:
307 *
308 * The icon name for this row.
309 *
310 * Since: 1.0
311 */
312 props[PROP_ICON_NAME] =
313 g_param_spec_string ("icon-name",
314 _("Icon name"),
315 _("Icon name"),
316 "",
317 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
318
319 /**
320 * HdyExpanderRow:expanded:
321 *
322 * %TRUE if the row is expanded.
323 */
324 props[PROP_EXPANDED] =
325 g_param_spec_boolean ("expanded",
326 _("Expanded"),
327 _("Whether the row is expanded"),
328 FALSE,
329 G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
330
331 /**
332 * HdyExpanderRow:enable-expansion:
333 *
334 * %TRUE if the expansion is enabled.
335 */
336 props[PROP_ENABLE_EXPANSION] =
337 g_param_spec_boolean ("enable-expansion",
338 _("Enable expansion"),
339 _("Whether the expansion is enabled"),
340 TRUE,
341 G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
342
343 /**
344 * HdyExpanderRow:show-enable-switch:
345 *
346 * %TRUE if the switch enabling the expansion is visible.
347 */
348 props[PROP_SHOW_ENABLE_SWITCH] =
349 g_param_spec_boolean ("show-enable-switch",
350 _("Show enable switch"),
351 _("Whether the switch enabling the expansion is visible"),
352 FALSE,
353 G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
354
355 g_object_class_install_properties (object_class, LAST_PROP, props);
356
357 gtk_widget_class_set_template_from_resource (widget_class,
358 "/sm/puri/handy/ui/hdy-expander-row.ui");
359 gtk_widget_class_bind_template_child_private (widget_class, HdyExpanderRow, action_row);
360 gtk_widget_class_bind_template_child_private (widget_class, HdyExpanderRow, box);
361 gtk_widget_class_bind_template_child_private (widget_class, HdyExpanderRow, actions);
362 gtk_widget_class_bind_template_child_private (widget_class, HdyExpanderRow, list);
363 gtk_widget_class_bind_template_child_private (widget_class, HdyExpanderRow, image);
364 gtk_widget_class_bind_template_child_private (widget_class, HdyExpanderRow, enable_switch);
365 gtk_widget_class_bind_template_callback (widget_class, activate_cb);
366 gtk_widget_class_bind_template_callback (widget_class, list_children_changed_cb);
367 }
368
369 #define NOTIFY(func, prop) \
370 static void \
371 func (gpointer this) { \
372 g_object_notify_by_pspec (G_OBJECT (this), props[prop]); \
373 } \
374
375 NOTIFY (notify_subtitle_cb, PROP_SUBTITLE);
376 NOTIFY (notify_use_underline_cb, PROP_USE_UNDERLINE);
377 NOTIFY (notify_icon_name_cb, PROP_ICON_NAME);
378
379 static void
hdy_expander_row_init(HdyExpanderRow * self)380 hdy_expander_row_init (HdyExpanderRow *self)
381 {
382 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
383
384 priv->prefixes = NULL;
385
386 gtk_widget_init_template (GTK_WIDGET (self));
387
388 hdy_expander_row_set_enable_expansion (self, TRUE);
389 hdy_expander_row_set_expanded (self, FALSE);
390
391 g_signal_connect_object (priv->action_row, "notify::subtitle", G_CALLBACK (notify_subtitle_cb), self, G_CONNECT_SWAPPED);
392 g_signal_connect_object (priv->action_row, "notify::use-underline", G_CALLBACK (notify_use_underline_cb), self, G_CONNECT_SWAPPED);
393 g_signal_connect_object (priv->action_row, "notify::icon-name", G_CALLBACK (notify_icon_name_cb), self, G_CONNECT_SWAPPED);
394 }
395
396 static void
hdy_expander_row_buildable_add_child(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * type)397 hdy_expander_row_buildable_add_child (GtkBuildable *buildable,
398 GtkBuilder *builder,
399 GObject *child,
400 const gchar *type)
401 {
402 HdyExpanderRow *self = HDY_EXPANDER_ROW (buildable);
403 HdyExpanderRowPrivate *priv = hdy_expander_row_get_instance_private (self);
404
405 if (priv->box == NULL || !type)
406 gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (child));
407 else if (type && strcmp (type, "action") == 0)
408 hdy_expander_row_add_action (self, GTK_WIDGET (child));
409 else if (type && strcmp (type, "prefix") == 0)
410 hdy_expander_row_add_prefix (self, GTK_WIDGET (child));
411 else
412 GTK_BUILDER_WARN_INVALID_CHILD_TYPE (self, type);
413 }
414
415 static void
hdy_expander_row_buildable_init(GtkBuildableIface * iface)416 hdy_expander_row_buildable_init (GtkBuildableIface *iface)
417 {
418 parent_buildable_iface = g_type_interface_peek_parent (iface);
419 iface->add_child = hdy_expander_row_buildable_add_child;
420 }
421
422 /**
423 * hdy_expander_row_new:
424 *
425 * Creates a new #HdyExpanderRow.
426 *
427 * Returns: a new #HdyExpanderRow
428 *
429 * Since: 0.0.6
430 */
431 GtkWidget *
hdy_expander_row_new(void)432 hdy_expander_row_new (void)
433 {
434 return g_object_new (HDY_TYPE_EXPANDER_ROW, NULL);
435 }
436
437 /**
438 * hdy_expander_row_get_subtitle:
439 * @self: a #HdyExpanderRow
440 *
441 * Gets the subtitle for @self.
442 *
443 * Returns: (transfer none) (nullable): the subtitle for @self, or %NULL.
444 *
445 * Since: 1.0
446 */
447 const gchar *
hdy_expander_row_get_subtitle(HdyExpanderRow * self)448 hdy_expander_row_get_subtitle (HdyExpanderRow *self)
449 {
450 HdyExpanderRowPrivate *priv;
451
452 g_return_val_if_fail (HDY_IS_EXPANDER_ROW (self), NULL);
453
454 priv = hdy_expander_row_get_instance_private (self);
455
456 return hdy_action_row_get_subtitle (priv->action_row);
457 }
458
459 /**
460 * hdy_expander_row_set_subtitle:
461 * @self: a #HdyExpanderRow
462 * @subtitle: (nullable): the subtitle
463 *
464 * Sets the subtitle for @self.
465 *
466 * Since: 1.0
467 */
468 void
hdy_expander_row_set_subtitle(HdyExpanderRow * self,const gchar * subtitle)469 hdy_expander_row_set_subtitle (HdyExpanderRow *self,
470 const gchar *subtitle)
471 {
472 HdyExpanderRowPrivate *priv;
473
474 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
475
476 priv = hdy_expander_row_get_instance_private (self);
477
478 hdy_action_row_set_subtitle (priv->action_row, subtitle);
479 }
480
481 /**
482 * hdy_expander_row_get_use_underline:
483 * @self: a #HdyExpanderRow
484 *
485 * Gets whether an embedded underline in the text of the title and subtitle
486 * labels indicates a mnemonic. See hdy_expander_row_set_use_underline().
487 *
488 * Returns: %TRUE if an embedded underline in the title and subtitle labels
489 * indicates the mnemonic accelerator keys.
490 *
491 * Since: 1.0
492 */
493 gboolean
hdy_expander_row_get_use_underline(HdyExpanderRow * self)494 hdy_expander_row_get_use_underline (HdyExpanderRow *self)
495 {
496 HdyExpanderRowPrivate *priv;
497
498 g_return_val_if_fail (HDY_IS_EXPANDER_ROW (self), FALSE);
499
500 priv = hdy_expander_row_get_instance_private (self);
501
502 return hdy_action_row_get_use_underline (priv->action_row);
503 }
504
505 /**
506 * hdy_expander_row_set_use_underline:
507 * @self: a #HdyExpanderRow
508 * @use_underline: %TRUE if underlines in the text indicate mnemonics
509 *
510 * If true, an underline in the text of the title and subtitle labels indicates
511 * the next character should be used for the mnemonic accelerator key.
512 *
513 * Since: 1.0
514 */
515 void
hdy_expander_row_set_use_underline(HdyExpanderRow * self,gboolean use_underline)516 hdy_expander_row_set_use_underline (HdyExpanderRow *self,
517 gboolean use_underline)
518 {
519 HdyExpanderRowPrivate *priv;
520
521 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
522
523 priv = hdy_expander_row_get_instance_private (self);
524
525 hdy_action_row_set_use_underline (priv->action_row, use_underline);
526 }
527
528 /**
529 * hdy_expander_row_get_icon_name:
530 * @self: a #HdyExpanderRow
531 *
532 * Gets the icon name for @self.
533 *
534 * Returns: the icon name for @self.
535 *
536 * Since: 1.0
537 */
538 const gchar *
hdy_expander_row_get_icon_name(HdyExpanderRow * self)539 hdy_expander_row_get_icon_name (HdyExpanderRow *self)
540 {
541 HdyExpanderRowPrivate *priv;
542
543 g_return_val_if_fail (HDY_IS_EXPANDER_ROW (self), NULL);
544
545 priv = hdy_expander_row_get_instance_private (self);
546
547 return hdy_action_row_get_icon_name (priv->action_row);
548 }
549
550 /**
551 * hdy_expander_row_set_icon_name:
552 * @self: a #HdyExpanderRow
553 * @icon_name: the icon name
554 *
555 * Sets the icon name for @self.
556 *
557 * Since: 1.0
558 */
559 void
hdy_expander_row_set_icon_name(HdyExpanderRow * self,const gchar * icon_name)560 hdy_expander_row_set_icon_name (HdyExpanderRow *self,
561 const gchar *icon_name)
562 {
563 HdyExpanderRowPrivate *priv;
564
565 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
566
567 priv = hdy_expander_row_get_instance_private (self);
568
569 hdy_action_row_set_icon_name (priv->action_row, icon_name);
570 }
571
572 gboolean
hdy_expander_row_get_expanded(HdyExpanderRow * self)573 hdy_expander_row_get_expanded (HdyExpanderRow *self)
574 {
575 HdyExpanderRowPrivate *priv;
576
577 g_return_val_if_fail (HDY_IS_EXPANDER_ROW (self), FALSE);
578
579 priv = hdy_expander_row_get_instance_private (self);
580
581 return priv->expanded;
582 }
583
584 void
hdy_expander_row_set_expanded(HdyExpanderRow * self,gboolean expanded)585 hdy_expander_row_set_expanded (HdyExpanderRow *self,
586 gboolean expanded)
587 {
588 HdyExpanderRowPrivate *priv;
589
590 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
591
592 priv = hdy_expander_row_get_instance_private (self);
593
594 expanded = !!expanded && priv->enable_expansion;
595
596 if (priv->expanded == expanded)
597 return;
598
599 priv->expanded = expanded;
600
601 update_arrow (self);
602
603 g_object_notify_by_pspec (G_OBJECT (self), props[PROP_EXPANDED]);
604 }
605
606 /**
607 * hdy_expander_row_get_enable_expansion:
608 * @self: a #HdyExpanderRow
609 *
610 * Gets whether the expansion of @self is enabled.
611 *
612 * Returns: whether the expansion of @self is enabled.
613 *
614 * Since: 0.0.6
615 */
616 gboolean
hdy_expander_row_get_enable_expansion(HdyExpanderRow * self)617 hdy_expander_row_get_enable_expansion (HdyExpanderRow *self)
618 {
619 HdyExpanderRowPrivate *priv;
620
621 g_return_val_if_fail (HDY_IS_EXPANDER_ROW (self), FALSE);
622
623 priv = hdy_expander_row_get_instance_private (self);
624
625 return priv->enable_expansion;
626 }
627
628 /**
629 * hdy_expander_row_set_enable_expansion:
630 * @self: a #HdyExpanderRow
631 * @enable_expansion: %TRUE to enable the expansion
632 *
633 * Sets whether the expansion of @self is enabled.
634 *
635 * Since: 0.0.6
636 */
637 void
hdy_expander_row_set_enable_expansion(HdyExpanderRow * self,gboolean enable_expansion)638 hdy_expander_row_set_enable_expansion (HdyExpanderRow *self,
639 gboolean enable_expansion)
640 {
641 HdyExpanderRowPrivate *priv;
642
643 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
644
645 priv = hdy_expander_row_get_instance_private (self);
646
647 enable_expansion = !!enable_expansion;
648
649 if (priv->enable_expansion == enable_expansion)
650 return;
651
652 priv->enable_expansion = enable_expansion;
653
654 hdy_expander_row_set_expanded (self, priv->enable_expansion);
655
656 g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ENABLE_EXPANSION]);
657 }
658
659 /**
660 * hdy_expander_row_get_show_enable_switch:
661 * @self: a #HdyExpanderRow
662 *
663 * Gets whether the switch enabling the expansion of @self is visible.
664 *
665 * Returns: whether the switch enabling the expansion of @self is visible.
666 *
667 * Since: 0.0.6
668 */
669 gboolean
hdy_expander_row_get_show_enable_switch(HdyExpanderRow * self)670 hdy_expander_row_get_show_enable_switch (HdyExpanderRow *self)
671 {
672 HdyExpanderRowPrivate *priv;
673
674 g_return_val_if_fail (HDY_IS_EXPANDER_ROW (self), FALSE);
675
676 priv = hdy_expander_row_get_instance_private (self);
677
678 return priv->show_enable_switch;
679 }
680
681 /**
682 * hdy_expander_row_set_show_enable_switch:
683 * @self: a #HdyExpanderRow
684 * @show_enable_switch: %TRUE to show the switch enabling the expansion
685 *
686 * Sets whether the switch enabling the expansion of @self is visible.
687 *
688 * Since: 0.0.6
689 */
690 void
hdy_expander_row_set_show_enable_switch(HdyExpanderRow * self,gboolean show_enable_switch)691 hdy_expander_row_set_show_enable_switch (HdyExpanderRow *self,
692 gboolean show_enable_switch)
693 {
694 HdyExpanderRowPrivate *priv;
695
696 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
697
698 priv = hdy_expander_row_get_instance_private (self);
699
700 show_enable_switch = !!show_enable_switch;
701
702 if (priv->show_enable_switch == show_enable_switch)
703 return;
704
705 priv->show_enable_switch = show_enable_switch;
706
707 g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SHOW_ENABLE_SWITCH]);
708 }
709
710 /**
711 * hdy_expander_row_add_action:
712 * @self: a #HdyExpanderRow
713 * @widget: the action widget
714 *
715 * Adds an action widget to @self.
716 *
717 * Since: 1.0
718 */
719 void
hdy_expander_row_add_action(HdyExpanderRow * self,GtkWidget * widget)720 hdy_expander_row_add_action (HdyExpanderRow *self,
721 GtkWidget *widget)
722 {
723 HdyExpanderRowPrivate *priv;
724
725 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
726 g_return_if_fail (GTK_IS_WIDGET (self));
727
728 priv = hdy_expander_row_get_instance_private (self);
729
730 gtk_box_pack_start (priv->actions, widget, FALSE, TRUE, 0);
731 gtk_widget_show (GTK_WIDGET (priv->actions));
732 }
733
734 /**
735 * hdy_expander_row_add_prefix:
736 * @self: a #HdyExpanderRow
737 * @widget: the prefix widget
738 *
739 * Adds a prefix widget to @self.
740 *
741 * Since: 1.0
742 */
743 void
hdy_expander_row_add_prefix(HdyExpanderRow * self,GtkWidget * widget)744 hdy_expander_row_add_prefix (HdyExpanderRow *self,
745 GtkWidget *widget)
746 {
747 HdyExpanderRowPrivate *priv;
748
749 g_return_if_fail (HDY_IS_EXPANDER_ROW (self));
750 g_return_if_fail (GTK_IS_WIDGET (widget));
751
752 priv = hdy_expander_row_get_instance_private (self);
753
754 if (priv->prefixes == NULL) {
755 priv->prefixes = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12));
756 gtk_widget_set_no_show_all (GTK_WIDGET (priv->prefixes), TRUE);
757 gtk_widget_set_can_focus (GTK_WIDGET (priv->prefixes), FALSE);
758 hdy_action_row_add_prefix (HDY_ACTION_ROW (priv->action_row), GTK_WIDGET (priv->prefixes));
759 }
760 gtk_box_pack_start (priv->prefixes, widget, FALSE, TRUE, 0);
761 gtk_widget_show (GTK_WIDGET (priv->prefixes));
762 }
763