File: | ctk/ctkheaderbar.c |
Warning: | line 1052, column 51 Access of the memory returned by 'alloca' at index 0, while it holds only 0 'struct _CtkRequestedSize' element |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright (c) 2013 Red Hat, Inc. | |||
3 | * | |||
4 | * This program is free software; you can redistribute it and/or modify | |||
5 | * it under the terms of the GNU Lesser General Public License as published by | |||
6 | * the Free Software Foundation; either version 2 of the License, or (at your | |||
7 | * option) any later version. | |||
8 | * | |||
9 | * This program is distributed in the hope that it will be useful, but | |||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |||
11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||
12 | * License for more details. | |||
13 | * | |||
14 | * You should have received a copy of the GNU Lesser General Public License | |||
15 | * along with this program; if not, write to the Free Software Foundation, | |||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||
17 | * | |||
18 | */ | |||
19 | ||||
20 | #include "config.h" | |||
21 | ||||
22 | #include "ctkheaderbar.h" | |||
23 | #include "ctkheaderbarprivate.h" | |||
24 | #include "ctkintl.h" | |||
25 | #include "ctkprivate.h" | |||
26 | #include "ctktypebuiltins.h" | |||
27 | #include "ctkwidgetprivate.h" | |||
28 | #include "ctkcssnodeprivate.h" | |||
29 | #include "ctkcsscustomgadgetprivate.h" | |||
30 | #include "ctkwindowprivate.h" | |||
31 | #include "ctkwidgetprivate.h" | |||
32 | #include "ctkcontainerprivate.h" | |||
33 | #include "a11y/ctkheaderbaraccessible.h" | |||
34 | ||||
35 | #include <string.h> | |||
36 | ||||
37 | /** | |||
38 | * SECTION:ctkheaderbar | |||
39 | * @Short_description: A box with a centered child | |||
40 | * @Title: CtkHeaderBar | |||
41 | * @See_also: #CtkBox, #CtkActionBar | |||
42 | * | |||
43 | * CtkHeaderBar is similar to a horizontal #CtkBox. It allows children to | |||
44 | * be placed at the start or the end. In addition, it allows a title and | |||
45 | * subtitle to be displayed. The title will be centered with respect to | |||
46 | * the width of the box, even if the children at either side take up | |||
47 | * different amounts of space. The height of the titlebar will be | |||
48 | * set to provide sufficient space for the subtitle, even if none is | |||
49 | * currently set. If a subtitle is not needed, the space reservation | |||
50 | * can be turned off with ctk_header_bar_set_has_subtitle(). | |||
51 | * | |||
52 | * CtkHeaderBar can add typical window frame controls, such as minimize, | |||
53 | * maximize and close buttons, or the window icon. | |||
54 | * | |||
55 | * For these reasons, CtkHeaderBar is the natural choice for use as the custom | |||
56 | * titlebar widget of a #CtkWindow (see ctk_window_set_titlebar()), as it gives | |||
57 | * features typical of titlebars while allowing the addition of child widgets. | |||
58 | */ | |||
59 | ||||
60 | #define DEFAULT_SPACING6 6 | |||
61 | #define MIN_TITLE_CHARS5 5 | |||
62 | ||||
63 | struct _CtkHeaderBarPrivate | |||
64 | { | |||
65 | gchar *title; | |||
66 | gchar *subtitle; | |||
67 | CtkWidget *title_label; | |||
68 | CtkWidget *subtitle_label; | |||
69 | CtkWidget *label_box; | |||
70 | CtkWidget *label_sizing_box; | |||
71 | CtkWidget *subtitle_sizing_label; | |||
72 | CtkWidget *custom_title; | |||
73 | gint spacing; | |||
74 | gboolean has_subtitle; | |||
75 | ||||
76 | GList *children; | |||
77 | ||||
78 | gboolean shows_wm_decorations; | |||
79 | gchar *decoration_layout; | |||
80 | gboolean decoration_layout_set; | |||
81 | ||||
82 | CtkWidget *titlebar_start_box; | |||
83 | CtkWidget *titlebar_end_box; | |||
84 | ||||
85 | CtkWidget *titlebar_start_separator; | |||
86 | CtkWidget *titlebar_end_separator; | |||
87 | ||||
88 | CtkWidget *titlebar_icon; | |||
89 | ||||
90 | CtkCssGadget *gadget; | |||
91 | }; | |||
92 | ||||
93 | typedef struct _Child Child; | |||
94 | struct _Child | |||
95 | { | |||
96 | CtkWidget *widget; | |||
97 | CtkPackType pack_type; | |||
98 | }; | |||
99 | ||||
100 | enum { | |||
101 | PROP_0, | |||
102 | PROP_TITLE, | |||
103 | PROP_SUBTITLE, | |||
104 | PROP_HAS_SUBTITLE, | |||
105 | PROP_CUSTOM_TITLE, | |||
106 | PROP_SPACING, | |||
107 | PROP_SHOW_CLOSE_BUTTON, | |||
108 | PROP_DECORATION_LAYOUT, | |||
109 | PROP_DECORATION_LAYOUT_SET, | |||
110 | LAST_PROP | |||
111 | }; | |||
112 | ||||
113 | enum { | |||
114 | CHILD_PROP_0, | |||
115 | CHILD_PROP_PACK_TYPE, | |||
116 | CHILD_PROP_POSITION | |||
117 | }; | |||
118 | ||||
119 | static GParamSpec *header_bar_props[LAST_PROP] = { NULL((void*)0), }; | |||
120 | ||||
121 | static void ctk_header_bar_buildable_init (CtkBuildableIface *iface); | |||
122 | ||||
123 | G_DEFINE_TYPE_WITH_CODE (CtkHeaderBar, ctk_header_bar, CTK_TYPE_CONTAINER,static void ctk_header_bar_init (CtkHeaderBar *self); static void ctk_header_bar_class_init (CtkHeaderBarClass *klass); static GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class = ((void*)0); static gint CtkHeaderBar_private_offset; static void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class = g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset ); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_header_bar_get_instance_private (CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_bar_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_header_bar_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_header_bar_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar" ), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void )) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), ( GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags ) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type ()), &g_implement_interface_info); };} } return g_define_type_id ; } | |||
124 | G_ADD_PRIVATE (CtkHeaderBar)static void ctk_header_bar_init (CtkHeaderBar *self); static void ctk_header_bar_class_init (CtkHeaderBarClass *klass); static GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class = ((void*)0); static gint CtkHeaderBar_private_offset; static void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class = g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset ); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_header_bar_get_instance_private (CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_bar_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_header_bar_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_header_bar_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar" ), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void )) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), ( GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags ) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type ()), &g_implement_interface_info); };} } return g_define_type_id ; } | |||
125 | G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_header_bar_init (CtkHeaderBar *self); static void ctk_header_bar_class_init (CtkHeaderBarClass *klass); static GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class = ((void*)0); static gint CtkHeaderBar_private_offset; static void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class = g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset ); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_header_bar_get_instance_private (CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_bar_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_header_bar_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_header_bar_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar" ), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void )) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), ( GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags ) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type ()), &g_implement_interface_info); };} } return g_define_type_id ; } | |||
126 | ctk_header_bar_buildable_init))static void ctk_header_bar_init (CtkHeaderBar *self); static void ctk_header_bar_class_init (CtkHeaderBarClass *klass); static GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class = ((void*)0); static gint CtkHeaderBar_private_offset; static void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class = g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset ); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_header_bar_get_instance_private (CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_bar_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_header_bar_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_header_bar_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar" ), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void )) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), ( GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags ) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type ()), &g_implement_interface_info); };} } return g_define_type_id ; }; | |||
127 | ||||
128 | static void | |||
129 | init_sizing_box (CtkHeaderBar *bar) | |||
130 | { | |||
131 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
132 | CtkWidget *w; | |||
133 | CtkStyleContext *context; | |||
134 | ||||
135 | /* We use this box to always request size for the two labels (title | |||
136 | * and subtitle) as if they were always visible, but then allocate | |||
137 | * the real label box with its actual size, to keep it center-aligned | |||
138 | * in case we have only the title. | |||
139 | */ | |||
140 | w = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0); | |||
141 | ctk_widget_show (w); | |||
142 | priv->label_sizing_box = g_object_ref_sink (w)((__typeof__ (w)) (g_object_ref_sink) (w)); | |||
143 | ||||
144 | w = ctk_label_new (NULL((void*)0)); | |||
145 | ctk_widget_show (w); | |||
146 | context = ctk_widget_get_style_context (w); | |||
147 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_TITLE"title"); | |||
148 | ctk_box_pack_start (CTK_BOX (priv->label_sizing_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->label_sizing_box)), ((ctk_box_get_type ())))))), w, FALSE(0), FALSE(0), 0); | |||
149 | ctk_label_set_line_wrap (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), FALSE(0)); | |||
150 | ctk_label_set_single_line_mode (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), TRUE(!(0))); | |||
151 | ctk_label_set_ellipsize (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), PANGO_ELLIPSIZE_END); | |||
152 | ctk_label_set_width_chars (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), MIN_TITLE_CHARS5); | |||
153 | ||||
154 | w = ctk_label_new (NULL((void*)0)); | |||
155 | context = ctk_widget_get_style_context (w); | |||
156 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_SUBTITLE"subtitle"); | |||
157 | ctk_box_pack_start (CTK_BOX (priv->label_sizing_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->label_sizing_box)), ((ctk_box_get_type ())))))), w, FALSE(0), FALSE(0), 0); | |||
158 | ctk_label_set_line_wrap (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), FALSE(0)); | |||
159 | ctk_label_set_single_line_mode (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), TRUE(!(0))); | |||
160 | ctk_label_set_ellipsize (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((w)), ((ctk_label_get_type ())))))), PANGO_ELLIPSIZE_END); | |||
161 | ctk_widget_set_visible (w, priv->has_subtitle || (priv->subtitle && priv->subtitle[0])); | |||
162 | priv->subtitle_sizing_label = w; | |||
163 | } | |||
164 | ||||
165 | static CtkWidget * | |||
166 | create_title_box (const char *title, | |||
167 | const char *subtitle, | |||
168 | CtkWidget **ret_title_label, | |||
169 | CtkWidget **ret_subtitle_label) | |||
170 | { | |||
171 | CtkWidget *label_box; | |||
172 | CtkWidget *title_label; | |||
173 | CtkWidget *subtitle_label; | |||
174 | CtkStyleContext *context; | |||
175 | ||||
176 | label_box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0); | |||
177 | ctk_widget_set_valign (label_box, CTK_ALIGN_CENTER); | |||
178 | ctk_widget_show (label_box); | |||
179 | ||||
180 | title_label = ctk_label_new (title); | |||
181 | context = ctk_widget_get_style_context (title_label); | |||
182 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_TITLE"title"); | |||
183 | ctk_label_set_line_wrap (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((title_label)), ((ctk_label_get_type ())))))), FALSE(0)); | |||
184 | ctk_label_set_single_line_mode (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((title_label)), ((ctk_label_get_type ())))))), TRUE(!(0))); | |||
185 | ctk_label_set_ellipsize (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((title_label)), ((ctk_label_get_type ())))))), PANGO_ELLIPSIZE_END); | |||
186 | ctk_box_pack_start (CTK_BOX (label_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((label_box)), ((ctk_box_get_type ())))))), title_label, FALSE(0), FALSE(0), 0); | |||
187 | ctk_widget_show (title_label); | |||
188 | ctk_label_set_width_chars (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((title_label)), ((ctk_label_get_type ())))))), MIN_TITLE_CHARS5); | |||
189 | ||||
190 | subtitle_label = ctk_label_new (subtitle); | |||
191 | context = ctk_widget_get_style_context (subtitle_label); | |||
192 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_SUBTITLE"subtitle"); | |||
193 | ctk_label_set_line_wrap (CTK_LABEL (subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((subtitle_label)), ((ctk_label_get_type ())))))), FALSE(0)); | |||
194 | ctk_label_set_single_line_mode (CTK_LABEL (subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((subtitle_label)), ((ctk_label_get_type ())))))), TRUE(!(0))); | |||
195 | ctk_label_set_ellipsize (CTK_LABEL (subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((subtitle_label)), ((ctk_label_get_type ())))))), PANGO_ELLIPSIZE_END); | |||
196 | ctk_box_pack_start (CTK_BOX (label_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((label_box)), ((ctk_box_get_type ())))))), subtitle_label, FALSE(0), FALSE(0), 0); | |||
197 | ctk_widget_set_no_show_all (subtitle_label, TRUE(!(0))); | |||
198 | ctk_widget_set_visible (subtitle_label, subtitle && subtitle[0]); | |||
199 | ||||
200 | if (ret_title_label) | |||
201 | *ret_title_label = title_label; | |||
202 | if (ret_subtitle_label) | |||
203 | *ret_subtitle_label = subtitle_label; | |||
204 | ||||
205 | return label_box; | |||
206 | } | |||
207 | ||||
208 | gboolean | |||
209 | _ctk_header_bar_update_window_icon (CtkHeaderBar *bar, | |||
210 | CtkWindow *window) | |||
211 | { | |||
212 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
213 | GdkPixbuf *pixbuf; | |||
214 | gint scale; | |||
215 | ||||
216 | if (priv->titlebar_icon == NULL((void*)0)) | |||
217 | return FALSE(0); | |||
218 | ||||
219 | scale = ctk_widget_get_scale_factor (priv->titlebar_icon); | |||
220 | if (CTK_IS_BUTTON (ctk_widget_get_parent (priv->titlebar_icon))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (ctk_widget_get_parent (priv->titlebar_icon))); GType __t = ((ctk_button_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; }))))) | |||
221 | pixbuf = ctk_window_get_icon_for_size (window, scale * 16); | |||
222 | else | |||
223 | pixbuf = ctk_window_get_icon_for_size (window, scale * 20); | |||
224 | ||||
225 | if (pixbuf) | |||
226 | { | |||
227 | cairo_surface_t *surface; | |||
228 | ||||
229 | surface = cdk_cairo_surface_create_from_pixbuf (pixbuf, scale, ctk_widget_get_window (priv->titlebar_icon)); | |||
230 | ||||
231 | ctk_image_set_from_surface (CTK_IMAGE (priv->titlebar_icon)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->titlebar_icon)), ((ctk_image_get_type ())))))), surface); | |||
232 | cairo_surface_destroy (surface); | |||
233 | g_object_unref (pixbuf); | |||
234 | ctk_widget_show (priv->titlebar_icon); | |||
235 | ||||
236 | return TRUE(!(0)); | |||
237 | } | |||
238 | ||||
239 | return FALSE(0); | |||
240 | } | |||
241 | ||||
242 | static void | |||
243 | _ctk_header_bar_update_separator_visibility (CtkHeaderBar *bar) | |||
244 | { | |||
245 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
246 | gboolean have_visible_at_start = FALSE(0); | |||
247 | gboolean have_visible_at_end = FALSE(0); | |||
248 | GList *l; | |||
249 | ||||
250 | for (l = priv->children; l != NULL((void*)0); l = l->next) | |||
251 | { | |||
252 | Child *child = l->data; | |||
253 | ||||
254 | if (ctk_widget_get_visible (child->widget)) | |||
255 | { | |||
256 | if (child->pack_type == CTK_PACK_START) | |||
257 | have_visible_at_start = TRUE(!(0)); | |||
258 | else | |||
259 | have_visible_at_end = TRUE(!(0)); | |||
260 | } | |||
261 | } | |||
262 | ||||
263 | if (priv->titlebar_start_separator != NULL((void*)0)) | |||
264 | ctk_widget_set_visible (priv->titlebar_start_separator, have_visible_at_start); | |||
265 | ||||
266 | if (priv->titlebar_end_separator != NULL((void*)0)) | |||
267 | ctk_widget_set_visible (priv->titlebar_end_separator, have_visible_at_end); | |||
268 | } | |||
269 | ||||
270 | void | |||
271 | _ctk_header_bar_update_window_buttons (CtkHeaderBar *bar) | |||
272 | { | |||
273 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
274 | CtkWidget *widget = CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ())))))), *toplevel; | |||
275 | CtkWindow *window; | |||
276 | CtkTextDirection direction; | |||
277 | gchar *layout_desc; | |||
278 | gchar **tokens, **t; | |||
279 | gint i, j; | |||
280 | GMenuModel *menu; | |||
281 | gboolean shown_by_shell; | |||
282 | gboolean is_sovereign_window; | |||
283 | ||||
284 | toplevel = ctk_widget_get_toplevel (widget); | |||
285 | if (!ctk_widget_is_toplevel (toplevel)) | |||
286 | return; | |||
287 | ||||
288 | if (priv->titlebar_start_box) | |||
289 | { | |||
290 | ctk_widget_unparent (priv->titlebar_start_box); | |||
291 | priv->titlebar_start_box = NULL((void*)0); | |||
292 | priv->titlebar_start_separator = NULL((void*)0); | |||
293 | } | |||
294 | if (priv->titlebar_end_box) | |||
295 | { | |||
296 | ctk_widget_unparent (priv->titlebar_end_box); | |||
297 | priv->titlebar_end_box = NULL((void*)0); | |||
298 | priv->titlebar_end_separator = NULL((void*)0); | |||
299 | } | |||
300 | ||||
301 | priv->titlebar_icon = NULL((void*)0); | |||
302 | ||||
303 | if (!priv->shows_wm_decorations) | |||
304 | return; | |||
305 | ||||
306 | direction = ctk_widget_get_direction (widget); | |||
307 | ||||
308 | g_object_get (ctk_widget_get_settings (widget), | |||
309 | "ctk-shell-shows-app-menu", &shown_by_shell, | |||
310 | "ctk-decoration-layout", &layout_desc, | |||
311 | NULL((void*)0)); | |||
312 | ||||
313 | if (priv->decoration_layout_set) | |||
314 | { | |||
315 | g_free (layout_desc); | |||
316 | layout_desc = g_strdup (priv->decoration_layout)g_strdup_inline (priv->decoration_layout); | |||
317 | } | |||
318 | ||||
319 | window = CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ())))))); | |||
320 | ||||
321 | if (!shown_by_shell && ctk_window_get_application (window)) | |||
322 | menu = ctk_application_get_app_menu (ctk_window_get_application (window)); | |||
323 | else | |||
324 | menu = NULL((void*)0); | |||
325 | ||||
326 | is_sovereign_window = (!ctk_window_get_modal (window) && | |||
327 | ctk_window_get_transient_for (window) == NULL((void*)0) && | |||
328 | ctk_window_get_type_hint (window) == CDK_WINDOW_TYPE_HINT_NORMAL); | |||
329 | ||||
330 | tokens = g_strsplit (layout_desc, ":", 2); | |||
331 | if (tokens) | |||
332 | { | |||
333 | for (i = 0; i < 2; i++) | |||
334 | { | |||
335 | CtkWidget *box; | |||
336 | CtkWidget *separator; | |||
337 | int n_children = 0; | |||
338 | ||||
339 | if (tokens[i] == NULL((void*)0)) | |||
340 | break; | |||
341 | ||||
342 | t = g_strsplit (tokens[i], ",", -1); | |||
343 | ||||
344 | separator = ctk_separator_new (CTK_ORIENTATION_VERTICAL); | |||
345 | ctk_widget_set_no_show_all (separator, TRUE(!(0))); | |||
346 | ctk_style_context_add_class (ctk_widget_get_style_context (separator), "titlebutton"); | |||
347 | ||||
348 | box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, priv->spacing); | |||
349 | ||||
350 | for (j = 0; t[j]; j++) | |||
351 | { | |||
352 | CtkWidget *button = NULL((void*)0); | |||
353 | CtkWidget *image = NULL((void*)0); | |||
354 | AtkObject *accessible; | |||
355 | ||||
356 | if (strcmp (t[j], "icon") == 0 && | |||
357 | is_sovereign_window) | |||
358 | { | |||
359 | button = ctk_image_new (); | |||
360 | ctk_widget_set_valign (button, CTK_ALIGN_CENTER); | |||
361 | priv->titlebar_icon = button; | |||
362 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton"); | |||
363 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "icon"); | |||
364 | ctk_widget_set_size_request (button, 20, 20); | |||
365 | ctk_widget_show (button); | |||
366 | ||||
367 | if (!_ctk_header_bar_update_window_icon (bar, window)) | |||
368 | { | |||
369 | ctk_widget_destroy (button); | |||
370 | priv->titlebar_icon = NULL((void*)0); | |||
371 | button = NULL((void*)0); | |||
372 | } | |||
373 | } | |||
374 | else if (strcmp (t[j], "menu") == 0 && | |||
375 | menu != NULL((void*)0) && | |||
376 | is_sovereign_window) | |||
377 | { | |||
378 | button = ctk_menu_button_new (); | |||
379 | ctk_widget_set_valign (button, CTK_ALIGN_CENTER); | |||
380 | ctk_menu_button_set_menu_model (CTK_MENU_BUTTON (button)((((CtkMenuButton*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_menu_button_get_type ())))))), menu); | |||
381 | ctk_menu_button_set_use_popover (CTK_MENU_BUTTON (button)((((CtkMenuButton*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_menu_button_get_type ())))))), TRUE(!(0))); | |||
382 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton"); | |||
383 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "appmenu"); | |||
384 | image = ctk_image_new (); | |||
385 | ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_container_get_type ())))))), image); | |||
386 | ctk_widget_set_can_focus (button, FALSE(0)); | |||
387 | ctk_widget_show_all (button); | |||
388 | ||||
389 | accessible = ctk_widget_get_accessible (button); | |||
390 | if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (accessible)); GType __t = ((ctk_accessible_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; }))))) | |||
391 | atk_object_set_name (accessible, _("Application menu")((char *) g_dgettext ("ctk30", "Application menu"))); | |||
392 | ||||
393 | priv->titlebar_icon = image; | |||
394 | if (!_ctk_header_bar_update_window_icon (bar, window)) | |||
395 | ctk_image_set_from_icon_name (CTK_IMAGE (priv->titlebar_icon)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->titlebar_icon)), ((ctk_image_get_type ())))))), | |||
396 | "application-x-executable-symbolic", CTK_ICON_SIZE_MENU); | |||
397 | } | |||
398 | else if (strcmp (t[j], "minimize") == 0 && | |||
399 | is_sovereign_window) | |||
400 | { | |||
401 | button = ctk_button_new (); | |||
402 | ctk_widget_set_valign (button, CTK_ALIGN_CENTER); | |||
403 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton"); | |||
404 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "minimize"); | |||
405 | image = ctk_image_new_from_icon_name ("window-minimize-symbolic", CTK_ICON_SIZE_MENU); | |||
406 | g_object_set (image, "use-fallback", TRUE(!(0)), NULL((void*)0)); | |||
407 | ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_container_get_type ())))))), image); | |||
408 | ctk_widget_set_can_focus (button, FALSE(0)); | |||
409 | ctk_widget_show_all (button); | |||
410 | g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), (((GCallback) ( ctk_window_iconify))), (window), ((void*)0), G_CONNECT_SWAPPED ) | |||
411 | G_CALLBACK (ctk_window_iconify), window)g_signal_connect_data ((button), ("clicked"), (((GCallback) ( ctk_window_iconify))), (window), ((void*)0), G_CONNECT_SWAPPED ); | |||
412 | ||||
413 | accessible = ctk_widget_get_accessible (button); | |||
414 | if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (accessible)); GType __t = ((ctk_accessible_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; }))))) | |||
415 | atk_object_set_name (accessible, _("Minimize")((char *) g_dgettext ("ctk30", "Minimize"))); | |||
416 | } | |||
417 | else if (strcmp (t[j], "maximize") == 0 && | |||
418 | ctk_window_get_resizable (window) && | |||
419 | is_sovereign_window) | |||
420 | { | |||
421 | const gchar *icon_name; | |||
422 | gboolean maximized = ctk_window_is_maximized (window); | |||
423 | ||||
424 | icon_name = maximized ? "window-restore-symbolic" : "window-maximize-symbolic"; | |||
425 | button = ctk_button_new (); | |||
426 | ctk_widget_set_valign (button, CTK_ALIGN_CENTER); | |||
427 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton"); | |||
428 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "maximize"); | |||
429 | image = ctk_image_new_from_icon_name (icon_name, CTK_ICON_SIZE_MENU); | |||
430 | g_object_set (image, "use-fallback", TRUE(!(0)), NULL((void*)0)); | |||
431 | ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_container_get_type ())))))), image); | |||
432 | ctk_widget_set_can_focus (button, FALSE(0)); | |||
433 | ctk_widget_show_all (button); | |||
434 | g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), (((GCallback) ( _ctk_window_toggle_maximized))), (window), ((void*)0), G_CONNECT_SWAPPED ) | |||
435 | G_CALLBACK (_ctk_window_toggle_maximized), window)g_signal_connect_data ((button), ("clicked"), (((GCallback) ( _ctk_window_toggle_maximized))), (window), ((void*)0), G_CONNECT_SWAPPED ); | |||
436 | ||||
437 | accessible = ctk_widget_get_accessible (button); | |||
438 | if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (accessible)); GType __t = ((ctk_accessible_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; }))))) | |||
439 | atk_object_set_name (accessible, maximized ? _("Restore")((char *) g_dgettext ("ctk30", "Restore")) : _("Maximize")((char *) g_dgettext ("ctk30", "Maximize"))); | |||
440 | } | |||
441 | else if (strcmp (t[j], "close") == 0 && | |||
442 | ctk_window_get_deletable (window)) | |||
443 | { | |||
444 | button = ctk_button_new (); | |||
445 | ctk_widget_set_valign (button, CTK_ALIGN_CENTER); | |||
446 | image = ctk_image_new_from_icon_name ("window-close-symbolic", CTK_ICON_SIZE_MENU); | |||
447 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton"); | |||
448 | ctk_style_context_add_class (ctk_widget_get_style_context (button), "close"); | |||
449 | g_object_set (image, "use-fallback", TRUE(!(0)), NULL((void*)0)); | |||
450 | ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((button)), ((ctk_container_get_type ())))))), image); | |||
451 | ctk_widget_set_can_focus (button, FALSE(0)); | |||
452 | ctk_widget_show_all (button); | |||
453 | g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), (((GCallback) ( ctk_window_close))), (window), ((void*)0), G_CONNECT_SWAPPED) | |||
454 | G_CALLBACK (ctk_window_close), window)g_signal_connect_data ((button), ("clicked"), (((GCallback) ( ctk_window_close))), (window), ((void*)0), G_CONNECT_SWAPPED); | |||
455 | ||||
456 | accessible = ctk_widget_get_accessible (button); | |||
457 | if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (accessible)); GType __t = ((ctk_accessible_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; }))))) | |||
458 | atk_object_set_name (accessible, _("Close")((char *) g_dgettext ("ctk30", "Close"))); | |||
459 | } | |||
460 | ||||
461 | if (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 | n_children ++; | |||
465 | } | |||
466 | } | |||
467 | g_strfreev (t); | |||
468 | ||||
469 | if (n_children == 0) | |||
470 | { | |||
471 | g_object_ref_sink (box)((__typeof__ (box)) (g_object_ref_sink) (box)); | |||
472 | g_object_unref (box); | |||
473 | g_object_ref_sink (separator)((__typeof__ (separator)) (g_object_ref_sink) (separator)); | |||
474 | g_object_unref (separator); | |||
475 | continue; | |||
476 | } | |||
477 | ||||
478 | ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), separator, FALSE(0), FALSE(0), 0); | |||
479 | if (i == 1) | |||
480 | ctk_box_reorder_child (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), separator, 0); | |||
481 | ||||
482 | if ((direction == CTK_TEXT_DIR_LTR && i == 0) || | |||
483 | (direction == CTK_TEXT_DIR_RTL && i == 1)) | |||
484 | { | |||
485 | ctk_style_context_add_class (ctk_widget_get_style_context (box), CTK_STYLE_CLASS_LEFT"left"); | |||
486 | ctk_css_node_insert_after (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))), | |||
487 | ctk_widget_get_css_node (box), | |||
488 | NULL((void*)0)); | |||
489 | } | |||
490 | else | |||
491 | { | |||
492 | ctk_style_context_add_class (ctk_widget_get_style_context (box), CTK_STYLE_CLASS_RIGHT"right"); | |||
493 | ctk_css_node_insert_before (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))), | |||
494 | ctk_widget_get_css_node (box), | |||
495 | NULL((void*)0)); | |||
496 | } | |||
497 | ||||
498 | ctk_widget_show (box); | |||
499 | ctk_widget_set_parent (box, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
500 | ||||
501 | if (i == 0) | |||
502 | { | |||
503 | priv->titlebar_start_box = box; | |||
504 | priv->titlebar_start_separator = separator; | |||
505 | } | |||
506 | else | |||
507 | { | |||
508 | priv->titlebar_end_box = box; | |||
509 | priv->titlebar_end_separator = separator; | |||
510 | } | |||
511 | } | |||
512 | g_strfreev (tokens); | |||
513 | } | |||
514 | g_free (layout_desc); | |||
515 | ||||
516 | _ctk_header_bar_update_separator_visibility (bar); | |||
517 | } | |||
518 | ||||
519 | gboolean | |||
520 | _ctk_header_bar_shows_app_menu (CtkHeaderBar *bar) | |||
521 | { | |||
522 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
523 | CtkWindow *window; | |||
524 | gchar *layout_desc; | |||
525 | gboolean ret; | |||
526 | ||||
527 | window = CTK_WINDOW (ctk_widget_get_toplevel (CTK_WIDGET (bar)))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_widget_get_toplevel (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((bar)), ((ctk_widget_get_type ()))))))))) , ((ctk_window_get_type ())))))); | |||
528 | ctk_widget_style_get (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((window)), ((ctk_widget_get_type ())))))), | |||
529 | "decoration-button-layout", &layout_desc, | |||
530 | NULL((void*)0)); | |||
531 | ||||
532 | ret = priv->shows_wm_decorations && | |||
533 | (layout_desc && strstr (layout_desc, "menu")); | |||
534 | ||||
535 | g_free (layout_desc); | |||
536 | ||||
537 | return ret; | |||
538 | } | |||
539 | ||||
540 | /* As an intended side effect, this function allows @child | |||
541 | * to be the title/label box */ | |||
542 | static void | |||
543 | ctk_header_bar_reorder_css_node (CtkHeaderBar *bar, | |||
544 | CtkPackType pack_type, | |||
545 | CtkWidget *widget) | |||
546 | { | |||
547 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
548 | CtkWidget *previous_widget; | |||
549 | GList *l; | |||
550 | ||||
551 | if (pack_type == CTK_PACK_START) | |||
552 | previous_widget = priv->titlebar_start_box; | |||
553 | else | |||
554 | previous_widget = priv->titlebar_end_box; | |||
555 | ||||
556 | for (l = priv->children; l; l = l->next) | |||
557 | { | |||
558 | Child *iter = l->data; | |||
559 | ||||
560 | if (iter->widget == widget) | |||
561 | break; | |||
562 | ||||
563 | if (iter->pack_type == pack_type) | |||
564 | previous_widget = iter->widget; | |||
565 | } | |||
566 | ||||
567 | if ((pack_type == CTK_PACK_START) | |||
568 | ^ (ctk_widget_get_direction (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_LTR)) | |||
569 | ctk_css_node_insert_after (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))), | |||
570 | ctk_widget_get_css_node (widget), | |||
571 | previous_widget ? ctk_widget_get_css_node (previous_widget) : NULL((void*)0)); | |||
572 | else | |||
573 | ctk_css_node_insert_before (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))), | |||
574 | ctk_widget_get_css_node (widget), | |||
575 | previous_widget ? ctk_widget_get_css_node (previous_widget) : NULL((void*)0)); | |||
576 | } | |||
577 | ||||
578 | static void | |||
579 | construct_label_box (CtkHeaderBar *bar) | |||
580 | { | |||
581 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
582 | ||||
583 | g_assert (priv->label_box == NULL)do { if (priv->label_box == ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkheaderbar.c", 583, ((const char*) (__func__)), "priv->label_box == NULL" ); } while (0); | |||
584 | ||||
585 | priv->label_box = create_title_box (priv->title, | |||
586 | priv->subtitle, | |||
587 | &priv->title_label, | |||
588 | &priv->subtitle_label); | |||
589 | ctk_header_bar_reorder_css_node (bar, CTK_PACK_START, priv->label_box); | |||
590 | ctk_widget_set_parent (priv->label_box, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
591 | } | |||
592 | ||||
593 | static gint | |||
594 | count_visible_children (CtkHeaderBar *bar) | |||
595 | { | |||
596 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
597 | GList *l; | |||
598 | Child *child; | |||
599 | gint n; | |||
600 | ||||
601 | n = 0; | |||
602 | for (l = priv->children; l; l = l->next) | |||
603 | { | |||
604 | child = l->data; | |||
605 | if (ctk_widget_get_visible (child->widget)) | |||
606 | n++; | |||
607 | } | |||
608 | ||||
609 | return n; | |||
610 | } | |||
611 | ||||
612 | static gboolean | |||
613 | add_child_size (CtkWidget *child, | |||
614 | CtkOrientation orientation, | |||
615 | gint *minimum, | |||
616 | gint *natural) | |||
617 | { | |||
618 | gint child_minimum, child_natural; | |||
619 | ||||
620 | if (!ctk_widget_get_visible (child)) | |||
621 | return FALSE(0); | |||
622 | ||||
623 | if (orientation == CTK_ORIENTATION_HORIZONTAL) | |||
624 | ctk_widget_get_preferred_width (child, &child_minimum, &child_natural); | |||
625 | else | |||
626 | ctk_widget_get_preferred_height (child, &child_minimum, &child_natural); | |||
627 | ||||
628 | if (CTK_ORIENTATION_HORIZONTAL == orientation) | |||
629 | { | |||
630 | *minimum += child_minimum; | |||
631 | *natural += child_natural; | |||
632 | } | |||
633 | else | |||
634 | { | |||
635 | *minimum = MAX (*minimum, child_minimum)(((*minimum) > (child_minimum)) ? (*minimum) : (child_minimum )); | |||
636 | *natural = MAX (*natural, child_natural)(((*natural) > (child_natural)) ? (*natural) : (child_natural )); | |||
637 | } | |||
638 | ||||
639 | return TRUE(!(0)); | |||
640 | } | |||
641 | ||||
642 | static void | |||
643 | ctk_header_bar_get_size (CtkWidget *widget, | |||
644 | CtkOrientation orientation, | |||
645 | gint *minimum_size, | |||
646 | gint *natural_size) | |||
647 | { | |||
648 | CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ())))))); | |||
649 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
650 | GList *l; | |||
651 | gint nvis_children; | |||
652 | gint minimum, natural; | |||
653 | gint center_min, center_nat; | |||
654 | ||||
655 | minimum = natural = 0; | |||
656 | nvis_children = 0; | |||
657 | ||||
658 | for (l = priv->children; l; l = l->next) | |||
659 | { | |||
660 | Child *child = l->data; | |||
661 | ||||
662 | if (add_child_size (child->widget, orientation, &minimum, &natural)) | |||
663 | nvis_children += 1; | |||
664 | } | |||
665 | ||||
666 | center_min = center_nat = 0; | |||
667 | if (priv->label_box != NULL((void*)0)) | |||
668 | { | |||
669 | if (orientation == CTK_ORIENTATION_HORIZONTAL) | |||
670 | add_child_size (priv->label_box, orientation, ¢er_min, ¢er_nat); | |||
671 | else | |||
672 | add_child_size (priv->label_sizing_box, orientation, ¢er_min, ¢er_nat); | |||
673 | ||||
674 | if (_ctk_widget_get_visible (priv->label_sizing_box)) | |||
675 | nvis_children += 1; | |||
676 | } | |||
677 | ||||
678 | if (priv->custom_title != NULL((void*)0)) | |||
679 | { | |||
680 | if (add_child_size (priv->custom_title, orientation, ¢er_min, ¢er_nat)) | |||
681 | nvis_children += 1; | |||
682 | } | |||
683 | ||||
684 | if (priv->titlebar_start_box != NULL((void*)0)) | |||
685 | { | |||
686 | if (add_child_size (priv->titlebar_start_box, orientation, &minimum, &natural)) | |||
687 | nvis_children += 1; | |||
688 | } | |||
689 | ||||
690 | if (priv->titlebar_end_box != NULL((void*)0)) | |||
691 | { | |||
692 | if (add_child_size (priv->titlebar_end_box, orientation, &minimum, &natural)) | |||
693 | nvis_children += 1; | |||
694 | } | |||
695 | ||||
696 | if (orientation == CTK_ORIENTATION_HORIZONTAL) | |||
697 | { | |||
698 | minimum += center_min; | |||
699 | natural += center_nat; | |||
700 | } | |||
701 | else | |||
702 | { | |||
703 | minimum = MAX (minimum, center_min)(((minimum) > (center_min)) ? (minimum) : (center_min)); | |||
704 | natural = MAX (natural, center_nat)(((natural) > (center_nat)) ? (natural) : (center_nat)); | |||
705 | } | |||
706 | ||||
707 | if (nvis_children > 0 && orientation == CTK_ORIENTATION_HORIZONTAL) | |||
708 | { | |||
709 | minimum += nvis_children * priv->spacing; | |||
710 | natural += nvis_children * priv->spacing; | |||
711 | } | |||
712 | ||||
713 | *minimum_size = minimum; | |||
714 | *natural_size = natural; | |||
715 | } | |||
716 | ||||
717 | static void | |||
718 | ctk_header_bar_compute_size_for_orientation (CtkWidget *widget, | |||
719 | gint avail_size, | |||
720 | gint *minimum_size, | |||
721 | gint *natural_size) | |||
722 | { | |||
723 | CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ())))))); | |||
724 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
725 | GList *children; | |||
726 | gint required_size = 0; | |||
727 | gint required_natural = 0; | |||
728 | gint child_size; | |||
729 | gint child_natural; | |||
730 | gint nvis_children; | |||
731 | ||||
732 | nvis_children = 0; | |||
733 | ||||
734 | for (children = priv->children; children != NULL((void*)0); children = children->next) | |||
735 | { | |||
736 | Child *child = children->data; | |||
737 | ||||
738 | if (ctk_widget_get_visible (child->widget)) | |||
739 | { | |||
740 | ctk_widget_get_preferred_width_for_height (child->widget, | |||
741 | avail_size, &child_size, &child_natural); | |||
742 | ||||
743 | required_size += child_size; | |||
744 | required_natural += child_natural; | |||
745 | ||||
746 | nvis_children += 1; | |||
747 | } | |||
748 | } | |||
749 | ||||
750 | if (priv->label_box != NULL((void*)0)) | |||
751 | { | |||
752 | ctk_widget_get_preferred_width (priv->label_sizing_box, | |||
753 | &child_size, &child_natural); | |||
754 | required_size += child_size; | |||
755 | required_natural += child_natural; | |||
756 | } | |||
757 | ||||
758 | if (priv->custom_title != NULL((void*)0) && | |||
759 | ctk_widget_get_visible (priv->custom_title)) | |||
760 | { | |||
761 | ctk_widget_get_preferred_width (priv->custom_title, | |||
762 | &child_size, &child_natural); | |||
763 | required_size += child_size; | |||
764 | required_natural += child_natural; | |||
765 | } | |||
766 | ||||
767 | if (priv->titlebar_start_box != NULL((void*)0)) | |||
768 | { | |||
769 | ctk_widget_get_preferred_width (priv->titlebar_start_box, | |||
770 | &child_size, &child_natural); | |||
771 | required_size += child_size; | |||
772 | required_natural += child_natural; | |||
773 | nvis_children += 1; | |||
774 | } | |||
775 | ||||
776 | if (priv->titlebar_end_box != NULL((void*)0)) | |||
777 | { | |||
778 | ctk_widget_get_preferred_width (priv->titlebar_end_box, | |||
779 | &child_size, &child_natural); | |||
780 | required_size += child_size; | |||
781 | required_natural += child_natural; | |||
782 | nvis_children += 1; | |||
783 | } | |||
784 | ||||
785 | if (nvis_children > 0) | |||
786 | { | |||
787 | required_size += nvis_children * priv->spacing; | |||
788 | required_natural += nvis_children * priv->spacing; | |||
789 | } | |||
790 | ||||
791 | *minimum_size = required_size; | |||
792 | *natural_size = required_natural; | |||
793 | } | |||
794 | ||||
795 | static void | |||
796 | ctk_header_bar_compute_size_for_opposing_orientation (CtkWidget *widget, | |||
797 | gint avail_size, | |||
798 | gint *minimum_size, | |||
799 | gint *natural_size) | |||
800 | { | |||
801 | CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ())))))); | |||
802 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
803 | Child *child; | |||
804 | GList *children; | |||
805 | gint nvis_children; | |||
806 | gint computed_minimum = 0; | |||
807 | gint computed_natural = 0; | |||
808 | CtkRequestedSize *sizes; | |||
809 | CtkPackType packing; | |||
810 | gint size = 0; | |||
811 | gint i; | |||
812 | gint child_size; | |||
813 | gint child_minimum; | |||
814 | gint child_natural; | |||
815 | gint center_min, center_nat; | |||
816 | ||||
817 | nvis_children = count_visible_children (bar); | |||
818 | ||||
819 | if (nvis_children <= 0) | |||
820 | return; | |||
821 | ||||
822 | sizes = g_newa (CtkRequestedSize, nvis_children)((CtkRequestedSize*) __builtin_alloca (sizeof (CtkRequestedSize ) * (gsize) (nvis_children))); | |||
823 | ||||
824 | /* Retrieve desired size for visible children */ | |||
825 | for (i = 0, children = priv->children; children; children = children->next) | |||
826 | { | |||
827 | child = children->data; | |||
828 | ||||
829 | if (ctk_widget_get_visible (child->widget)) | |||
830 | { | |||
831 | ctk_widget_get_preferred_width (child->widget, | |||
832 | &sizes[i].minimum_size, | |||
833 | &sizes[i].natural_size); | |||
834 | ||||
835 | size -= sizes[i].minimum_size; | |||
836 | sizes[i].data = child; | |||
837 | i += 1; | |||
838 | } | |||
839 | } | |||
840 | ||||
841 | /* Bring children up to size first */ | |||
842 | size = ctk_distribute_natural_allocation (MAX (0, avail_size)(((0) > (avail_size)) ? (0) : (avail_size)), nvis_children, sizes); | |||
843 | ||||
844 | /* Allocate child positions. */ | |||
845 | for (packing = CTK_PACK_START; packing <= CTK_PACK_END; ++packing) | |||
846 | { | |||
847 | for (i = 0, children = priv->children; children; children = children->next) | |||
848 | { | |||
849 | child = children->data; | |||
850 | ||||
851 | /* If widget is not visible, skip it. */ | |||
852 | if (!ctk_widget_get_visible (child->widget)) | |||
853 | continue; | |||
854 | ||||
855 | /* If widget is packed differently skip it, but still increment i, | |||
856 | * since widget is visible and will be handled in next loop | |||
857 | * iteration. | |||
858 | */ | |||
859 | if (child->pack_type != packing) | |||
860 | { | |||
861 | i++; | |||
862 | continue; | |||
863 | } | |||
864 | ||||
865 | child_size = sizes[i].minimum_size; | |||
866 | ||||
867 | ctk_widget_get_preferred_height_for_width (child->widget, | |||
868 | child_size, &child_minimum, &child_natural); | |||
869 | ||||
870 | computed_minimum = MAX (computed_minimum, child_minimum)(((computed_minimum) > (child_minimum)) ? (computed_minimum ) : (child_minimum)); | |||
871 | computed_natural = MAX (computed_natural, child_natural)(((computed_natural) > (child_natural)) ? (computed_natural ) : (child_natural)); | |||
872 | } | |||
873 | i += 1; | |||
874 | } | |||
875 | ||||
876 | center_min = center_nat = 0; | |||
877 | if (priv->label_box != NULL((void*)0)) | |||
878 | { | |||
879 | ctk_widget_get_preferred_height (priv->label_sizing_box, | |||
880 | ¢er_min, ¢er_nat); | |||
881 | } | |||
882 | ||||
883 | if (priv->custom_title != NULL((void*)0) && | |||
884 | ctk_widget_get_visible (priv->custom_title)) | |||
885 | { | |||
886 | ctk_widget_get_preferred_height (priv->custom_title, | |||
887 | ¢er_min, ¢er_nat); | |||
888 | } | |||
889 | ||||
890 | if (priv->titlebar_start_box != NULL((void*)0)) | |||
891 | { | |||
892 | ctk_widget_get_preferred_height (priv->titlebar_start_box, | |||
893 | &child_minimum, &child_natural); | |||
894 | computed_minimum = MAX (computed_minimum, child_minimum)(((computed_minimum) > (child_minimum)) ? (computed_minimum ) : (child_minimum)); | |||
895 | computed_natural = MAX (computed_natural, child_natural)(((computed_natural) > (child_natural)) ? (computed_natural ) : (child_natural)); | |||
896 | } | |||
897 | ||||
898 | if (priv->titlebar_end_box != NULL((void*)0)) | |||
899 | { | |||
900 | ctk_widget_get_preferred_height (priv->titlebar_end_box, | |||
901 | &child_minimum, &child_natural); | |||
902 | computed_minimum = MAX (computed_minimum, child_minimum)(((computed_minimum) > (child_minimum)) ? (computed_minimum ) : (child_minimum)); | |||
903 | computed_natural = MAX (computed_natural, child_natural)(((computed_natural) > (child_natural)) ? (computed_natural ) : (child_natural)); | |||
904 | } | |||
905 | ||||
906 | *minimum_size = computed_minimum; | |||
907 | *natural_size = computed_natural; | |||
908 | } | |||
909 | ||||
910 | static void | |||
911 | ctk_header_bar_get_content_size (CtkCssGadget *gadget, | |||
912 | CtkOrientation orientation, | |||
913 | gint for_size, | |||
914 | gint *minimum, | |||
915 | gint *natural, | |||
916 | gint *minimum_baseline G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
917 | gint *natural_baseline G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
918 | gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
919 | { | |||
920 | CtkWidget *widget = ctk_css_gadget_get_owner (gadget); | |||
921 | ||||
922 | if (for_size < 0) | |||
923 | ctk_header_bar_get_size (widget, orientation, minimum, natural); | |||
924 | else if (orientation == CTK_ORIENTATION_HORIZONTAL) | |||
925 | ctk_header_bar_compute_size_for_orientation (widget, for_size, minimum, natural); | |||
926 | else | |||
927 | ctk_header_bar_compute_size_for_opposing_orientation (widget, for_size, minimum, natural); | |||
928 | } | |||
929 | ||||
930 | static void | |||
931 | ctk_header_bar_get_preferred_width (CtkWidget *widget, | |||
932 | gint *minimum, | |||
933 | gint *natural) | |||
934 | { | |||
935 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
936 | ||||
937 | ctk_css_gadget_get_preferred_size (priv->gadget, | |||
938 | CTK_ORIENTATION_HORIZONTAL, | |||
939 | -1, | |||
940 | minimum, natural, | |||
941 | NULL((void*)0), NULL((void*)0)); | |||
942 | } | |||
943 | ||||
944 | static void | |||
945 | ctk_header_bar_get_preferred_height (CtkWidget *widget, | |||
946 | gint *minimum, | |||
947 | gint *natural) | |||
948 | { | |||
949 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
950 | ||||
951 | ctk_css_gadget_get_preferred_size (priv->gadget, | |||
952 | CTK_ORIENTATION_VERTICAL, | |||
953 | -1, | |||
954 | minimum, natural, | |||
955 | NULL((void*)0), NULL((void*)0)); | |||
956 | } | |||
957 | ||||
958 | static void | |||
959 | ctk_header_bar_get_preferred_width_for_height (CtkWidget *widget, | |||
960 | gint height, | |||
961 | gint *minimum, | |||
962 | gint *natural) | |||
963 | { | |||
964 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
965 | ||||
966 | ctk_css_gadget_get_preferred_size (priv->gadget, | |||
967 | CTK_ORIENTATION_HORIZONTAL, | |||
968 | height, | |||
969 | minimum, natural, | |||
970 | NULL((void*)0), NULL((void*)0)); | |||
971 | } | |||
972 | ||||
973 | static void | |||
974 | ctk_header_bar_get_preferred_height_for_width (CtkWidget *widget, | |||
975 | gint width, | |||
976 | gint *minimum, | |||
977 | gint *natural) | |||
978 | { | |||
979 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
980 | ||||
981 | ctk_css_gadget_get_preferred_size (priv->gadget, | |||
982 | CTK_ORIENTATION_VERTICAL, | |||
983 | width, | |||
984 | minimum, natural, | |||
985 | NULL((void*)0), NULL((void*)0)); | |||
986 | } | |||
987 | ||||
988 | static void | |||
989 | ctk_header_bar_size_allocate (CtkWidget *widget, | |||
990 | CtkAllocation *allocation) | |||
991 | { | |||
992 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
993 | CtkAllocation clip; | |||
994 | ||||
995 | ctk_widget_set_allocation (widget, allocation); | |||
996 | ||||
997 | ctk_css_gadget_allocate (priv->gadget, allocation, ctk_widget_get_allocated_baseline (widget), &clip); | |||
998 | ||||
999 | ctk_widget_set_clip (widget, &clip); | |||
1000 | } | |||
1001 | ||||
1002 | static void | |||
1003 | ctk_header_bar_allocate_contents (CtkCssGadget *gadget, | |||
1004 | const CtkAllocation *allocation, | |||
1005 | int baseline G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1006 | CtkAllocation *out_clip, | |||
1007 | gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
1008 | { | |||
1009 | CtkWidget *widget = ctk_css_gadget_get_owner (gadget); | |||
1010 | CtkWidget *title_widget; | |||
1011 | CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ())))))); | |||
1012 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1013 | CtkRequestedSize *sizes; | |||
1014 | gint width, height; | |||
1015 | gint nvis_children; | |||
1016 | gint title_minimum_size; | |||
1017 | gint title_natural_size; | |||
1018 | gboolean title_expands = FALSE(0); | |||
1019 | gint start_width, end_width; | |||
1020 | gint uniform_expand_bonus[2] = { 0 }; | |||
1021 | gint leftover_expand_bonus[2] = { 0 }; | |||
1022 | gint nexpand_children[2] = { 0 }; | |||
1023 | gint side[2]; | |||
1024 | GList *l; | |||
1025 | gint i; | |||
1026 | Child *child; | |||
1027 | CtkPackType packing; | |||
1028 | CtkAllocation child_allocation; | |||
1029 | gint x; | |||
1030 | gint child_size; | |||
1031 | CtkTextDirection direction; | |||
1032 | ||||
1033 | direction = ctk_widget_get_direction (widget); | |||
1034 | nvis_children = count_visible_children (bar); | |||
1035 | sizes = g_newa (CtkRequestedSize, nvis_children)((CtkRequestedSize*) __builtin_alloca (sizeof (CtkRequestedSize ) * (gsize) (nvis_children))); | |||
1036 | ||||
1037 | width = allocation->width - nvis_children * priv->spacing; | |||
1038 | height = allocation->height; | |||
1039 | ||||
1040 | i = 0; | |||
1041 | for (l = priv->children; l; l = l->next) | |||
| ||||
1042 | { | |||
1043 | child = l->data; | |||
1044 | if (!ctk_widget_get_visible (child->widget)) | |||
1045 | continue; | |||
1046 | ||||
1047 | if (ctk_widget_compute_expand (child->widget, CTK_ORIENTATION_HORIZONTAL)) | |||
1048 | nexpand_children[child->pack_type]++; | |||
1049 | ||||
1050 | ctk_widget_get_preferred_width_for_height (child->widget, | |||
1051 | height, | |||
1052 | &sizes[i].minimum_size, | |||
| ||||
1053 | &sizes[i].natural_size); | |||
1054 | width -= sizes[i].minimum_size; | |||
1055 | i++; | |||
1056 | } | |||
1057 | ||||
1058 | title_minimum_size = 0; | |||
1059 | title_natural_size = 0; | |||
1060 | ||||
1061 | if (priv->custom_title != NULL((void*)0) && | |||
1062 | ctk_widget_get_visible (priv->custom_title)) | |||
1063 | title_widget = priv->custom_title; | |||
1064 | else if (priv->label_box != NULL((void*)0)) | |||
1065 | title_widget = priv->label_box; | |||
1066 | else | |||
1067 | title_widget = NULL((void*)0); | |||
1068 | ||||
1069 | if (title_widget) | |||
1070 | { | |||
1071 | ctk_widget_get_preferred_width_for_height (title_widget, | |||
1072 | height, | |||
1073 | &title_minimum_size, | |||
1074 | &title_natural_size); | |||
1075 | width -= title_natural_size; | |||
1076 | ||||
1077 | title_expands = ctk_widget_compute_expand (title_widget, CTK_ORIENTATION_HORIZONTAL); | |||
1078 | } | |||
1079 | ||||
1080 | start_width = 0; | |||
1081 | if (priv->titlebar_start_box != NULL((void*)0)) | |||
1082 | { | |||
1083 | gint min, nat; | |||
1084 | ctk_widget_get_preferred_width_for_height (priv->titlebar_start_box, | |||
1085 | height, | |||
1086 | &min, &nat); | |||
1087 | start_width = nat + priv->spacing; | |||
1088 | } | |||
1089 | width -= start_width; | |||
1090 | ||||
1091 | end_width = 0; | |||
1092 | if (priv->titlebar_end_box != NULL((void*)0)) | |||
1093 | { | |||
1094 | gint min, nat; | |||
1095 | ctk_widget_get_preferred_width_for_height (priv->titlebar_end_box, | |||
1096 | height, | |||
1097 | &min, &nat); | |||
1098 | end_width = nat + priv->spacing; | |||
1099 | } | |||
1100 | width -= end_width; | |||
1101 | ||||
1102 | width = ctk_distribute_natural_allocation (MAX (0, width)(((0) > (width)) ? (0) : (width)), nvis_children, sizes); | |||
1103 | ||||
1104 | /* compute the nominal size of the children filling up each side of | |||
1105 | * the title in titlebar | |||
1106 | */ | |||
1107 | side[0] = start_width; | |||
1108 | side[1] = end_width; | |||
1109 | for (packing = CTK_PACK_START; packing <= CTK_PACK_END; packing++) | |||
1110 | { | |||
1111 | i = 0; | |||
1112 | for (l = priv->children; l != NULL((void*)0); l = l->next) | |||
1113 | { | |||
1114 | child = l->data; | |||
1115 | if (!ctk_widget_get_visible (child->widget)) | |||
1116 | continue; | |||
1117 | ||||
1118 | if (child->pack_type == packing) | |||
1119 | side[packing] += sizes[i].minimum_size + priv->spacing; | |||
1120 | ||||
1121 | i++; | |||
1122 | } | |||
1123 | } | |||
1124 | ||||
1125 | /* figure out how much space is left on each side of the title, | |||
1126 | * and earkmark that space for the expanded children. | |||
1127 | * | |||
1128 | * If the title itself is expanded, then it gets half the spoils | |||
1129 | * from each side. | |||
1130 | */ | |||
1131 | for (packing = CTK_PACK_START; packing <= CTK_PACK_END; packing++) | |||
1132 | { | |||
1133 | gint side_free_space; | |||
1134 | ||||
1135 | side_free_space = allocation->width / 2 - title_natural_size / 2 - side[packing]; | |||
1136 | ||||
1137 | if (side_free_space > 0 && nexpand_children[packing] > 0) | |||
1138 | { | |||
1139 | width -= side_free_space; | |||
1140 | ||||
1141 | if (title_expands) | |||
1142 | side_free_space -= side_free_space / 2; | |||
1143 | ||||
1144 | side[packing] += side_free_space; | |||
1145 | uniform_expand_bonus[packing] = side_free_space / nexpand_children[packing]; | |||
1146 | leftover_expand_bonus[packing] = side_free_space % nexpand_children[packing]; | |||
1147 | } | |||
1148 | } | |||
1149 | ||||
1150 | /* allocate the children on both sides of the title */ | |||
1151 | for (packing = CTK_PACK_START; packing <= CTK_PACK_END; packing++) | |||
1152 | { | |||
1153 | child_allocation.y = allocation->y; | |||
1154 | child_allocation.height = height; | |||
1155 | if (packing == CTK_PACK_START) | |||
1156 | x = allocation->x + start_width; | |||
1157 | else | |||
1158 | x = allocation->x + allocation->width - end_width; | |||
1159 | ||||
1160 | i = 0; | |||
1161 | for (l = priv->children; l != NULL((void*)0); l = l->next) | |||
1162 | { | |||
1163 | child = l->data; | |||
1164 | if (!ctk_widget_get_visible (child->widget)) | |||
1165 | continue; | |||
1166 | ||||
1167 | if (child->pack_type != packing) | |||
1168 | goto next; | |||
1169 | ||||
1170 | child_size = sizes[i].minimum_size; | |||
1171 | ||||
1172 | /* if this child is expanded, give it extra space from the reserves */ | |||
1173 | if (ctk_widget_compute_expand (child->widget, CTK_ORIENTATION_HORIZONTAL)) | |||
1174 | { | |||
1175 | gint expand_bonus; | |||
1176 | ||||
1177 | expand_bonus = uniform_expand_bonus[packing]; | |||
1178 | ||||
1179 | if (leftover_expand_bonus[packing] > 0) | |||
1180 | { | |||
1181 | expand_bonus++; | |||
1182 | leftover_expand_bonus[packing]--; | |||
1183 | } | |||
1184 | ||||
1185 | child_size += expand_bonus; | |||
1186 | } | |||
1187 | ||||
1188 | child_allocation.width = child_size; | |||
1189 | ||||
1190 | if (packing == CTK_PACK_START) | |||
1191 | { | |||
1192 | child_allocation.x = x; | |||
1193 | x += child_size; | |||
1194 | x += priv->spacing; | |||
1195 | } | |||
1196 | else | |||
1197 | { | |||
1198 | x -= child_size; | |||
1199 | child_allocation.x = x; | |||
1200 | x -= priv->spacing; | |||
1201 | } | |||
1202 | ||||
1203 | if (direction == CTK_TEXT_DIR_RTL) | |||
1204 | child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; | |||
1205 | ||||
1206 | ctk_widget_size_allocate (child->widget, &child_allocation); | |||
1207 | ||||
1208 | next: | |||
1209 | i++; | |||
1210 | } | |||
1211 | } | |||
1212 | ||||
1213 | /* We don't enforce css borders on the center widget, to make | |||
1214 | * title/subtitle combinations fit without growing the header | |||
1215 | */ | |||
1216 | child_allocation.y = allocation->y; | |||
1217 | child_allocation.height = allocation->height; | |||
1218 | ||||
1219 | child_size = MIN (allocation->width - side[0] - side[1], title_natural_size)(((allocation->width - side[0] - side[1]) < (title_natural_size )) ? (allocation->width - side[0] - side[1]) : (title_natural_size )); | |||
1220 | ||||
1221 | child_allocation.x = allocation->x + (allocation->width - child_size) / 2; | |||
1222 | child_allocation.width = child_size; | |||
1223 | ||||
1224 | /* if the title widget is expanded, then grow it by all the available | |||
1225 | * free space, and recenter it | |||
1226 | */ | |||
1227 | if (title_expands && width > 0) | |||
1228 | { | |||
1229 | child_allocation.width += width; | |||
1230 | child_allocation.x -= width / 2; | |||
1231 | } | |||
1232 | ||||
1233 | if (allocation->x + side[0] > child_allocation.x) | |||
1234 | child_allocation.x = allocation->x + side[0]; | |||
1235 | else if (allocation->x + allocation->width - side[1] < child_allocation.x + child_allocation.width) | |||
1236 | child_allocation.x = allocation->x + allocation->width - side[1] - child_allocation.width; | |||
1237 | ||||
1238 | if (direction == CTK_TEXT_DIR_RTL) | |||
1239 | child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; | |||
1240 | ||||
1241 | if (title_widget != NULL((void*)0)) | |||
1242 | ctk_widget_size_allocate (title_widget, &child_allocation); | |||
1243 | ||||
1244 | child_allocation.y = allocation->y; | |||
1245 | child_allocation.height = height; | |||
1246 | ||||
1247 | if (priv->titlebar_start_box) | |||
1248 | { | |||
1249 | gboolean left = (direction == CTK_TEXT_DIR_LTR); | |||
1250 | if (left) | |||
1251 | child_allocation.x = allocation->x; | |||
1252 | else | |||
1253 | child_allocation.x = allocation->x + allocation->width - start_width + priv->spacing; | |||
1254 | child_allocation.width = start_width - priv->spacing; | |||
1255 | ctk_widget_size_allocate (priv->titlebar_start_box, &child_allocation); | |||
1256 | } | |||
1257 | ||||
1258 | if (priv->titlebar_end_box) | |||
1259 | { | |||
1260 | gboolean left = (direction != CTK_TEXT_DIR_LTR); | |||
1261 | if (left) | |||
1262 | child_allocation.x = allocation->x; | |||
1263 | else | |||
1264 | child_allocation.x = allocation->x + allocation->width - end_width + priv->spacing; | |||
1265 | child_allocation.width = end_width - priv->spacing; | |||
1266 | ctk_widget_size_allocate (priv->titlebar_end_box, &child_allocation); | |||
1267 | } | |||
1268 | ||||
1269 | ctk_container_get_children_clip (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_container_get_type ())))))), out_clip); | |||
1270 | } | |||
1271 | ||||
1272 | /** | |||
1273 | * ctk_header_bar_set_title: | |||
1274 | * @bar: a #CtkHeaderBar | |||
1275 | * @title: (allow-none): a title, or %NULL | |||
1276 | * | |||
1277 | * Sets the title of the #CtkHeaderBar. The title should help a user | |||
1278 | * identify the current view. A good title should not include the | |||
1279 | * application name. | |||
1280 | * | |||
1281 | * Since: 3.10 | |||
1282 | */ | |||
1283 | void | |||
1284 | ctk_header_bar_set_title (CtkHeaderBar *bar, | |||
1285 | const gchar *title) | |||
1286 | { | |||
1287 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1288 | gchar *new_title; | |||
1289 | ||||
1290 | g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return; } } while (0); | |||
1291 | ||||
1292 | new_title = g_strdup (title)g_strdup_inline (title); | |||
1293 | g_free (priv->title); | |||
1294 | priv->title = new_title; | |||
1295 | ||||
1296 | if (priv->title_label != NULL((void*)0)) | |||
1297 | { | |||
1298 | ctk_label_set_label (CTK_LABEL (priv->title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->title_label)), ((ctk_label_get_type ())))))), priv->title); | |||
1299 | ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
1300 | } | |||
1301 | ||||
1302 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_TITLE]); | |||
1303 | } | |||
1304 | ||||
1305 | /** | |||
1306 | * ctk_header_bar_get_title: | |||
1307 | * @bar: a #CtkHeaderBar | |||
1308 | * | |||
1309 | * Retrieves the title of the header. See ctk_header_bar_set_title(). | |||
1310 | * | |||
1311 | * Returns: (nullable): the title of the header, or %NULL if none has | |||
1312 | * been set explicitly. The returned string is owned by the widget | |||
1313 | * and must not be modified or freed. | |||
1314 | * | |||
1315 | * Since: 3.10 | |||
1316 | */ | |||
1317 | const gchar * | |||
1318 | ctk_header_bar_get_title (CtkHeaderBar *bar) | |||
1319 | { | |||
1320 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1321 | ||||
1322 | g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return (((void*)0)); } } while (0); | |||
1323 | ||||
1324 | return priv->title; | |||
1325 | } | |||
1326 | ||||
1327 | /** | |||
1328 | * ctk_header_bar_set_subtitle: | |||
1329 | * @bar: a #CtkHeaderBar | |||
1330 | * @subtitle: (allow-none): a subtitle, or %NULL | |||
1331 | * | |||
1332 | * Sets the subtitle of the #CtkHeaderBar. The title should give a user | |||
1333 | * an additional detail to help him identify the current view. | |||
1334 | * | |||
1335 | * Note that CtkHeaderBar by default reserves room for the subtitle, | |||
1336 | * even if none is currently set. If this is not desired, set the | |||
1337 | * #CtkHeaderBar:has-subtitle property to %FALSE. | |||
1338 | * | |||
1339 | * Since: 3.10 | |||
1340 | */ | |||
1341 | void | |||
1342 | ctk_header_bar_set_subtitle (CtkHeaderBar *bar, | |||
1343 | const gchar *subtitle) | |||
1344 | { | |||
1345 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1346 | gchar *new_subtitle; | |||
1347 | ||||
1348 | g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return; } } while (0); | |||
1349 | ||||
1350 | new_subtitle = g_strdup (subtitle)g_strdup_inline (subtitle); | |||
1351 | g_free (priv->subtitle); | |||
1352 | priv->subtitle = new_subtitle; | |||
1353 | ||||
1354 | if (priv->subtitle_label != NULL((void*)0)) | |||
1355 | { | |||
1356 | ctk_label_set_label (CTK_LABEL (priv->subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->subtitle_label)), ((ctk_label_get_type ())))))), priv->subtitle); | |||
1357 | ctk_widget_set_visible (priv->subtitle_label, priv->subtitle && priv->subtitle[0]); | |||
1358 | ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
1359 | } | |||
1360 | ||||
1361 | ctk_widget_set_visible (priv->subtitle_sizing_label, priv->has_subtitle || (priv->subtitle && priv->subtitle[0])); | |||
1362 | ||||
1363 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_SUBTITLE]); | |||
1364 | } | |||
1365 | ||||
1366 | /** | |||
1367 | * ctk_header_bar_get_subtitle: | |||
1368 | * @bar: a #CtkHeaderBar | |||
1369 | * | |||
1370 | * Retrieves the subtitle of the header. See ctk_header_bar_set_subtitle(). | |||
1371 | * | |||
1372 | * Returns: (nullable): the subtitle of the header, or %NULL if none has | |||
1373 | * been set explicitly. The returned string is owned by the widget | |||
1374 | * and must not be modified or freed. | |||
1375 | * | |||
1376 | * Since: 3.10 | |||
1377 | */ | |||
1378 | const gchar * | |||
1379 | ctk_header_bar_get_subtitle (CtkHeaderBar *bar) | |||
1380 | { | |||
1381 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1382 | ||||
1383 | g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return (((void*)0)); } } while (0); | |||
1384 | ||||
1385 | return priv->subtitle; | |||
1386 | } | |||
1387 | ||||
1388 | /** | |||
1389 | * ctk_header_bar_set_custom_title: | |||
1390 | * @bar: a #CtkHeaderBar | |||
1391 | * @title_widget: (allow-none): a custom widget to use for a title | |||
1392 | * | |||
1393 | * Sets a custom title for the #CtkHeaderBar. | |||
1394 | * | |||
1395 | * The title should help a user identify the current view. This | |||
1396 | * supersedes any title set by ctk_header_bar_set_title() or | |||
1397 | * ctk_header_bar_set_subtitle(). To achieve the same style as | |||
1398 | * the builtin title and subtitle, use the “title” and “subtitle” | |||
1399 | * style classes. | |||
1400 | * | |||
1401 | * You should set the custom title to %NULL, for the header title | |||
1402 | * label to be visible again. | |||
1403 | * | |||
1404 | * Since: 3.10 | |||
1405 | */ | |||
1406 | void | |||
1407 | ctk_header_bar_set_custom_title (CtkHeaderBar *bar, | |||
1408 | CtkWidget *title_widget) | |||
1409 | { | |||
1410 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1411 | ||||
1412 | g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return; } } while (0); | |||
1413 | if (title_widget) | |||
1414 | g_return_if_fail (CTK_IS_WIDGET (title_widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((title_widget)); GType __t = ((ctk_widget_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (title_widget)"); return; } } while (0); | |||
1415 | ||||
1416 | /* No need to do anything if the custom widget stays the same */ | |||
1417 | if (priv->custom_title == title_widget) | |||
1418 | return; | |||
1419 | ||||
1420 | if (priv->custom_title) | |||
1421 | { | |||
1422 | CtkWidget *custom = priv->custom_title; | |||
1423 | ||||
1424 | priv->custom_title = NULL((void*)0); | |||
1425 | ctk_widget_unparent (custom); | |||
1426 | } | |||
1427 | ||||
1428 | if (title_widget != NULL((void*)0)) | |||
1429 | { | |||
1430 | priv->custom_title = title_widget; | |||
1431 | ||||
1432 | ctk_header_bar_reorder_css_node (bar, CTK_PACK_START, priv->custom_title); | |||
1433 | ctk_widget_set_parent (priv->custom_title, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
1434 | ctk_widget_set_valign (priv->custom_title, CTK_ALIGN_CENTER); | |||
1435 | ||||
1436 | if (priv->label_box != NULL((void*)0)) | |||
1437 | { | |||
1438 | CtkWidget *label_box = priv->label_box; | |||
1439 | ||||
1440 | priv->label_box = NULL((void*)0); | |||
1441 | priv->title_label = NULL((void*)0); | |||
1442 | priv->subtitle_label = NULL((void*)0); | |||
1443 | ctk_widget_unparent (label_box); | |||
1444 | } | |||
1445 | ||||
1446 | } | |||
1447 | else | |||
1448 | { | |||
1449 | if (priv->label_box == NULL((void*)0)) | |||
1450 | construct_label_box (bar); | |||
1451 | } | |||
1452 | ||||
1453 | ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
1454 | ||||
1455 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_CUSTOM_TITLE]); | |||
1456 | } | |||
1457 | ||||
1458 | /** | |||
1459 | * ctk_header_bar_get_custom_title: | |||
1460 | * @bar: a #CtkHeaderBar | |||
1461 | * | |||
1462 | * Retrieves the custom title widget of the header. See | |||
1463 | * ctk_header_bar_set_custom_title(). | |||
1464 | * | |||
1465 | * Returns: (nullable) (transfer none): the custom title widget | |||
1466 | * of the header, or %NULL if none has been set explicitly. | |||
1467 | * | |||
1468 | * Since: 3.10 | |||
1469 | */ | |||
1470 | CtkWidget * | |||
1471 | ctk_header_bar_get_custom_title (CtkHeaderBar *bar) | |||
1472 | { | |||
1473 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1474 | ||||
1475 | g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return (((void*)0)); } } while (0); | |||
1476 | ||||
1477 | return priv->custom_title; | |||
1478 | } | |||
1479 | ||||
1480 | static void | |||
1481 | ctk_header_bar_destroy (CtkWidget *widget) | |||
1482 | { | |||
1483 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
1484 | ||||
1485 | if (priv->label_sizing_box) | |||
1486 | { | |||
1487 | ctk_widget_destroy (priv->label_sizing_box); | |||
1488 | g_clear_object (&priv->label_sizing_box)do { _Static_assert (sizeof *((&priv->label_sizing_box )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&priv->label_sizing_box))) _pp = ((&priv->label_sizing_box )); __typeof__ (*((&priv->label_sizing_box))) _ptr = * _pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); | |||
1489 | } | |||
1490 | ||||
1491 | if (priv->custom_title) | |||
1492 | { | |||
1493 | ctk_widget_unparent (priv->custom_title); | |||
1494 | priv->custom_title = NULL((void*)0); | |||
1495 | } | |||
1496 | ||||
1497 | if (priv->label_box) | |||
1498 | { | |||
1499 | ctk_widget_unparent (priv->label_box); | |||
1500 | priv->label_box = NULL((void*)0); | |||
1501 | } | |||
1502 | ||||
1503 | if (priv->titlebar_start_box) | |||
1504 | { | |||
1505 | ctk_widget_unparent (priv->titlebar_start_box); | |||
1506 | priv->titlebar_start_box = NULL((void*)0); | |||
1507 | priv->titlebar_start_separator = NULL((void*)0); | |||
1508 | } | |||
1509 | ||||
1510 | if (priv->titlebar_end_box) | |||
1511 | { | |||
1512 | ctk_widget_unparent (priv->titlebar_end_box); | |||
1513 | priv->titlebar_end_box = NULL((void*)0); | |||
1514 | priv->titlebar_end_separator = NULL((void*)0); | |||
1515 | } | |||
1516 | ||||
1517 | CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ()) )))))->destroy (widget); | |||
1518 | } | |||
1519 | ||||
1520 | static void | |||
1521 | ctk_header_bar_finalize (GObject *object) | |||
1522 | { | |||
1523 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (object)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_header_bar_get_type ()))))))); | |||
1524 | ||||
1525 | g_free (priv->title); | |||
1526 | g_free (priv->subtitle); | |||
1527 | g_free (priv->decoration_layout); | |||
1528 | ||||
1529 | g_clear_object (&priv->gadget)do { _Static_assert (sizeof *((&priv->gadget)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((( &priv->gadget))) _pp = ((&priv->gadget)); __typeof__ (*((&priv->gadget))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); | |||
1530 | ||||
1531 | G_OBJECT_CLASS (ctk_header_bar_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_header_bar_parent_class)), (((GType) ((20) << ( 2))))))))->finalize (object); | |||
1532 | } | |||
1533 | ||||
1534 | static void | |||
1535 | ctk_header_bar_get_property (GObject *object, | |||
1536 | guint prop_id, | |||
1537 | GValue *value, | |||
1538 | GParamSpec *pspec) | |||
1539 | { | |||
1540 | CtkHeaderBar *bar = CTK_HEADER_BAR (object)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_header_bar_get_type ())))))); | |||
1541 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1542 | ||||
1543 | switch (prop_id) | |||
1544 | { | |||
1545 | case PROP_TITLE: | |||
1546 | g_value_set_string (value, priv->title); | |||
1547 | break; | |||
1548 | ||||
1549 | case PROP_SUBTITLE: | |||
1550 | g_value_set_string (value, priv->subtitle); | |||
1551 | break; | |||
1552 | ||||
1553 | case PROP_CUSTOM_TITLE: | |||
1554 | g_value_set_object (value, priv->custom_title); | |||
1555 | break; | |||
1556 | ||||
1557 | case PROP_SPACING: | |||
1558 | g_value_set_int (value, priv->spacing); | |||
1559 | break; | |||
1560 | ||||
1561 | case PROP_SHOW_CLOSE_BUTTON: | |||
1562 | g_value_set_boolean (value, ctk_header_bar_get_show_close_button (bar)); | |||
1563 | break; | |||
1564 | ||||
1565 | case PROP_HAS_SUBTITLE: | |||
1566 | g_value_set_boolean (value, ctk_header_bar_get_has_subtitle (bar)); | |||
1567 | break; | |||
1568 | ||||
1569 | case PROP_DECORATION_LAYOUT: | |||
1570 | g_value_set_string (value, ctk_header_bar_get_decoration_layout (bar)); | |||
1571 | break; | |||
1572 | ||||
1573 | case PROP_DECORATION_LAYOUT_SET: | |||
1574 | g_value_set_boolean (value, priv->decoration_layout_set); | |||
1575 | break; | |||
1576 | ||||
1577 | default: | |||
1578 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkheaderbar.c", 1578, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
1579 | break; | |||
1580 | } | |||
1581 | } | |||
1582 | ||||
1583 | static void | |||
1584 | ctk_header_bar_set_property (GObject *object, | |||
1585 | guint prop_id, | |||
1586 | const GValue *value, | |||
1587 | GParamSpec *pspec) | |||
1588 | { | |||
1589 | CtkHeaderBar *bar = CTK_HEADER_BAR (object)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_header_bar_get_type ())))))); | |||
1590 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1591 | ||||
1592 | switch (prop_id) | |||
1593 | { | |||
1594 | case PROP_TITLE: | |||
1595 | ctk_header_bar_set_title (bar, g_value_get_string (value)); | |||
1596 | break; | |||
1597 | ||||
1598 | case PROP_SUBTITLE: | |||
1599 | ctk_header_bar_set_subtitle (bar, g_value_get_string (value)); | |||
1600 | break; | |||
1601 | ||||
1602 | case PROP_CUSTOM_TITLE: | |||
1603 | ctk_header_bar_set_custom_title (bar, g_value_get_object (value)); | |||
1604 | break; | |||
1605 | ||||
1606 | case PROP_SPACING: | |||
1607 | if (priv->spacing != g_value_get_int (value)) | |||
1608 | { | |||
1609 | priv->spacing = g_value_get_int (value); | |||
1610 | ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
1611 | g_object_notify_by_pspec (object, pspec); | |||
1612 | } | |||
1613 | break; | |||
1614 | ||||
1615 | case PROP_SHOW_CLOSE_BUTTON: | |||
1616 | ctk_header_bar_set_show_close_button (bar, g_value_get_boolean (value)); | |||
1617 | break; | |||
1618 | ||||
1619 | case PROP_HAS_SUBTITLE: | |||
1620 | ctk_header_bar_set_has_subtitle (bar, g_value_get_boolean (value)); | |||
1621 | break; | |||
1622 | ||||
1623 | case PROP_DECORATION_LAYOUT: | |||
1624 | ctk_header_bar_set_decoration_layout (bar, g_value_get_string (value)); | |||
1625 | break; | |||
1626 | ||||
1627 | case PROP_DECORATION_LAYOUT_SET: | |||
1628 | priv->decoration_layout_set = g_value_get_boolean (value); | |||
1629 | break; | |||
1630 | ||||
1631 | default: | |||
1632 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkheaderbar.c", 1632, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
1633 | break; | |||
1634 | } | |||
1635 | } | |||
1636 | ||||
1637 | static void | |||
1638 | notify_child_cb (GObject *child G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1639 | GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1640 | CtkHeaderBar *bar) | |||
1641 | { | |||
1642 | _ctk_header_bar_update_separator_visibility (bar); | |||
1643 | } | |||
1644 | ||||
1645 | static void | |||
1646 | ctk_header_bar_pack (CtkHeaderBar *bar, | |||
1647 | CtkWidget *widget, | |||
1648 | CtkPackType pack_type) | |||
1649 | { | |||
1650 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1651 | Child *child; | |||
1652 | ||||
1653 | g_return_if_fail (ctk_widget_get_parent (widget) == NULL)do { if ((ctk_widget_get_parent (widget) == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "ctk_widget_get_parent (widget) == NULL"); return; } } while (0); | |||
1654 | ||||
1655 | child = g_new (Child, 1)((Child *) g_malloc_n ((1), sizeof (Child))); | |||
1656 | child->widget = widget; | |||
1657 | child->pack_type = pack_type; | |||
1658 | ||||
1659 | priv->children = g_list_append (priv->children, child); | |||
1660 | ||||
1661 | ctk_widget_freeze_child_notify (widget); | |||
1662 | ctk_header_bar_reorder_css_node (bar, CTK_PACK_START, widget); | |||
1663 | ctk_widget_set_parent (widget, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
1664 | g_signal_connect (widget, "notify::visible", G_CALLBACK (notify_child_cb), bar)g_signal_connect_data ((widget), ("notify::visible"), (((GCallback ) (notify_child_cb))), (bar), ((void*)0), (GConnectFlags) 0); | |||
1665 | ctk_widget_child_notify (widget, "pack-type"); | |||
1666 | ctk_widget_child_notify (widget, "position"); | |||
1667 | ctk_widget_thaw_child_notify (widget); | |||
1668 | ||||
1669 | _ctk_header_bar_update_separator_visibility (bar); | |||
1670 | } | |||
1671 | ||||
1672 | static void | |||
1673 | ctk_header_bar_add (CtkContainer *container, | |||
1674 | CtkWidget *child) | |||
1675 | { | |||
1676 | ctk_header_bar_pack (CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_header_bar_get_type ())))))), child, CTK_PACK_START); | |||
1677 | } | |||
1678 | ||||
1679 | static GList * | |||
1680 | find_child_link (CtkHeaderBar *bar, | |||
1681 | CtkWidget *widget, | |||
1682 | gint *position) | |||
1683 | { | |||
1684 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1685 | GList *l; | |||
1686 | Child *child; | |||
1687 | gint i; | |||
1688 | ||||
1689 | for (l = priv->children, i = 0; l; l = l->next, i++) | |||
1690 | { | |||
1691 | child = l->data; | |||
1692 | if (child->widget == widget) | |||
1693 | { | |||
1694 | if (position) | |||
1695 | *position = i; | |||
1696 | return l; | |||
1697 | } | |||
1698 | } | |||
1699 | ||||
1700 | return NULL((void*)0); | |||
1701 | } | |||
1702 | ||||
1703 | static void | |||
1704 | ctk_header_bar_remove (CtkContainer *container, | |||
1705 | CtkWidget *widget) | |||
1706 | { | |||
1707 | CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_header_bar_get_type ())))))); | |||
1708 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1709 | GList *l; | |||
1710 | Child *child; | |||
1711 | ||||
1712 | l = find_child_link (bar, widget, NULL((void*)0)); | |||
1713 | if (l) | |||
1714 | { | |||
1715 | child = l->data; | |||
1716 | g_signal_handlers_disconnect_by_func (widget, notify_child_cb, bar)g_signal_handlers_disconnect_matched ((widget), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (notify_child_cb), (bar)); | |||
1717 | ctk_widget_unparent (child->widget); | |||
1718 | priv->children = g_list_delete_link (priv->children, l); | |||
1719 | g_free (child); | |||
1720 | ctk_widget_queue_resize (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_widget_get_type ()))))))); | |||
1721 | _ctk_header_bar_update_separator_visibility (bar); | |||
1722 | } | |||
1723 | } | |||
1724 | ||||
1725 | static void | |||
1726 | ctk_header_bar_forall (CtkContainer *container, | |||
1727 | gboolean include_internals, | |||
1728 | CtkCallback callback, | |||
1729 | gpointer callback_data) | |||
1730 | { | |||
1731 | CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_header_bar_get_type ())))))); | |||
1732 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1733 | Child *child; | |||
1734 | GList *children; | |||
1735 | ||||
1736 | if (include_internals && priv->titlebar_start_box != NULL((void*)0)) | |||
1737 | (* callback) (priv->titlebar_start_box, callback_data); | |||
1738 | ||||
1739 | children = priv->children; | |||
1740 | while (children) | |||
1741 | { | |||
1742 | child = children->data; | |||
1743 | children = children->next; | |||
1744 | if (child->pack_type == CTK_PACK_START) | |||
1745 | (* callback) (child->widget, callback_data); | |||
1746 | } | |||
1747 | ||||
1748 | if (priv->custom_title != NULL((void*)0)) | |||
1749 | (* callback) (priv->custom_title, callback_data); | |||
1750 | ||||
1751 | if (include_internals && priv->label_box != NULL((void*)0)) | |||
1752 | (* callback) (priv->label_box, callback_data); | |||
1753 | ||||
1754 | children = priv->children; | |||
1755 | while (children) | |||
1756 | { | |||
1757 | child = children->data; | |||
1758 | children = children->next; | |||
1759 | if (child->pack_type == CTK_PACK_END) | |||
1760 | (* callback) (child->widget, callback_data); | |||
1761 | } | |||
1762 | ||||
1763 | if (include_internals && priv->titlebar_end_box != NULL((void*)0)) | |||
1764 | (* callback) (priv->titlebar_end_box, callback_data); | |||
1765 | } | |||
1766 | ||||
1767 | static void | |||
1768 | ctk_header_bar_reorder_child (CtkHeaderBar *bar, | |||
1769 | CtkWidget *widget, | |||
1770 | gint position) | |||
1771 | { | |||
1772 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1773 | GList *l; | |||
1774 | gint old_position; | |||
1775 | Child *child; | |||
1776 | ||||
1777 | l = find_child_link (bar, widget, &old_position); | |||
1778 | ||||
1779 | if (l == NULL((void*)0)) | |||
1780 | return; | |||
1781 | ||||
1782 | if (old_position == position) | |||
1783 | return; | |||
1784 | ||||
1785 | child = l->data; | |||
1786 | priv->children = g_list_delete_link (priv->children, l); | |||
1787 | ||||
1788 | if (position < 0) | |||
1789 | l = NULL((void*)0); | |||
1790 | else | |||
1791 | l = g_list_nth (priv->children, position); | |||
1792 | ||||
1793 | priv->children = g_list_insert_before (priv->children, l, child); | |||
1794 | ctk_header_bar_reorder_css_node (bar, child->pack_type, widget); | |||
1795 | ctk_widget_child_notify (widget, "position"); | |||
1796 | ctk_widget_queue_resize (widget); | |||
1797 | } | |||
1798 | ||||
1799 | static GType | |||
1800 | ctk_header_bar_child_type (CtkContainer *container G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
1801 | { | |||
1802 | return CTK_TYPE_WIDGET(ctk_widget_get_type ()); | |||
1803 | } | |||
1804 | ||||
1805 | static void | |||
1806 | ctk_header_bar_get_child_property (CtkContainer *container, | |||
1807 | CtkWidget *widget, | |||
1808 | guint property_id, | |||
1809 | GValue *value, | |||
1810 | GParamSpec *pspec) | |||
1811 | { | |||
1812 | CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_header_bar_get_type ())))))); | |||
1813 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar); | |||
1814 | GList *l; | |||
1815 | Child *child; | |||
1816 | ||||
1817 | l = find_child_link (bar, widget, NULL((void*)0)); | |||
1818 | if (l == NULL((void*)0)) | |||
1819 | { | |||
1820 | g_param_value_set_default (pspec, value); | |||
1821 | return; | |||
1822 | } | |||
1823 | ||||
1824 | child = l->data; | |||
1825 | ||||
1826 | switch (property_id) | |||
1827 | { | |||
1828 | case CHILD_PROP_PACK_TYPE: | |||
1829 | g_value_set_enum (value, child->pack_type); | |||
1830 | break; | |||
1831 | ||||
1832 | case CHILD_PROP_POSITION: | |||
1833 | g_value_set_int (value, g_list_position (priv->children, l)); | |||
1834 | break; | |||
1835 | ||||
1836 | default: | |||
1837 | CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkheaderbar.c", 1837, ("child property"), _glib__property_id , _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance *) (_glib__pspec))->g_class))->g_type)))), (g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
1838 | break; | |||
1839 | } | |||
1840 | } | |||
1841 | ||||
1842 | static void | |||
1843 | ctk_header_bar_set_child_property (CtkContainer *container, | |||
1844 | CtkWidget *widget, | |||
1845 | guint property_id, | |||
1846 | const GValue *value, | |||
1847 | GParamSpec *pspec) | |||
1848 | { | |||
1849 | CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_header_bar_get_type ())))))); | |||
1850 | GList *l; | |||
1851 | Child *child; | |||
1852 | ||||
1853 | l = find_child_link (bar, widget, NULL((void*)0)); | |||
1854 | if (l == NULL((void*)0)) | |||
1855 | return; | |||
1856 | ||||
1857 | child = l->data; | |||
1858 | ||||
1859 | switch (property_id) | |||
1860 | { | |||
1861 | case CHILD_PROP_PACK_TYPE: | |||
1862 | child->pack_type = g_value_get_enum (value); | |||
1863 | _ctk_header_bar_update_separator_visibility (bar); | |||
1864 | ctk_widget_queue_resize (widget); | |||
1865 | break; | |||
1866 | ||||
1867 | case CHILD_PROP_POSITION: | |||
1868 | ctk_header_bar_reorder_child (bar, widget, g_value_get_int (value)); | |||
1869 | break; | |||
1870 | ||||
1871 | default: | |||
1872 | CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkheaderbar.c", 1872, ("child property"), _glib__property_id , _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance *) (_glib__pspec))->g_class))->g_type)))), (g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
1873 | break; | |||
1874 | } | |||
1875 | } | |||
1876 | ||||
1877 | static gint | |||
1878 | ctk_header_bar_draw (CtkWidget *widget, | |||
1879 | cairo_t *cr) | |||
1880 | { | |||
1881 | CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
1882 | ||||
1883 | ctk_css_gadget_draw (priv->gadget, cr); | |||
1884 | ||||
1885 | return FALSE(0); | |||
1886 | } | |||
1887 | ||||
1888 | static gboolean | |||
1889 | ctk_header_bar_render_contents (CtkCssGadget *gadget, | |||
1890 | cairo_t *cr, | |||
1891 | int x G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1892 | int y G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1893 | int width G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1894 | int height G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1895 | gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
1896 | { | |||
1897 | CtkWidget *widget = ctk_css_gadget_get_owner (gadget); | |||
1898 | ||||
1899 | CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ()) )))))->draw (widget, cr); | |||
1900 | ||||
1901 | return FALSE(0); | |||
1902 | } | |||
1903 | ||||
1904 | static void | |||
1905 | ctk_header_bar_realize (CtkWidget *widget) | |||
1906 | { | |||
1907 | CtkSettings *settings; | |||
1908 | ||||
1909 | CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ()) )))))->realize (widget); | |||
1910 | ||||
1911 | settings = ctk_widget_get_settings (widget); | |||
1912 | g_signal_connect_swapped (settings, "notify::ctk-shell-shows-app-menu",g_signal_connect_data ((settings), ("notify::ctk-shell-shows-app-menu" ), (((GCallback) (_ctk_header_bar_update_window_buttons))), ( widget), ((void*)0), G_CONNECT_SWAPPED) | |||
1913 | G_CALLBACK (_ctk_header_bar_update_window_buttons), widget)g_signal_connect_data ((settings), ("notify::ctk-shell-shows-app-menu" ), (((GCallback) (_ctk_header_bar_update_window_buttons))), ( widget), ((void*)0), G_CONNECT_SWAPPED); | |||
1914 | g_signal_connect_swapped (settings, "notify::ctk-decoration-layout",g_signal_connect_data ((settings), ("notify::ctk-decoration-layout" ), (((GCallback) (_ctk_header_bar_update_window_buttons))), ( widget), ((void*)0), G_CONNECT_SWAPPED) | |||
1915 | G_CALLBACK (_ctk_header_bar_update_window_buttons), widget)g_signal_connect_data ((settings), ("notify::ctk-decoration-layout" ), (((GCallback) (_ctk_header_bar_update_window_buttons))), ( widget), ((void*)0), G_CONNECT_SWAPPED); | |||
1916 | _ctk_header_bar_update_window_buttons (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ()))))))); | |||
1917 | } | |||
1918 | ||||
1919 | static void | |||
1920 | ctk_header_bar_unrealize (CtkWidget *widget) | |||
1921 | { | |||
1922 | CtkSettings *settings; | |||
1923 | ||||
1924 | settings = ctk_widget_get_settings (widget); | |||
1925 | ||||
1926 | g_signal_handlers_disconnect_by_func (settings, _ctk_header_bar_update_window_buttons, widget)g_signal_handlers_disconnect_matched ((settings), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (_ctk_header_bar_update_window_buttons), (widget)); | |||
1927 | ||||
1928 | CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ()) )))))->unrealize (widget); | |||
1929 | } | |||
1930 | ||||
1931 | static gboolean | |||
1932 | window_state_changed (CtkWidget *window G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1933 | CdkEventWindowState *event, | |||
1934 | gpointer data) | |||
1935 | { | |||
1936 | CtkHeaderBar *bar = CTK_HEADER_BAR (data)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_header_bar_get_type ())))))); | |||
1937 | ||||
1938 | if (event->changed_mask & (CDK_WINDOW_STATE_FULLSCREEN | | |||
1939 | CDK_WINDOW_STATE_MAXIMIZED | | |||
1940 | CDK_WINDOW_STATE_TILED | | |||
1941 | CDK_WINDOW_STATE_TOP_TILED | | |||
1942 | CDK_WINDOW_STATE_RIGHT_TILED | | |||
1943 | CDK_WINDOW_STATE_BOTTOM_TILED | | |||
1944 | CDK_WINDOW_STATE_LEFT_TILED)) | |||
1945 | _ctk_header_bar_update_window_buttons (bar); | |||
1946 | ||||
1947 | return FALSE(0); | |||
1948 | } | |||
1949 | ||||
1950 | static void | |||
1951 | ctk_header_bar_hierarchy_changed (CtkWidget *widget, | |||
1952 | CtkWidget *previous_toplevel) | |||
1953 | { | |||
1954 | CtkWidget *toplevel; | |||
1955 | CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_header_bar_get_type ())))))); | |||
1956 | ||||
1957 | toplevel = ctk_widget_get_toplevel (widget); | |||
1958 | ||||
1959 | if (previous_toplevel) | |||
1960 | g_signal_handlers_disconnect_by_func (previous_toplevel,g_signal_handlers_disconnect_matched ((previous_toplevel), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (window_state_changed), (widget)) | |||
1961 | window_state_changed, widget)g_signal_handlers_disconnect_matched ((previous_toplevel), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (window_state_changed), (widget)); | |||
1962 | ||||
1963 | if (toplevel) | |||
1964 | g_signal_connect_after (toplevel, "window-state-event",g_signal_connect_data ((toplevel), ("window-state-event"), (( (GCallback) (window_state_changed))), (widget), ((void*)0), G_CONNECT_AFTER ) | |||
1965 | G_CALLBACK (window_state_changed), widget)g_signal_connect_data ((toplevel), ("window-state-event"), (( (GCallback) (window_state_changed))), (widget), ((void*)0), G_CONNECT_AFTER ); | |||
1966 | ||||
1967 | _ctk_header_bar_update_window_buttons (bar); | |||
1968 | } | |||
1969 | ||||
1970 | static void | |||
1971 | ctk_header_bar_direction_changed (CtkWidget *widget, | |||
1972 | CtkTextDirection previous_direction) | |||
1973 | { | |||
1974 | CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ()) )))))->direction_changed (widget, previous_direction); | |||
1975 | ||||
1976 | ctk_css_node_reverse_children (ctk_widget_get_css_node (widget)); | |||
1977 | } | |||
1978 | ||||
1979 | static void | |||
1980 | ctk_header_bar_class_init (CtkHeaderBarClass *class) | |||
1981 | { | |||
1982 | GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); | |||
1983 | CtkWidgetClass *widget_class = CTK_WIDGET_CLASS (class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), ((ctk_widget_get_type ())))))); | |||
1984 | CtkContainerClass *container_class = CTK_CONTAINER_CLASS (class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), ((ctk_container_get_type ())))))); | |||
1985 | ||||
1986 | object_class->finalize = ctk_header_bar_finalize; | |||
1987 | object_class->get_property = ctk_header_bar_get_property; | |||
1988 | object_class->set_property = ctk_header_bar_set_property; | |||
1989 | ||||
1990 | widget_class->destroy = ctk_header_bar_destroy; | |||
1991 | widget_class->size_allocate = ctk_header_bar_size_allocate; | |||
1992 | widget_class->get_preferred_width = ctk_header_bar_get_preferred_width; | |||
1993 | widget_class->get_preferred_height = ctk_header_bar_get_preferred_height; | |||
1994 | widget_class->get_preferred_height_for_width = ctk_header_bar_get_preferred_height_for_width; | |||
1995 | widget_class->get_preferred_width_for_height = ctk_header_bar_get_preferred_width_for_height; | |||
1996 | widget_class->draw = ctk_header_bar_draw; | |||
1997 | widget_class->realize = ctk_header_bar_realize; | |||
1998 | widget_class->unrealize = ctk_header_bar_unrealize; | |||
1999 | widget_class->hierarchy_changed = ctk_header_bar_hierarchy_changed; | |||
2000 | widget_class->direction_changed = ctk_header_bar_direction_changed; | |||
2001 | ||||
2002 | container_class->add = ctk_header_bar_add; | |||
2003 | container_class->remove = ctk_header_bar_remove; | |||
2004 | container_class->forall = ctk_header_bar_forall; | |||
2005 | container_class->child_type = ctk_header_bar_child_type; | |||
2006 | container_class->set_child_property = ctk_header_bar_set_child_property; | |||
2007 | container_class->get_child_property = ctk_header_bar_get_child_property; | |||
2008 | ctk_container_class_handle_border_width (container_class); | |||
2009 | ||||
2010 | ctk_container_class_install_child_property (container_class, | |||
2011 | CHILD_PROP_PACK_TYPE, | |||
2012 | g_param_spec_enum ("pack-type", | |||
2013 | P_("Pack type")g_dgettext("ctk30" "-properties","Pack type"), | |||
2014 | P_("A CtkPackType indicating whether the child is packed with reference to the start or end of the parent")g_dgettext("ctk30" "-properties","A CtkPackType indicating whether the child is packed with reference to the start or end of the parent" ), | |||
2015 | CTK_TYPE_PACK_TYPE(ctk_pack_type_get_type ()), CTK_PACK_START, | |||
2016 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); | |||
2017 | ctk_container_class_install_child_property (container_class, | |||
2018 | CHILD_PROP_POSITION, | |||
2019 | g_param_spec_int ("position", | |||
2020 | P_("Position")g_dgettext("ctk30" "-properties","Position"), | |||
2021 | P_("The index of the child in the parent")g_dgettext("ctk30" "-properties","The index of the child in the parent" ), | |||
2022 | -1, G_MAXINT2147483647, 0, | |||
2023 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); | |||
2024 | ||||
2025 | header_bar_props[PROP_TITLE] = | |||
2026 | g_param_spec_string ("title", | |||
2027 | P_("Title")g_dgettext("ctk30" "-properties","Title"), | |||
2028 | P_("The title to display")g_dgettext("ctk30" "-properties","The title to display"), | |||
2029 | NULL((void*)0), | |||
2030 | G_PARAM_READWRITE); | |||
2031 | ||||
2032 | header_bar_props[PROP_SUBTITLE] = | |||
2033 | g_param_spec_string ("subtitle", | |||
2034 | P_("Subtitle")g_dgettext("ctk30" "-properties","Subtitle"), | |||
2035 | P_("The subtitle to display")g_dgettext("ctk30" "-properties","The subtitle to display"), | |||
2036 | NULL((void*)0), | |||
2037 | G_PARAM_READWRITE); | |||
2038 | ||||
2039 | header_bar_props[PROP_CUSTOM_TITLE] = | |||
2040 | g_param_spec_object ("custom-title", | |||
2041 | P_("Custom Title")g_dgettext("ctk30" "-properties","Custom Title"), | |||
2042 | P_("Custom title widget to display")g_dgettext("ctk30" "-properties","Custom title widget to display" ), | |||
2043 | CTK_TYPE_WIDGET(ctk_widget_get_type ()), | |||
2044 | G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
2045 | ||||
2046 | header_bar_props[PROP_SPACING] = | |||
2047 | g_param_spec_int ("spacing", | |||
2048 | P_("Spacing")g_dgettext("ctk30" "-properties","Spacing"), | |||
2049 | P_("The amount of space between children")g_dgettext("ctk30" "-properties","The amount of space between children" ), | |||
2050 | 0, G_MAXINT2147483647, | |||
2051 | DEFAULT_SPACING6, | |||
2052 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
2053 | ||||
2054 | /** | |||
2055 | * CtkHeaderBar:show-close-button: | |||
2056 | * | |||
2057 | * Whether to show window decorations. | |||
2058 | * | |||
2059 | * Which buttons are actually shown and where is determined | |||
2060 | * by the #CtkHeaderBar:decoration-layout property, and by | |||
2061 | * the state of the window (e.g. a close button will not be | |||
2062 | * shown if the window can't be closed). | |||
2063 | */ | |||
2064 | header_bar_props[PROP_SHOW_CLOSE_BUTTON] = | |||
2065 | g_param_spec_boolean ("show-close-button", | |||
2066 | P_("Show decorations")g_dgettext("ctk30" "-properties","Show decorations"), | |||
2067 | P_("Whether to show window decorations")g_dgettext("ctk30" "-properties","Whether to show window decorations" ), | |||
2068 | FALSE(0), | |||
2069 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
2070 | ||||
2071 | /** | |||
2072 | * CtkHeaderBar:decoration-layout: | |||
2073 | * | |||
2074 | * The decoration layout for buttons. If this property is | |||
2075 | * not set, the #CtkSettings:ctk-decoration-layout setting | |||
2076 | * is used. | |||
2077 | * | |||
2078 | * See ctk_header_bar_set_decoration_layout() for information | |||
2079 | * about the format of this string. | |||
2080 | * | |||
2081 | * Since: 3.12 | |||
2082 | */ | |||
2083 | header_bar_props[PROP_DECORATION_LAYOUT] = | |||
2084 | g_param_spec_string ("decoration-layout", | |||
2085 | P_("Decoration Layout")g_dgettext("ctk30" "-properties","Decoration Layout"), | |||
2086 | P_("The layout for window decorations")g_dgettext("ctk30" "-properties","The layout for window decorations" ), | |||
2087 | NULL((void*)0), | |||
2088 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); | |||
2089 | ||||
2090 | /** | |||
2091 | * CtkHeaderBar:decoration-layout-set: | |||
2092 | * | |||
2093 | * Set to %TRUE if #CtkHeaderBar:decoration-layout is set. | |||
2094 | * | |||
2095 | * Since: 3.12 | |||
2096 | */ | |||
2097 | header_bar_props[PROP_DECORATION_LAYOUT_SET] = | |||
2098 | g_param_spec_boolean ("decoration-layout-set", | |||
2099 | P_("Decoration Layout Set")g_dgettext("ctk30" "-properties","Decoration Layout Set"), | |||
2100 | P_("Whether the decoration-layout property has been set")g_dgettext("ctk30" "-properties","Whether the decoration-layout property has been set" ), | |||
2101 | FALSE(0), | |||
2102 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); | |||
2103 | ||||
2104 | /** | |||
2105 | * CtkHeaderBar:has-subtitle: | |||
2106 | * | |||
2107 | * If %TRUE, reserve space for a subtitle, even if none | |||
2108 | * is currently set. | |||
2109 | * | |||
2110 | * Since: 3.12 | |||
2111 | */ | |||
2112 | header_bar_props[PROP_HAS_SUBTITLE] = | |||
2113 | g_param_spec_boolean ("has-subtitle", | |||
2114 | P_("Has Subtitle")g_dgettext("ctk30" "-properties","Has Subtitle"), | |||
2115 | P_("Whether to reserve space for a subtitle")g_dgettext("ctk30" "-properties","Whether to reserve space for a subtitle" ), | |||
2116 | TRUE(!(0)), | |||
2117 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
2118 | ||||
2119 | g_object_class_install_properties (object_class, LAST_PROP, header_bar_props); | |||
2120 | ||||
2121 | ctk_widget_class_set_accessible_type (widget_class, CTK_TYPE_HEADER_BAR_ACCESSIBLE(ctk_header_bar_accessible_get_type ())); | |||
2122 | ctk_widget_class_set_accessible_role (widget_class, ATK_ROLE_PANEL); | |||
2123 | ctk_widget_class_set_css_name (widget_class, "headerbar"); | |||
2124 | } | |||
2125 | ||||
2126 | static void | |||
2127 | ctk_header_bar_init (CtkHeaderBar *bar) | |||
2128 | { | |||
2129 | CtkHeaderBarPrivate *priv; | |||
2130 | CtkCssNode *widget_node; | |||
2131 | ||||
2132 | priv = ctk_header_bar_get_instance_private (bar); | |||
2133 | ||||
2134 | ctk_widget_set_has_window (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ())))))), FALSE(0)); | |||
2135 | ||||
2136 | priv->title = NULL((void*)0); | |||
2137 | priv->subtitle = NULL((void*)0); | |||
2138 | priv->custom_title = NULL((void*)0); | |||
2139 | priv->children = NULL((void*)0); | |||
2140 | priv->spacing = DEFAULT_SPACING6; | |||
2141 | priv->has_subtitle = TRUE(!(0)); | |||
2142 | priv->decoration_layout = NULL((void*)0); | |||
2143 | priv->decoration_layout_set = FALSE(0); | |||
2144 | ||||
2145 | init_sizing_box (bar); | |||
2146 | construct_label_box (bar); | |||
2147 | ||||
2148 | widget_node = ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
2149 | priv->gadget = ctk_css_custom_gadget_new_for_node (widget_node, | |||
2150 | CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ())))))), | |||
2151 | ctk_header_bar_get_content_size, | |||
2152 | ctk_header_bar_allocate_contents, | |||
2153 | ctk_header_bar_render_contents, | |||
2154 | NULL((void*)0), | |||
2155 | NULL((void*)0)); | |||
2156 | ||||
2157 | } | |||
2158 | ||||
2159 | static void | |||
2160 | ctk_header_bar_buildable_add_child (CtkBuildable *buildable, | |||
2161 | CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
2162 | GObject *child, | |||
2163 | const gchar *type) | |||
2164 | { | |||
2165 | if (type && strcmp (type, "title") == 0) | |||
2166 | ctk_header_bar_set_custom_title (CTK_HEADER_BAR (buildable)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((buildable)), ((ctk_header_bar_get_type ())))))), CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_widget_get_type ()))))))); | |||
2167 | else if (!type) | |||
2168 | ctk_container_add (CTK_CONTAINER (buildable)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((buildable)), ((ctk_container_get_type ())))))), CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_widget_get_type ()))))))); | |||
2169 | else | |||
2170 | CTK_BUILDER_WARN_INVALID_CHILD_TYPE (CTK_HEADER_BAR (buildable), type)g_warning ("'%s' is not a valid child type of '%s'", type, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((buildable) ), ((ctk_header_bar_get_type ()))))))))->g_class))->g_type ))))); | |||
2171 | } | |||
2172 | ||||
2173 | static void | |||
2174 | ctk_header_bar_buildable_init (CtkBuildableIface *iface) | |||
2175 | { | |||
2176 | iface->add_child = ctk_header_bar_buildable_add_child; | |||
2177 | } | |||
2178 | ||||
2179 | /** | |||
2180 | * ctk_header_bar_pack_start: | |||
2181 | * @bar: A #CtkHeaderBar | |||
2182 | * @child: the #CtkWidget to be added to @bar | |||
2183 | * | |||
2184 | * Adds @child to @bar, packed with reference to the | |||
2185 | * start of the @bar. | |||
2186 | * | |||
2187 | * Since: 3.10 | |||
2188 | */ | |||
2189 | void | |||
2190 | ctk_header_bar_pack_start (CtkHeaderBar *bar, | |||
2191 | CtkWidget *child) | |||
2192 | { | |||
2193 | ctk_header_bar_pack (bar, child, CTK_PACK_START); | |||
2194 | } | |||
2195 | ||||
2196 | /** | |||
2197 | * ctk_header_bar_pack_end: | |||
2198 | * @bar: A #CtkHeaderBar | |||
2199 | * @child: the #CtkWidget to be added to @bar | |||
2200 | * | |||
2201 | * Adds @child to @bar, packed with reference to the | |||
2202 | * end of the @bar. | |||
2203 | * | |||
2204 | * Since: 3.10 | |||
2205 | */ | |||
2206 | void | |||
2207 | ctk_header_bar_pack_end (CtkHeaderBar *bar, | |||
2208 | CtkWidget *child) | |||
2209 | { | |||
2210 | ctk_header_bar_pack (bar, child, CTK_PACK_END); | |||
2211 | } | |||
2212 | ||||
2213 | /** | |||
2214 | * ctk_header_bar_new: | |||
2215 | * | |||
2216 | * Creates a new #CtkHeaderBar widget. | |||
2217 | * | |||
2218 | * Returns: a new #CtkHeaderBar | |||
2219 | * | |||
2220 | * Since: 3.10 | |||
2221 | */ | |||
2222 | CtkWidget * | |||
2223 | ctk_header_bar_new (void) | |||
2224 | { | |||
2225 | return CTK_WIDGET (g_object_new (CTK_TYPE_HEADER_BAR, NULL))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_new ((ctk_header_bar_get_type ()), ((void*)0))) ), ((ctk_widget_get_type ())))))); | |||
2226 | } | |||
2227 | ||||
2228 | /** | |||
2229 | * ctk_header_bar_get_show_close_button: | |||
2230 | * @bar: a #CtkHeaderBar | |||
2231 | * | |||
2232 | * Returns whether this header bar shows the standard window | |||
2233 | * decorations. | |||
2234 | * | |||
2235 | * Returns: %TRUE if the decorations are shown | |||
2236 | * | |||
2237 | * Since: 3.10 | |||
2238 | */ | |||
2239 | gboolean | |||
2240 | ctk_header_bar_get_show_close_button (CtkHeaderBar *bar) | |||
2241 | { | |||
2242 | CtkHeaderBarPrivate *priv; | |||
2243 | ||||
2244 | g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return ((0)); } } while (0); | |||
2245 | ||||
2246 | priv = ctk_header_bar_get_instance_private (bar); | |||
2247 | ||||
2248 | return priv->shows_wm_decorations; | |||
2249 | } | |||
2250 | ||||
2251 | /** | |||
2252 | * ctk_header_bar_set_show_close_button: | |||
2253 | * @bar: a #CtkHeaderBar | |||
2254 | * @setting: %TRUE to show standard window decorations | |||
2255 | * | |||
2256 | * Sets whether this header bar shows the standard window decorations, | |||
2257 | * including close, maximize, and minimize. | |||
2258 | * | |||
2259 | * Since: 3.10 | |||
2260 | */ | |||
2261 | void | |||
2262 | ctk_header_bar_set_show_close_button (CtkHeaderBar *bar, | |||
2263 | gboolean setting) | |||
2264 | { | |||
2265 | CtkHeaderBarPrivate *priv; | |||
2266 | ||||
2267 | g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return; } } while (0); | |||
2268 | ||||
2269 | priv = ctk_header_bar_get_instance_private (bar); | |||
2270 | ||||
2271 | setting = setting != FALSE(0); | |||
2272 | ||||
2273 | if (priv->shows_wm_decorations == setting) | |||
2274 | return; | |||
2275 | ||||
2276 | priv->shows_wm_decorations = setting; | |||
2277 | _ctk_header_bar_update_window_buttons (bar); | |||
2278 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_SHOW_CLOSE_BUTTON]); | |||
2279 | } | |||
2280 | ||||
2281 | /** | |||
2282 | * ctk_header_bar_set_has_subtitle: | |||
2283 | * @bar: a #CtkHeaderBar | |||
2284 | * @setting: %TRUE to reserve space for a subtitle | |||
2285 | * | |||
2286 | * Sets whether the header bar should reserve space | |||
2287 | * for a subtitle, even if none is currently set. | |||
2288 | * | |||
2289 | * Since: 3.12 | |||
2290 | */ | |||
2291 | void | |||
2292 | ctk_header_bar_set_has_subtitle (CtkHeaderBar *bar, | |||
2293 | gboolean setting) | |||
2294 | { | |||
2295 | CtkHeaderBarPrivate *priv; | |||
2296 | ||||
2297 | g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return; } } while (0); | |||
2298 | ||||
2299 | priv = ctk_header_bar_get_instance_private (bar); | |||
2300 | ||||
2301 | setting = setting != FALSE(0); | |||
2302 | ||||
2303 | if (priv->has_subtitle == setting) | |||
2304 | return; | |||
2305 | ||||
2306 | priv->has_subtitle = setting; | |||
2307 | ctk_widget_set_visible (priv->subtitle_sizing_label, setting || (priv->subtitle && priv->subtitle[0])); | |||
2308 | ||||
2309 | ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), ((ctk_widget_get_type ()))))))); | |||
2310 | ||||
2311 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_HAS_SUBTITLE]); | |||
2312 | } | |||
2313 | ||||
2314 | /** | |||
2315 | * ctk_header_bar_get_has_subtitle: | |||
2316 | * @bar: a #CtkHeaderBar | |||
2317 | * | |||
2318 | * Retrieves whether the header bar reserves space for | |||
2319 | * a subtitle, regardless if one is currently set or not. | |||
2320 | * | |||
2321 | * Returns: %TRUE if the header bar reserves space | |||
2322 | * for a subtitle | |||
2323 | * | |||
2324 | * Since: 3.12 | |||
2325 | */ | |||
2326 | gboolean | |||
2327 | ctk_header_bar_get_has_subtitle (CtkHeaderBar *bar) | |||
2328 | { | |||
2329 | CtkHeaderBarPrivate *priv; | |||
2330 | ||||
2331 | g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return ((0)); } } while (0); | |||
2332 | ||||
2333 | priv = ctk_header_bar_get_instance_private (bar); | |||
2334 | ||||
2335 | return priv->has_subtitle; | |||
2336 | } | |||
2337 | ||||
2338 | /** | |||
2339 | * ctk_header_bar_set_decoration_layout: | |||
2340 | * @bar: a #CtkHeaderBar | |||
2341 | * @layout: (allow-none): a decoration layout, or %NULL to | |||
2342 | * unset the layout | |||
2343 | * | |||
2344 | * Sets the decoration layout for this header bar, overriding | |||
2345 | * the #CtkSettings:ctk-decoration-layout setting. | |||
2346 | * | |||
2347 | * There can be valid reasons for overriding the setting, such | |||
2348 | * as a header bar design that does not allow for buttons to take | |||
2349 | * room on the right, or only offers room for a single close button. | |||
2350 | * Split header bars are another example for overriding the | |||
2351 | * setting. | |||
2352 | * | |||
2353 | * The format of the string is button names, separated by commas. | |||
2354 | * A colon separates the buttons that should appear on the left | |||
2355 | * from those on the right. Recognized button names are minimize, | |||
2356 | * maximize, close, icon (the window icon) and menu (a menu button | |||
2357 | * for the fallback app menu). | |||
2358 | * | |||
2359 | * For example, “menu:minimize,maximize,close” specifies a menu | |||
2360 | * on the left, and minimize, maximize and close buttons on the right. | |||
2361 | * | |||
2362 | * Since: 3.12 | |||
2363 | */ | |||
2364 | void | |||
2365 | ctk_header_bar_set_decoration_layout (CtkHeaderBar *bar, | |||
2366 | const gchar *layout) | |||
2367 | { | |||
2368 | CtkHeaderBarPrivate *priv; | |||
2369 | ||||
2370 | g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return; } } while (0); | |||
2371 | ||||
2372 | priv = ctk_header_bar_get_instance_private (bar); | |||
2373 | ||||
2374 | g_free (priv->decoration_layout); | |||
2375 | priv->decoration_layout = g_strdup (layout)g_strdup_inline (layout); | |||
2376 | priv->decoration_layout_set = (layout != NULL((void*)0)); | |||
2377 | ||||
2378 | _ctk_header_bar_update_window_buttons (bar); | |||
2379 | ||||
2380 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_DECORATION_LAYOUT]); | |||
2381 | g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((bar)), (((GType) ((20) << (2)))))))), header_bar_props[PROP_DECORATION_LAYOUT_SET]); | |||
2382 | } | |||
2383 | ||||
2384 | /** | |||
2385 | * ctk_header_bar_get_decoration_layout: | |||
2386 | * @bar: a #CtkHeaderBar | |||
2387 | * | |||
2388 | * Gets the decoration layout set with | |||
2389 | * ctk_header_bar_set_decoration_layout(). | |||
2390 | * | |||
2391 | * Returns: the decoration layout | |||
2392 | * | |||
2393 | * Since: 3.12 | |||
2394 | */ | |||
2395 | const gchar * | |||
2396 | ctk_header_bar_get_decoration_layout (CtkHeaderBar *bar) | |||
2397 | { | |||
2398 | CtkHeaderBarPrivate *priv; | |||
2399 | ||||
2400 | g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bar)); GType __t = ((ctk_header_bar_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; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_HEADER_BAR (bar)"); return (((void*)0)); } } while (0); | |||
2401 | ||||
2402 | priv = ctk_header_bar_get_instance_private (bar); | |||
2403 | ||||
2404 | return priv->decoration_layout; | |||
2405 | } |