File: | ctk/ctkmenusectionbox.c |
Warning: | line 394, column 28 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright © 2014 Canonical Limited |
3 | * Copyright © 2013 Carlos Garnacho |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the licence, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | * Author: Ryan Lortie <desrt@desrt.ca> |
19 | */ |
20 | |
21 | #include "config.h" |
22 | |
23 | #include "ctkmenusectionbox.h" |
24 | |
25 | #include "ctkwidgetprivate.h" |
26 | #include "ctklabel.h" |
27 | #include "ctkmenutracker.h" |
28 | #include "ctkmodelbutton.h" |
29 | #include "ctkseparator.h" |
30 | #include "ctksizegroup.h" |
31 | #include "ctkstack.h" |
32 | #include "ctkstylecontext.h" |
33 | #include "ctkpopover.h" |
34 | #include "ctkorientable.h" |
35 | |
36 | typedef CtkBoxClass CtkMenuSectionBoxClass; |
37 | |
38 | struct _CtkMenuSectionBox |
39 | { |
40 | CtkBox parent_instance; |
41 | |
42 | CtkMenuSectionBox *toplevel; |
43 | CtkMenuTracker *tracker; |
44 | CtkBox *item_box; |
45 | CtkWidget *separator; |
46 | guint separator_sync_idle; |
47 | gboolean iconic; |
48 | gint depth; |
49 | }; |
50 | |
51 | typedef struct |
52 | { |
53 | gint n_items; |
54 | gboolean previous_is_iconic; |
55 | } MenuData; |
56 | |
57 | G_DEFINE_TYPE (CtkMenuSectionBox, ctk_menu_section_box, CTK_TYPE_BOX)static void ctk_menu_section_box_init (CtkMenuSectionBox *self ); static void ctk_menu_section_box_class_init (CtkMenuSectionBoxClass *klass); static GType ctk_menu_section_box_get_type_once (void ); static gpointer ctk_menu_section_box_parent_class = ((void *)0); static gint CtkMenuSectionBox_private_offset; static void ctk_menu_section_box_class_intern_init (gpointer klass) { ctk_menu_section_box_parent_class = g_type_class_peek_parent (klass); if (CtkMenuSectionBox_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkMenuSectionBox_private_offset ); ctk_menu_section_box_class_init ((CtkMenuSectionBoxClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_menu_section_box_get_instance_private (CtkMenuSectionBox *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkMenuSectionBox_private_offset )))); } GType ctk_menu_section_box_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); (void) (0 ? (gpointer) * ( &static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_menu_section_box_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_menu_section_box_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((ctk_box_get_type ()), g_intern_static_string ("CtkMenuSectionBox" ), sizeof (CtkMenuSectionBoxClass), (GClassInitFunc)(void (*) (void)) ctk_menu_section_box_class_intern_init, sizeof (CtkMenuSectionBox ), (GInstanceInitFunc)(void (*)(void)) ctk_menu_section_box_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } |
58 | |
59 | static void ctk_menu_section_box_sync_separators (CtkMenuSectionBox *box, |
60 | MenuData *data); |
61 | static void ctk_menu_section_box_new_submenu (CtkMenuTrackerItem *item, |
62 | CtkMenuSectionBox *toplevel, |
63 | CtkWidget *focus, |
64 | const gchar *name); |
65 | static CtkWidget * ctk_menu_section_box_new_section (CtkMenuTrackerItem *item, |
66 | CtkMenuSectionBox *parent); |
67 | |
68 | static void |
69 | ctk_menu_section_box_sync_item (CtkWidget *widget, |
70 | gpointer user_data) |
71 | { |
72 | MenuData *data = (MenuData *)user_data; |
73 | |
74 | if (CTK_IS_MENU_SECTION_BOX (widget)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (widget)); GType __t = ((ctk_menu_section_box_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
75 | ctk_menu_section_box_sync_separators (CTK_MENU_SECTION_BOX (widget)((((CtkMenuSectionBox*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((widget)), ((ctk_menu_section_box_get_type ( ))))))), data); |
76 | else |
77 | data->n_items++; |
78 | } |
79 | |
80 | /* We are trying to implement the following rules here: |
81 | * |
82 | * rule 1: never ever show separators for empty sections |
83 | * rule 2: always show a separator if there is a label |
84 | * rule 3: don't show a separator for the first section |
85 | * rule 4: don't show a separator for the following sections if there are |
86 | * no items before it |
87 | * rule 5: never show separators directly above or below an iconic box |
88 | * (rule 6: these rules don't apply exactly the same way for subsections) |
89 | */ |
90 | static void |
91 | ctk_menu_section_box_sync_separators (CtkMenuSectionBox *box, |
92 | MenuData *data) |
93 | { |
94 | gboolean previous_section_is_iconic; |
95 | gboolean should_have_separator; |
96 | gboolean should_have_top_margin = FALSE(0); |
97 | gboolean is_not_empty_item; |
98 | gboolean has_separator; |
99 | gboolean has_label; |
100 | gboolean separator_condition; |
101 | gint n_items_before; |
102 | |
103 | n_items_before = data->n_items; |
104 | previous_section_is_iconic = data->previous_is_iconic; |
105 | |
106 | ctk_container_foreach (CTK_CONTAINER (box->item_box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_container_get_type ())))))), ctk_menu_section_box_sync_item, data); |
107 | |
108 | is_not_empty_item = (data->n_items > n_items_before); |
109 | |
110 | if (is_not_empty_item) |
111 | data->previous_is_iconic = box->iconic; |
112 | |
113 | if (box->separator == NULL((void*)0)) |
114 | return; |
115 | |
116 | has_separator = ctk_widget_get_parent (box->separator) != NULL((void*)0); |
117 | has_label = !CTK_IS_SEPARATOR (box->separator)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (box->separator)); GType __t = ((ctk_separator_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))); |
118 | |
119 | separator_condition = has_label ? TRUE(!(0)) : n_items_before > 0 && |
120 | box->depth <= 1 && |
121 | !previous_section_is_iconic && |
122 | !box->iconic; |
123 | |
124 | should_have_separator = separator_condition && is_not_empty_item; |
125 | |
126 | should_have_top_margin = !should_have_separator && |
127 | (box->depth <= 1 || box->iconic) && |
128 | n_items_before > 0 && |
129 | is_not_empty_item; |
130 | |
131 | ctk_widget_set_margin_top (CTK_WIDGET (box->item_box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_widget_get_type ())))))), should_have_top_margin ? 10 : 0); |
132 | |
133 | if (should_have_separator == has_separator) |
134 | return; |
135 | |
136 | if (should_have_separator) |
137 | ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), box->separator, FALSE(0), FALSE(0), 0); |
138 | else |
139 | ctk_container_remove (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ())))))), box->separator); |
140 | } |
141 | |
142 | static gboolean |
143 | ctk_menu_section_box_handle_sync_separators (gpointer user_data) |
144 | { |
145 | CtkMenuSectionBox *box = user_data; |
146 | MenuData data; |
147 | |
148 | data.n_items = 0; |
149 | data.previous_is_iconic = FALSE(0); |
150 | ctk_menu_section_box_sync_separators (box, &data); |
151 | |
152 | box->separator_sync_idle = 0; |
153 | |
154 | return G_SOURCE_REMOVE(0); |
155 | } |
156 | |
157 | static void |
158 | ctk_menu_section_box_schedule_separator_sync (CtkMenuSectionBox *box) |
159 | { |
160 | box = box->toplevel; |
161 | |
162 | if (!box->separator_sync_idle) |
163 | box->separator_sync_idle = cdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE100, /* before resize... */ |
164 | ctk_menu_section_box_handle_sync_separators, |
165 | box, NULL((void*)0)); |
166 | } |
167 | |
168 | static void |
169 | ctk_popover_item_activate (CtkWidget *button, |
170 | gpointer user_data) |
171 | { |
172 | CtkMenuTrackerItem *item = user_data; |
173 | CtkWidget *popover = NULL((void*)0); |
174 | |
175 | if (ctk_menu_tracker_item_get_role (item) == CTK_MENU_TRACKER_ITEM_ROLE_NORMAL) |
176 | { |
177 | /* Activating the item could cause the popover |
178 | * to be free'd, for example if it is a Quit item |
179 | */ |
180 | popover = g_object_ref (ctk_widget_get_ancestor (button,((__typeof__ (ctk_widget_get_ancestor (button, (ctk_popover_get_type ())))) (g_object_ref) (ctk_widget_get_ancestor (button, (ctk_popover_get_type ())))) |
181 | CTK_TYPE_POPOVER))((__typeof__ (ctk_widget_get_ancestor (button, (ctk_popover_get_type ())))) (g_object_ref) (ctk_widget_get_ancestor (button, (ctk_popover_get_type ())))); |
182 | } |
183 | |
184 | ctk_menu_tracker_item_activated (item); |
185 | |
186 | if (popover != NULL((void*)0)) |
187 | { |
188 | ctk_widget_hide (popover); |
189 | g_object_unref (popover); |
190 | } |
191 | } |
192 | |
193 | static void |
194 | ctk_menu_section_box_remove_func (gint position, |
195 | gpointer user_data) |
196 | { |
197 | CtkMenuSectionBox *box = user_data; |
198 | CtkMenuTrackerItem *item; |
199 | CtkWidget *widget; |
200 | GList *children; |
201 | |
202 | children = ctk_container_get_children (CTK_CONTAINER (box->item_box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_container_get_type ()))))))); |
203 | |
204 | widget = g_list_nth_data (children, position); |
205 | |
206 | item = g_object_get_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), "CtkMenuTrackerItem"); |
207 | if (ctk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU"submenu")) |
208 | { |
209 | CtkWidget *stack, *subbox; |
210 | |
211 | stack = ctk_widget_get_ancestor (CTK_WIDGET (box->toplevel)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->toplevel)), ((ctk_widget_get_type ())))))), CTK_TYPE_STACK(ctk_stack_get_type ())); |
212 | subbox = ctk_stack_get_child_by_name (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), ctk_menu_tracker_item_get_label (item)); |
213 | if (subbox != NULL((void*)0)) |
214 | ctk_container_remove (CTK_CONTAINER (stack)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_container_get_type ())))))), subbox); |
215 | } |
216 | |
217 | ctk_widget_destroy (g_list_nth_data (children, position)); |
218 | g_list_free (children); |
219 | |
220 | ctk_menu_section_box_schedule_separator_sync (box); |
221 | } |
222 | |
223 | static gboolean |
224 | get_ancestors (CtkWidget *widget, |
225 | GType widget_type, |
226 | CtkWidget **ancestor, |
227 | CtkWidget **below) |
228 | { |
229 | CtkWidget *a, *b; |
230 | |
231 | a = NULL((void*)0); |
232 | b = widget; |
233 | while (b != NULL((void*)0)) |
234 | { |
235 | a = ctk_widget_get_parent (b); |
236 | if (!a) |
237 | return FALSE(0); |
238 | if (g_type_is_a (G_OBJECT_TYPE (a), widget_type)(((((((GTypeClass*) (((GTypeInstance*) (a))->g_class))-> g_type)))) == (widget_type) || (g_type_is_a) (((((((GTypeClass *) (((GTypeInstance*) (a))->g_class))->g_type)))), (widget_type )))) |
239 | break; |
240 | b = a; |
241 | } |
242 | |
243 | *below = b; |
244 | *ancestor = a; |
245 | |
246 | return TRUE(!(0)); |
247 | } |
248 | |
249 | static void |
250 | close_submenu (CtkWidget *button, |
251 | gpointer data) |
252 | { |
253 | CtkMenuTrackerItem *item = data; |
254 | CtkWidget *focus; |
255 | |
256 | if (ctk_menu_tracker_item_get_should_request_show (item)) |
257 | ctk_menu_tracker_item_request_submenu_shown (item, FALSE(0)); |
258 | |
259 | focus = CTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((button)), (((GType) ((20) << (2))) ))))), "focus"))), ((ctk_widget_get_type ())))))); |
260 | ctk_widget_grab_focus (focus); |
261 | } |
262 | |
263 | static void |
264 | open_submenu (CtkWidget *button, |
265 | gpointer data) |
266 | { |
267 | CtkMenuTrackerItem *item = data; |
268 | CtkWidget *focus; |
269 | |
270 | if (ctk_menu_tracker_item_get_should_request_show (item)) |
271 | ctk_menu_tracker_item_request_submenu_shown (item, TRUE(!(0))); |
272 | |
273 | focus = CTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((button)), (((GType) ((20) << (2))) ))))), "focus"))), ((ctk_widget_get_type ())))))); |
274 | ctk_widget_grab_focus (focus); |
275 | } |
276 | |
277 | static void |
278 | ctk_menu_section_box_insert_func (CtkMenuTrackerItem *item, |
279 | gint position, |
280 | gpointer user_data) |
281 | { |
282 | CtkMenuSectionBox *box = user_data; |
283 | CtkWidget *widget; |
284 | |
285 | if (ctk_menu_tracker_item_get_is_separator (item)) |
286 | { |
287 | widget = ctk_menu_section_box_new_section (item, box); |
288 | } |
289 | else if (ctk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU"submenu")) |
290 | { |
291 | CtkWidget *stack = NULL((void*)0); |
292 | CtkWidget *parent = NULL((void*)0); |
293 | gchar *name; |
294 | |
295 | widget = g_object_new (CTK_TYPE_MODEL_BUTTON(ctk_model_button_get_type ()), |
296 | "menu-name", ctk_menu_tracker_item_get_label (item), |
297 | NULL((void*)0)); |
298 | g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE); |
299 | g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE); |
300 | g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE); |
301 | |
302 | get_ancestors (CTK_WIDGET (box->toplevel)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->toplevel)), ((ctk_widget_get_type ())))))), CTK_TYPE_STACK(ctk_stack_get_type ()), &stack, &parent); |
303 | ctk_container_child_get (CTK_CONTAINER (stack)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_container_get_type ())))))), parent, "name", &name, NULL((void*)0)); |
304 | ctk_menu_section_box_new_submenu (item, box->toplevel, widget, name); |
305 | g_free (name); |
306 | } |
307 | else |
308 | { |
309 | widget = ctk_model_button_new (); |
310 | g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE); |
311 | |
312 | if (box->iconic) |
313 | { |
314 | g_object_bind_property (item, "verb-icon", widget, "icon", G_BINDING_SYNC_CREATE); |
315 | g_object_set (widget, "iconic", TRUE(!(0)), "centered", TRUE(!(0)), NULL((void*)0)); |
316 | } |
317 | else |
318 | g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE); |
319 | |
320 | g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE); |
321 | g_object_bind_property (item, "role", widget, "role", G_BINDING_SYNC_CREATE); |
322 | g_object_bind_property (item, "toggled", widget, "active", G_BINDING_SYNC_CREATE); |
323 | g_signal_connect (widget, "clicked", G_CALLBACK (ctk_popover_item_activate), item)g_signal_connect_data ((widget), ("clicked"), (((GCallback) ( ctk_popover_item_activate))), (item), ((void*)0), (GConnectFlags ) 0); |
324 | } |
325 | |
326 | ctk_widget_show (widget); |
327 | |
328 | g_object_set_data_full (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), "CtkMenuTrackerItem", g_object_ref (item)((__typeof__ (item)) (g_object_ref) (item)), g_object_unref); |
329 | |
330 | ctk_widget_set_halign (widget, CTK_ALIGN_FILL); |
331 | if (box->iconic) |
332 | ctk_box_pack_start (CTK_BOX (box->item_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_box_get_type ())))))), widget, TRUE(!(0)), TRUE(!(0)), 0); |
333 | else |
334 | ctk_container_add (CTK_CONTAINER (box->item_box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_container_get_type ())))))), widget); |
335 | ctk_box_reorder_child (CTK_BOX (box->item_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_box_get_type ())))))), widget, position); |
336 | |
337 | ctk_menu_section_box_schedule_separator_sync (box); |
338 | } |
339 | |
340 | static void |
341 | ctk_menu_section_box_init (CtkMenuSectionBox *box) |
342 | { |
343 | CtkWidget *item_box; |
344 | |
345 | ctk_orientable_set_orientation (CTK_ORIENTABLE (box)((((CtkOrientable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_orientable_get_type ())))))), CTK_ORIENTATION_VERTICAL); |
346 | |
347 | box->toplevel = box; |
348 | |
349 | item_box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0); |
350 | box->item_box = CTK_BOX (item_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((item_box)), ((ctk_box_get_type ())))))); |
351 | ctk_box_pack_end (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), item_box, FALSE(0), FALSE(0), 0); |
352 | ctk_widget_set_halign (CTK_WIDGET (item_box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((item_box)), ((ctk_widget_get_type ())))))), CTK_ALIGN_FILL); |
353 | ctk_widget_show (item_box); |
354 | |
355 | ctk_widget_set_halign (CTK_WIDGET (box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_widget_get_type ())))))), CTK_ALIGN_FILL); |
356 | g_object_set (box, "margin", 0, NULL((void*)0)); |
357 | |
358 | } |
359 | |
360 | static void |
361 | ctk_menu_section_box_dispose (GObject *object) |
362 | { |
363 | CtkMenuSectionBox *box = CTK_MENU_SECTION_BOX (object)((((CtkMenuSectionBox*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_menu_section_box_get_type ( ))))))); |
364 | |
365 | if (box->separator_sync_idle) |
366 | { |
367 | g_source_remove (box->separator_sync_idle); |
368 | box->separator_sync_idle = 0; |
369 | } |
370 | |
371 | g_clear_object (&box->separator)do { _Static_assert (sizeof *((&box->separator)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((( &box->separator))) _pp = ((&box->separator)); __typeof__ (*((&box->separator))) _ptr = *_pp; *_pp = ((void*)0) ; if (_ptr) (g_object_unref) (_ptr); } while (0); |
372 | |
373 | if (box->tracker) |
374 | { |
375 | ctk_menu_tracker_free (box->tracker); |
376 | box->tracker = NULL((void*)0); |
377 | } |
378 | |
379 | G_OBJECT_CLASS (ctk_menu_section_box_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_menu_section_box_parent_class)), (((GType) ((20) << (2))))))))->dispose (object); |
380 | } |
381 | |
382 | static void |
383 | ctk_menu_section_box_class_init (CtkMenuSectionBoxClass *class) |
384 | { |
385 | G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2))))))))->dispose = ctk_menu_section_box_dispose; |
386 | } |
387 | |
388 | static void |
389 | update_popover_position_cb (GObject *source, |
390 | GParamSpec *spec G_GNUC_UNUSED__attribute__ ((__unused__)), |
391 | gpointer *user_data) |
392 | { |
393 | CtkPopover *popover = CTK_POPOVER (source)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((source)), ((ctk_popover_get_type ())))))); |
394 | CtkMenuSectionBox *box = CTK_MENU_SECTION_BOX (user_data)((((CtkMenuSectionBox*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((user_data)), ((ctk_menu_section_box_get_type ())))))); |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
395 | |
396 | CtkPositionType new_pos = ctk_popover_get_position (popover); |
397 | |
398 | GList *children = ctk_container_get_children (CTK_CONTAINER (ctk_widget_get_parent (CTK_WIDGET (box)))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_widget_get_parent (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((box)), ((ctk_widget_get_type ()))))))))) , ((ctk_container_get_type ()))))))); |
399 | GList *l; |
400 | |
401 | for (l = children; |
402 | l != NULL((void*)0); |
403 | l = l->next) |
404 | { |
405 | CtkWidget *w = l->data; |
406 | |
407 | if (new_pos == CTK_POS_BOTTOM) |
408 | ctk_widget_set_valign (w, CTK_ALIGN_START); |
409 | else if (new_pos == CTK_POS_TOP) |
410 | ctk_widget_set_valign (w, CTK_ALIGN_END); |
411 | else |
412 | ctk_widget_set_valign (w, CTK_ALIGN_CENTER); |
413 | } |
414 | |
415 | g_list_free (children); |
416 | } |
417 | |
418 | void |
419 | ctk_menu_section_box_new_toplevel (CtkStack *stack, |
420 | GMenuModel *model, |
421 | const gchar *action_namespace, |
422 | CtkPopover *popover) |
423 | { |
424 | CtkMenuSectionBox *box; |
425 | |
426 | box = g_object_new (CTK_TYPE_MENU_SECTION_BOX(ctk_menu_section_box_get_type ()), "margin", 10, NULL((void*)0)); |
427 | ctk_stack_add_named (stack, CTK_WIDGET (box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_widget_get_type ())))))), "main"); |
428 | |
429 | box->tracker = ctk_menu_tracker_new (CTK_ACTION_OBSERVABLE (_ctk_widget_get_action_muxer (CTK_WIDGET (box), TRUE))((((CtkActionObservable*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((_ctk_widget_get_action_muxer (((((CtkWidget *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((box )), ((ctk_widget_get_type ())))))), (!(0))))), ((ctk_action_observable_get_type ())))))), |
430 | model, TRUE(!(0)), FALSE(0), FALSE(0), action_namespace, |
431 | ctk_menu_section_box_insert_func, |
432 | ctk_menu_section_box_remove_func, box); |
433 | |
434 | g_signal_connect (G_OBJECT (popover), "notify::position", G_CALLBACK (update_popover_position_cb), box)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((popover)), (((GType) ((20) << (2)) ))))))), ("notify::position"), (((GCallback) (update_popover_position_cb ))), (box), ((void*)0), (GConnectFlags) 0); |
435 | |
436 | |
437 | ctk_widget_show (CTK_WIDGET (box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_widget_get_type ()))))))); |
438 | } |
439 | |
440 | static void |
441 | ctk_menu_section_box_new_submenu (CtkMenuTrackerItem *item, |
442 | CtkMenuSectionBox *toplevel, |
443 | CtkWidget *focus, |
444 | const gchar *name) |
445 | { |
446 | CtkMenuSectionBox *box; |
447 | CtkWidget *button; |
448 | |
449 | box = g_object_new (CTK_TYPE_MENU_SECTION_BOX(ctk_menu_section_box_get_type ()), "margin", 10, NULL((void*)0)); |
450 | |
451 | button = g_object_new (CTK_TYPE_MODEL_BUTTON(ctk_model_button_get_type ()), |
452 | "menu-name", name, |
453 | "inverted", TRUE(!(0)), |
454 | "centered", TRUE(!(0)), |
455 | NULL((void*)0)); |
456 | |
457 | g_object_bind_property (item, "label", button, "text", G_BINDING_SYNC_CREATE); |
458 | g_object_bind_property (item, "icon", button, "icon", G_BINDING_SYNC_CREATE); |
459 | |
460 | g_object_set_data (G_OBJECT (button)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), (((GType) ((20) << (2)))))))), "focus", focus); |
461 | g_object_set_data (G_OBJECT (focus)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((focus)), (((GType) ((20) << (2)))))))), "focus", button); |
462 | |
463 | ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), button, FALSE(0), FALSE(0), 0); |
464 | ctk_widget_show (button); |
465 | |
466 | g_signal_connect (focus, "clicked", G_CALLBACK (open_submenu), item)g_signal_connect_data ((focus), ("clicked"), (((GCallback) (open_submenu ))), (item), ((void*)0), (GConnectFlags) 0); |
467 | g_signal_connect (button, "clicked", G_CALLBACK (close_submenu), item)g_signal_connect_data ((button), ("clicked"), (((GCallback) ( close_submenu))), (item), ((void*)0), (GConnectFlags) 0); |
468 | |
469 | ctk_stack_add_named (CTK_STACK (ctk_widget_get_ancestor (CTK_WIDGET (toplevel), CTK_TYPE_STACK))((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_widget_get_ancestor (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((toplevel)), ((ctk_widget_get_type ())))) )), (ctk_stack_get_type ())))), ((ctk_stack_get_type ())))))), |
470 | CTK_WIDGET (box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_widget_get_type ())))))), ctk_menu_tracker_item_get_label (item)); |
471 | ctk_widget_show (CTK_WIDGET (box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_widget_get_type ()))))))); |
472 | |
473 | box->tracker = ctk_menu_tracker_new_for_item_link (item, G_MENU_LINK_SUBMENU"submenu", FALSE(0), FALSE(0), |
474 | ctk_menu_section_box_insert_func, |
475 | ctk_menu_section_box_remove_func, |
476 | box); |
477 | } |
478 | |
479 | static CtkWidget * |
480 | ctk_menu_section_box_new_section (CtkMenuTrackerItem *item, |
481 | CtkMenuSectionBox *parent) |
482 | { |
483 | CtkMenuSectionBox *box; |
484 | const gchar *label; |
485 | const gchar *hint; |
486 | const gchar *text_direction; |
487 | |
488 | box = g_object_new (CTK_TYPE_MENU_SECTION_BOX(ctk_menu_section_box_get_type ()), NULL((void*)0)); |
489 | box->toplevel = parent->toplevel; |
490 | box->depth = parent->depth + 1; |
491 | |
492 | label = ctk_menu_tracker_item_get_label (item); |
493 | hint = ctk_menu_tracker_item_get_display_hint (item); |
494 | text_direction = ctk_menu_tracker_item_get_text_direction (item); |
495 | |
496 | if (hint && g_str_equal (hint, "horizontal-buttons")(strcmp ((const char *) (hint), (const char *) ("horizontal-buttons" )) == 0)) |
497 | { |
498 | ctk_orientable_set_orientation (CTK_ORIENTABLE (box->item_box)((((CtkOrientable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_orientable_get_type ())))))), CTK_ORIENTATION_HORIZONTAL); |
499 | ctk_style_context_add_class (ctk_widget_get_style_context (CTK_WIDGET (box->item_box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_widget_get_type ()))))))), CTK_STYLE_CLASS_LINKED"linked"); |
500 | box->iconic = TRUE(!(0)); |
501 | |
502 | if (text_direction) |
503 | { |
504 | CtkTextDirection dir = CTK_TEXT_DIR_NONE; |
505 | |
506 | if (g_str_equal (text_direction, "rtl")(strcmp ((const char *) (text_direction), (const char *) ("rtl" )) == 0)) |
507 | dir = CTK_TEXT_DIR_RTL; |
508 | else if (g_str_equal (text_direction, "ltr")(strcmp ((const char *) (text_direction), (const char *) ("ltr" )) == 0)) |
509 | dir = CTK_TEXT_DIR_LTR; |
510 | |
511 | ctk_widget_set_direction (CTK_WIDGET (box->item_box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->item_box)), ((ctk_widget_get_type ())))))), dir); |
512 | } |
513 | } |
514 | |
515 | if (label != NULL((void*)0)) |
516 | { |
517 | CtkWidget *separator; |
518 | CtkWidget *title; |
519 | |
520 | box->separator = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 4); |
521 | g_object_ref_sink (box->separator)((__typeof__ (box->separator)) (g_object_ref_sink) (box-> separator)); |
522 | |
523 | separator = ctk_separator_new (CTK_ORIENTATION_HORIZONTAL); |
524 | ctk_widget_set_valign (separator, CTK_ALIGN_CENTER); |
525 | ctk_box_pack_start (CTK_BOX (box->separator)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->separator)), ((ctk_box_get_type ())))))), separator, TRUE(!(0)), TRUE(!(0)), 0); |
526 | |
527 | title = ctk_label_new (label); |
528 | g_object_bind_property (item, "label", title, "label", G_BINDING_SYNC_CREATE); |
529 | ctk_style_context_add_class (ctk_widget_get_style_context (title), CTK_STYLE_CLASS_SEPARATOR"separator"); |
530 | ctk_widget_set_halign (title, CTK_ALIGN_START); |
531 | ctk_box_pack_start (CTK_BOX (box->separator)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->separator)), ((ctk_box_get_type ())))))), title, FALSE(0), FALSE(0), 0); |
532 | |
533 | separator = ctk_separator_new (CTK_ORIENTATION_HORIZONTAL); |
534 | ctk_widget_set_valign (separator, CTK_ALIGN_CENTER); |
535 | ctk_box_pack_start (CTK_BOX (box->separator)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box->separator)), ((ctk_box_get_type ())))))), separator, TRUE(!(0)), TRUE(!(0)), 0); |
536 | |
537 | ctk_widget_show_all (box->separator); |
538 | } |
539 | else |
540 | { |
541 | box->separator = ctk_separator_new (CTK_ORIENTATION_HORIZONTAL); |
542 | g_object_ref_sink (box->separator)((__typeof__ (box->separator)) (g_object_ref_sink) (box-> separator)); |
543 | |
544 | ctk_widget_show (box->separator); |
545 | } |
546 | |
547 | box->tracker = ctk_menu_tracker_new_for_item_link (item, G_MENU_LINK_SECTION"section", FALSE(0), FALSE(0), |
548 | ctk_menu_section_box_insert_func, |
549 | ctk_menu_section_box_remove_func, |
550 | box); |
551 | |
552 | return CTK_WIDGET (box)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_widget_get_type ())))))); |
553 | } |