Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-menu-stack"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gtk/gtk.h>
9 : :
10 : : #include "valent-menu-list.h"
11 : : #include "valent-menu-stack.h"
12 : :
13 : :
14 : : struct _ValentMenuStack
15 : : {
16 : : GtkWidget parent_instance;
17 : :
18 : : GtkWidget *stack;
19 : : ValentMenuList *main;
20 : : };
21 : :
22 [ + + + - ]: 41 : G_DEFINE_FINAL_TYPE (ValentMenuStack, valent_menu_stack, GTK_TYPE_WIDGET)
23 : :
24 : : typedef enum {
25 : : PROP_MENU_MODEL = 1,
26 : : } ValentMenuStackProperty;
27 : :
28 : : static GParamSpec *properties[PROP_MENU_MODEL + 1] = { NULL, };
29 : :
30 : :
31 : : /*
32 : : * GObject
33 : : */
34 : : static void
35 : 3 : valent_menu_stack_dispose (GObject *object)
36 : : {
37 : 3 : ValentMenuStack *self = VALENT_MENU_STACK (object);
38 : :
39 [ + - ]: 3 : g_clear_pointer (&self->stack, gtk_widget_unparent);
40 : :
41 : 3 : G_OBJECT_CLASS (valent_menu_stack_parent_class)->dispose (object);
42 : 3 : }
43 : :
44 : : static void
45 : 0 : valent_menu_stack_get_property (GObject *object,
46 : : guint prop_id,
47 : : GValue *value,
48 : : GParamSpec *pspec)
49 : : {
50 : 0 : ValentMenuStack *self = VALENT_MENU_STACK (object);
51 : :
52 [ # # ]: 0 : switch ((ValentMenuStackProperty)prop_id)
53 : : {
54 : 0 : case PROP_MENU_MODEL:
55 : 0 : g_value_set_object (value, valent_menu_stack_get_menu_model (self));
56 : 0 : break;
57 : :
58 : 0 : default:
59 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
60 : : }
61 : 0 : }
62 : :
63 : : static void
64 : 0 : valent_menu_stack_set_property (GObject *object,
65 : : guint prop_id,
66 : : const GValue *value,
67 : : GParamSpec *pspec)
68 : : {
69 : 0 : ValentMenuStack *self = VALENT_MENU_STACK (object);
70 : :
71 [ # # ]: 0 : switch ((ValentMenuStackProperty)prop_id)
72 : : {
73 : 0 : case PROP_MENU_MODEL:
74 : 0 : valent_menu_stack_set_menu_model (self, g_value_get_object (value));
75 : 0 : break;
76 : :
77 : 0 : default:
78 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
79 : : }
80 : 0 : }
81 : :
82 : : static void
83 : 2 : valent_menu_stack_class_init (ValentMenuStackClass *klass)
84 : : {
85 : 2 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
86 : 2 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
87 : :
88 : 2 : object_class->dispose = valent_menu_stack_dispose;
89 : 2 : object_class->get_property = valent_menu_stack_get_property;
90 : 2 : object_class->set_property = valent_menu_stack_set_property;
91 : :
92 : 2 : gtk_widget_class_set_css_name (widget_class, "valent-menu-stack");
93 : 2 : gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
94 : :
95 : : /**
96 : : * ValentMenuStack:model:
97 : : *
98 : : * The `GMenuModel` for this `ValentMenuStack`.
99 : : */
100 : 4 : properties [PROP_MENU_MODEL] =
101 : 2 : g_param_spec_object ("menu-model", NULL, NULL,
102 : : G_TYPE_MENU_MODEL,
103 : : (G_PARAM_READWRITE |
104 : : G_PARAM_EXPLICIT_NOTIFY |
105 : : G_PARAM_STATIC_STRINGS));
106 : :
107 : 2 : g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
108 : 2 : }
109 : :
110 : : static void
111 : 3 : valent_menu_stack_init (ValentMenuStack *self)
112 : : {
113 : 3 : self->stack = g_object_new (GTK_TYPE_STACK,
114 : : "interpolate-size", TRUE,
115 : : "transition-type", GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT,
116 : : "vhomogeneous", FALSE,
117 : : NULL);
118 : 3 : gtk_widget_insert_before (self->stack, GTK_WIDGET (self), NULL);
119 : 3 : }
120 : :
121 : : /**
122 : : * valent_menu_stack_new:
123 : : * @menu_model: (nullable): a `GMenuModel`
124 : : *
125 : : * Create a new `ValentMenuStack`.
126 : : *
127 : : * Returns: a `GtkWidget`
128 : : */
129 : : GtkWidget *
130 : 0 : valent_menu_stack_new (GMenuModel *menu_model)
131 : : {
132 : 0 : return g_object_new (VALENT_TYPE_MENU_STACK,
133 : : "menu-model", menu_model,
134 : : NULL);
135 : : }
136 : :
137 : : /**
138 : : * valent_menu_stack_get_model:
139 : : * @stack: a `ValentMenuStack`
140 : : *
141 : : * Get the `GMenuModel` for @stack.
142 : : *
143 : : * Returns: (transfer none) (nullable): a `GMenuModel`
144 : : */
145 : : GMenuModel *
146 : 0 : valent_menu_stack_get_menu_model (ValentMenuStack *stack)
147 : : {
148 [ # # ]: 0 : g_return_val_if_fail (VALENT_IS_MENU_STACK (stack), NULL);
149 : :
150 [ # # ]: 0 : if (stack->main == NULL)
151 : : return NULL;
152 : :
153 : 0 : return valent_menu_list_get_menu_model (stack->main);
154 : : }
155 : :
156 : : /**
157 : : * valent_menu_stack_set_model:
158 : : * @stack: a `ValentMenuStack`
159 : : * @menu_model: (nullable): a `GMenuModel`
160 : : *
161 : : * Set the `GMenuModel` for @stack to @menu_model.
162 : : */
163 : : void
164 : 3 : valent_menu_stack_set_menu_model (ValentMenuStack *stack,
165 : : GMenuModel *menu_model)
166 : : {
167 [ + - ]: 3 : g_return_if_fail (VALENT_IS_MENU_STACK (stack));
168 [ + - + - : 3 : g_return_if_fail (menu_model == NULL || G_IS_MENU_MODEL (menu_model));
+ - - + ]
169 : :
170 : : /* Destroy any existing menu lists */
171 [ - + ]: 3 : if (stack->main != NULL)
172 : : {
173 : 0 : gtk_stack_remove (GTK_STACK (stack->stack), GTK_WIDGET (stack->main));
174 : 0 : stack->main = NULL;
175 : : }
176 : :
177 [ + - ]: 3 : if (menu_model != NULL)
178 : : {
179 : 3 : stack->main = valent_menu_list_new (NULL);
180 : 3 : gtk_stack_add_named (GTK_STACK (stack->stack),
181 : : GTK_WIDGET (stack->main),
182 : : "main");
183 : 3 : valent_menu_list_set_menu_model (stack->main, menu_model);
184 : : }
185 : : }
186 : :
|