Line |
Branch |
Exec |
Source |
1 |
|
|
/* cc-vertical-row.c |
2 |
|
|
* |
3 |
|
|
* Copyright 2018 Purism SPC |
4 |
|
|
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> |
5 |
|
|
* 2023 Red Hat, Inc |
6 |
|
|
* |
7 |
|
|
* This program is free software: you can redistribute it and/or modify |
8 |
|
|
* it under the terms of the GNU General Public License as published by |
9 |
|
|
* the Free Software Foundation, either version 3 of the License, or |
10 |
|
|
* (at your option) any later version. |
11 |
|
|
* |
12 |
|
|
* This program is distributed in the hope that it will be useful, |
13 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
|
|
* GNU General Public License for more details. |
16 |
|
|
* |
17 |
|
|
* You should have received a copy of the GNU General Public License |
18 |
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 |
|
|
* |
20 |
|
|
* SPDX-License-Identifier: GPL-3.0-or-later |
21 |
|
|
*/ |
22 |
|
|
|
23 |
|
|
#include "cc-vertical-row.h" |
24 |
|
|
|
25 |
|
|
typedef struct |
26 |
|
|
{ |
27 |
|
|
AdwPreferencesRow parent; |
28 |
|
|
|
29 |
|
|
GtkBox *content_box; |
30 |
|
|
GtkBox *header; |
31 |
|
|
GtkImage *image; |
32 |
|
|
GtkBox *prefixes; |
33 |
|
|
GtkLabel *subtitle; |
34 |
|
|
GtkBox *suffixes; |
35 |
|
|
GtkLabel *title; |
36 |
|
|
GtkBox *title_box; |
37 |
|
|
|
38 |
|
|
GtkWidget *previous_parent; |
39 |
|
|
|
40 |
|
|
gboolean use_underline; |
41 |
|
|
gint title_lines; |
42 |
|
|
gint subtitle_lines; |
43 |
|
|
GtkWidget *activatable_widget; |
44 |
|
|
} CcVerticalRowPrivate; |
45 |
|
|
|
46 |
|
|
static GtkBuildableIface *parent_buildable_iface; |
47 |
|
|
|
48 |
|
|
static void cc_vertical_row_buildable_init (GtkBuildableIface *iface); |
49 |
|
|
|
50 |
|
✗ |
G_DEFINE_TYPE_WITH_CODE (CcVerticalRow, cc_vertical_row, ADW_TYPE_PREFERENCES_ROW, |
51 |
|
|
G_ADD_PRIVATE (CcVerticalRow) G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, cc_vertical_row_buildable_init)) |
52 |
|
|
|
53 |
|
|
enum |
54 |
|
|
{ |
55 |
|
|
PROP_0, |
56 |
|
|
PROP_ICON_NAME, |
57 |
|
|
PROP_ACTIVATABLE_WIDGET, |
58 |
|
|
PROP_SUBTITLE, |
59 |
|
|
PROP_USE_UNDERLINE, |
60 |
|
|
PROP_TITLE_LINES, |
61 |
|
|
PROP_SUBTITLE_LINES, |
62 |
|
|
N_PROPS, |
63 |
|
|
}; |
64 |
|
|
|
65 |
|
|
enum |
66 |
|
|
{ |
67 |
|
|
SIGNAL_ACTIVATED, |
68 |
|
|
SIGNAL_LAST_SIGNAL, |
69 |
|
|
}; |
70 |
|
|
|
71 |
|
|
static GParamSpec *props[N_PROPS] = { NULL, }; |
72 |
|
|
static guint signals[SIGNAL_LAST_SIGNAL] = { 0, }; |
73 |
|
|
|
74 |
|
|
static void |
75 |
|
✗ |
row_activated_cb (CcVerticalRow *self, |
76 |
|
|
GtkListBoxRow *row) |
77 |
|
|
{ |
78 |
|
|
/* No need to use GTK_LIST_BOX_ROW() for a pointer comparison. */ |
79 |
|
✗ |
if ((GtkListBoxRow *) self == row) |
80 |
|
✗ |
cc_vertical_row_activate (self); |
81 |
|
✗ |
} |
82 |
|
|
|
83 |
|
|
static void |
84 |
|
✗ |
parent_cb (CcVerticalRow *self) |
85 |
|
|
{ |
86 |
|
✗ |
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self)); |
87 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
88 |
|
|
|
89 |
|
✗ |
if (priv->previous_parent != NULL) |
90 |
|
|
{ |
91 |
|
✗ |
g_signal_handlers_disconnect_by_func (priv->previous_parent, |
92 |
|
|
G_CALLBACK (row_activated_cb), |
93 |
|
|
self); |
94 |
|
✗ |
priv->previous_parent = NULL; |
95 |
|
|
} |
96 |
|
|
|
97 |
|
✗ |
if (parent == NULL || !GTK_IS_LIST_BOX (parent)) |
98 |
|
✗ |
return; |
99 |
|
|
|
100 |
|
✗ |
priv->previous_parent = parent; |
101 |
|
✗ |
g_signal_connect_swapped (parent, "row-activated", G_CALLBACK (row_activated_cb), self); |
102 |
|
|
} |
103 |
|
|
|
104 |
|
|
static void |
105 |
|
✗ |
update_subtitle_visibility (CcVerticalRow *self) |
106 |
|
|
{ |
107 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
108 |
|
|
|
109 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (priv->subtitle), |
110 |
|
✗ |
gtk_label_get_text (priv->subtitle) != NULL && |
111 |
|
✗ |
g_strcmp0 (gtk_label_get_text (priv->subtitle), "") != 0); |
112 |
|
✗ |
} |
113 |
|
|
|
114 |
|
|
static void |
115 |
|
✗ |
cc_vertical_row_get_property (GObject *object, |
116 |
|
|
guint prop_id, |
117 |
|
|
GValue *value, |
118 |
|
|
GParamSpec *pspec) |
119 |
|
|
{ |
120 |
|
✗ |
CcVerticalRow *self = CC_VERTICAL_ROW (object); |
121 |
|
|
|
122 |
|
✗ |
switch (prop_id) |
123 |
|
|
{ |
124 |
|
✗ |
case PROP_ICON_NAME: |
125 |
|
✗ |
g_value_set_string (value, cc_vertical_row_get_icon_name (self)); |
126 |
|
✗ |
break; |
127 |
|
✗ |
case PROP_ACTIVATABLE_WIDGET: |
128 |
|
✗ |
g_value_set_object (value, (GObject *) cc_vertical_row_get_activatable_widget (self)); |
129 |
|
✗ |
break; |
130 |
|
✗ |
case PROP_SUBTITLE: |
131 |
|
✗ |
g_value_set_string (value, cc_vertical_row_get_subtitle (self)); |
132 |
|
✗ |
break; |
133 |
|
✗ |
case PROP_SUBTITLE_LINES: |
134 |
|
✗ |
g_value_set_int (value, cc_vertical_row_get_subtitle_lines (self)); |
135 |
|
✗ |
break; |
136 |
|
✗ |
case PROP_TITLE_LINES: |
137 |
|
✗ |
g_value_set_int (value, cc_vertical_row_get_title_lines (self)); |
138 |
|
✗ |
break; |
139 |
|
✗ |
case PROP_USE_UNDERLINE: |
140 |
|
✗ |
g_value_set_boolean (value, cc_vertical_row_get_use_underline (self)); |
141 |
|
✗ |
break; |
142 |
|
✗ |
default: |
143 |
|
✗ |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
144 |
|
|
} |
145 |
|
✗ |
} |
146 |
|
|
|
147 |
|
|
static void |
148 |
|
✗ |
cc_vertical_row_set_property (GObject *object, |
149 |
|
|
guint prop_id, |
150 |
|
|
const GValue *value, |
151 |
|
|
GParamSpec *pspec) |
152 |
|
|
{ |
153 |
|
✗ |
CcVerticalRow *self = CC_VERTICAL_ROW (object); |
154 |
|
|
|
155 |
|
✗ |
switch (prop_id) |
156 |
|
|
{ |
157 |
|
✗ |
case PROP_ICON_NAME: |
158 |
|
✗ |
cc_vertical_row_set_icon_name (self, g_value_get_string (value)); |
159 |
|
✗ |
break; |
160 |
|
✗ |
case PROP_ACTIVATABLE_WIDGET: |
161 |
|
✗ |
cc_vertical_row_set_activatable_widget (self, (GtkWidget*) g_value_get_object (value)); |
162 |
|
✗ |
break; |
163 |
|
✗ |
case PROP_SUBTITLE: |
164 |
|
✗ |
cc_vertical_row_set_subtitle (self, g_value_get_string (value)); |
165 |
|
✗ |
break; |
166 |
|
✗ |
case PROP_SUBTITLE_LINES: |
167 |
|
✗ |
cc_vertical_row_set_subtitle_lines (self, g_value_get_int (value)); |
168 |
|
✗ |
break; |
169 |
|
✗ |
case PROP_TITLE_LINES: |
170 |
|
✗ |
cc_vertical_row_set_title_lines (self, g_value_get_int (value)); |
171 |
|
✗ |
break; |
172 |
|
✗ |
case PROP_USE_UNDERLINE: |
173 |
|
✗ |
cc_vertical_row_set_use_underline (self, g_value_get_boolean (value)); |
174 |
|
✗ |
break; |
175 |
|
✗ |
default: |
176 |
|
✗ |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
177 |
|
|
} |
178 |
|
✗ |
} |
179 |
|
|
|
180 |
|
|
static void |
181 |
|
✗ |
cc_vertical_row_dispose (GObject *object) |
182 |
|
|
{ |
183 |
|
✗ |
CcVerticalRow *self = CC_VERTICAL_ROW (object); |
184 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
185 |
|
|
|
186 |
|
✗ |
if (priv->previous_parent != NULL) { |
187 |
|
✗ |
g_signal_handlers_disconnect_by_func (priv->previous_parent, G_CALLBACK (row_activated_cb), self); |
188 |
|
✗ |
priv->previous_parent = NULL; |
189 |
|
|
} |
190 |
|
|
|
191 |
|
✗ |
cc_vertical_row_set_activatable_widget (self, NULL); |
192 |
|
✗ |
g_clear_pointer ((GtkWidget**)&priv->header, gtk_widget_unparent); |
193 |
|
|
|
194 |
|
✗ |
G_OBJECT_CLASS (cc_vertical_row_parent_class)->dispose (object); |
195 |
|
✗ |
} |
196 |
|
|
|
197 |
|
|
static void |
198 |
|
✗ |
cc_vertical_row_class_init (CcVerticalRowClass *klass) |
199 |
|
|
{ |
200 |
|
✗ |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
201 |
|
✗ |
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
202 |
|
|
|
203 |
|
✗ |
object_class->get_property = cc_vertical_row_get_property; |
204 |
|
✗ |
object_class->set_property = cc_vertical_row_set_property; |
205 |
|
✗ |
object_class->dispose = cc_vertical_row_dispose; |
206 |
|
|
|
207 |
|
✗ |
props[PROP_ICON_NAME] = |
208 |
|
✗ |
g_param_spec_string ("icon-name", |
209 |
|
|
"Icon name", |
210 |
|
|
"Icon name", |
211 |
|
|
"", |
212 |
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); |
213 |
|
|
|
214 |
|
✗ |
props[PROP_ACTIVATABLE_WIDGET] = |
215 |
|
✗ |
g_param_spec_object ("activatable-widget", |
216 |
|
|
"Activatable widget", |
217 |
|
|
"The widget to be activated when the row is activated", |
218 |
|
|
GTK_TYPE_WIDGET, |
219 |
|
|
G_PARAM_READWRITE); |
220 |
|
|
|
221 |
|
✗ |
props[PROP_SUBTITLE] = |
222 |
|
✗ |
g_param_spec_string ("subtitle", |
223 |
|
|
"Subtitle", |
224 |
|
|
"Subtitle", |
225 |
|
|
"", |
226 |
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); |
227 |
|
|
|
228 |
|
✗ |
props[PROP_USE_UNDERLINE] = |
229 |
|
✗ |
g_param_spec_boolean ("use-underline", |
230 |
|
|
"Use underline", |
231 |
|
|
"If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key", |
232 |
|
|
FALSE, |
233 |
|
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); |
234 |
|
|
|
235 |
|
✗ |
props[PROP_TITLE_LINES] = |
236 |
|
✗ |
g_param_spec_int ("title-lines", |
237 |
|
|
"Number of title lines", |
238 |
|
|
"The desired number of title lines", |
239 |
|
|
0, G_MAXINT, |
240 |
|
|
1, |
241 |
|
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); |
242 |
|
|
|
243 |
|
✗ |
props[PROP_SUBTITLE_LINES] = |
244 |
|
✗ |
g_param_spec_int ("subtitle-lines", |
245 |
|
|
"Number of subtitle lines", |
246 |
|
|
"The desired number of subtitle lines", |
247 |
|
|
0, G_MAXINT, |
248 |
|
|
1, |
249 |
|
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); |
250 |
|
|
|
251 |
|
✗ |
g_object_class_install_properties (object_class, N_PROPS, props); |
252 |
|
|
|
253 |
|
✗ |
signals[SIGNAL_ACTIVATED] = |
254 |
|
✗ |
g_signal_new ("activated", |
255 |
|
|
G_TYPE_FROM_CLASS (klass), |
256 |
|
|
G_SIGNAL_RUN_LAST, |
257 |
|
|
0, |
258 |
|
|
NULL, NULL, NULL, |
259 |
|
|
G_TYPE_NONE, |
260 |
|
|
0); |
261 |
|
|
|
262 |
|
✗ |
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/common/cc-vertical-row.ui"); |
263 |
|
|
|
264 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, content_box); |
265 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, header); |
266 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, image); |
267 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, prefixes); |
268 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, subtitle); |
269 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, suffixes); |
270 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, title); |
271 |
|
✗ |
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, title_box); |
272 |
|
✗ |
} |
273 |
|
|
|
274 |
|
|
static gboolean |
275 |
|
✗ |
string_is_not_empty (GBinding *binding, |
276 |
|
|
const GValue *from_value, |
277 |
|
|
GValue *to_value, |
278 |
|
|
gpointer user_data) |
279 |
|
|
{ |
280 |
|
✗ |
const gchar *string = g_value_get_string (from_value); |
281 |
|
|
|
282 |
|
✗ |
g_value_set_boolean (to_value, string != NULL && g_strcmp0 (string, "") != 0); |
283 |
|
|
|
284 |
|
✗ |
return TRUE; |
285 |
|
|
} |
286 |
|
|
|
287 |
|
|
static void |
288 |
|
✗ |
cc_vertical_row_init (CcVerticalRow *self) |
289 |
|
|
{ |
290 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
291 |
|
|
|
292 |
|
✗ |
priv->title_lines = 1; |
293 |
|
✗ |
priv->subtitle_lines = 1; |
294 |
|
|
|
295 |
|
✗ |
gtk_widget_init_template (GTK_WIDGET (self)); |
296 |
|
|
|
297 |
|
✗ |
g_object_bind_property_full (self, "title", |
298 |
|
✗ |
priv->title, "visible", |
299 |
|
|
G_BINDING_SYNC_CREATE, |
300 |
|
|
string_is_not_empty, |
301 |
|
|
NULL, NULL, NULL); |
302 |
|
|
|
303 |
|
✗ |
update_subtitle_visibility (self); |
304 |
|
|
|
305 |
|
✗ |
g_signal_connect (self, "notify::parent", G_CALLBACK (parent_cb), NULL); |
306 |
|
✗ |
} |
307 |
|
|
|
308 |
|
|
static void |
309 |
|
✗ |
cc_vertical_row_buildable_add_child (GtkBuildable *buildable, |
310 |
|
|
GtkBuilder *builder, |
311 |
|
|
GObject *child, |
312 |
|
|
const gchar *type) |
313 |
|
|
{ |
314 |
|
✗ |
CcVerticalRow *self = CC_VERTICAL_ROW (buildable); |
315 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
316 |
|
|
|
317 |
|
✗ |
if (!priv->header) |
318 |
|
✗ |
parent_buildable_iface->add_child (buildable, builder, child, type); |
319 |
|
✗ |
else if (type && strcmp (type, "prefix") == 0) |
320 |
|
✗ |
cc_vertical_row_add_prefix (self, GTK_WIDGET (child)); |
321 |
|
✗ |
else if (type && strcmp (type, "content") == 0) |
322 |
|
✗ |
cc_vertical_row_add_content (self, GTK_WIDGET (child)); |
323 |
|
✗ |
else if (!type && GTK_IS_WIDGET (child)) |
324 |
|
|
{ |
325 |
|
✗ |
gtk_box_append (priv->suffixes, GTK_WIDGET (child)); |
326 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (priv->suffixes), TRUE); |
327 |
|
|
} |
328 |
|
|
else |
329 |
|
✗ |
parent_buildable_iface->add_child (buildable, builder, child, type); |
330 |
|
✗ |
} |
331 |
|
|
|
332 |
|
|
static void |
333 |
|
✗ |
cc_vertical_row_buildable_init (GtkBuildableIface *iface) |
334 |
|
|
{ |
335 |
|
✗ |
parent_buildable_iface = g_type_interface_peek_parent (iface); |
336 |
|
✗ |
iface->add_child = cc_vertical_row_buildable_add_child; |
337 |
|
✗ |
} |
338 |
|
|
|
339 |
|
|
const gchar * |
340 |
|
✗ |
cc_vertical_row_get_subtitle (CcVerticalRow *self) |
341 |
|
|
{ |
342 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
343 |
|
✗ |
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), NULL); |
344 |
|
|
|
345 |
|
✗ |
return gtk_label_get_text (priv->subtitle); |
346 |
|
|
} |
347 |
|
|
|
348 |
|
|
void |
349 |
|
✗ |
cc_vertical_row_set_subtitle (CcVerticalRow *self, |
350 |
|
|
const gchar *subtitle) |
351 |
|
|
{ |
352 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
353 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
354 |
|
|
|
355 |
|
✗ |
if (g_strcmp0 (gtk_label_get_text (priv->subtitle), subtitle) == 0) |
356 |
|
✗ |
return; |
357 |
|
|
|
358 |
|
✗ |
gtk_label_set_text (priv->subtitle, subtitle); |
359 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (priv->subtitle), |
360 |
|
✗ |
subtitle != NULL && g_strcmp0 (subtitle, "") != 0); |
361 |
|
|
|
362 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SUBTITLE]); |
363 |
|
|
} |
364 |
|
|
|
365 |
|
|
const gchar * |
366 |
|
✗ |
cc_vertical_row_get_icon_name (CcVerticalRow *self) |
367 |
|
|
{ |
368 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
369 |
|
✗ |
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), NULL); |
370 |
|
|
|
371 |
|
✗ |
return gtk_image_get_icon_name (priv->image); |
372 |
|
|
} |
373 |
|
|
|
374 |
|
|
void |
375 |
|
✗ |
cc_vertical_row_set_icon_name (CcVerticalRow *self, |
376 |
|
|
const gchar *icon_name) |
377 |
|
|
{ |
378 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
379 |
|
|
const gchar *old_icon_name; |
380 |
|
|
|
381 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
382 |
|
|
|
383 |
|
✗ |
old_icon_name = gtk_image_get_icon_name (priv->image); |
384 |
|
✗ |
if (g_strcmp0 (old_icon_name, icon_name) == 0) |
385 |
|
✗ |
return; |
386 |
|
|
|
387 |
|
✗ |
gtk_image_set_from_icon_name (priv->image, icon_name); |
388 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (priv->image), |
389 |
|
✗ |
icon_name != NULL && g_strcmp0 (icon_name, "") != 0); |
390 |
|
|
|
391 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]); |
392 |
|
|
} |
393 |
|
|
|
394 |
|
|
GtkWidget * |
395 |
|
✗ |
cc_vertical_row_get_activatable_widget (CcVerticalRow *self) |
396 |
|
|
{ |
397 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
398 |
|
✗ |
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), NULL); |
399 |
|
|
|
400 |
|
✗ |
return priv->activatable_widget; |
401 |
|
|
} |
402 |
|
|
|
403 |
|
|
static void |
404 |
|
✗ |
activatable_widget_weak_notify (gpointer data, |
405 |
|
|
GObject *where_the_object_was) |
406 |
|
|
{ |
407 |
|
✗ |
CcVerticalRow *self = CC_VERTICAL_ROW (data); |
408 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
409 |
|
|
|
410 |
|
✗ |
priv->activatable_widget = NULL; |
411 |
|
|
|
412 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVATABLE_WIDGET]); |
413 |
|
✗ |
} |
414 |
|
|
|
415 |
|
|
void |
416 |
|
✗ |
cc_vertical_row_set_activatable_widget (CcVerticalRow *self, |
417 |
|
|
GtkWidget *widget) |
418 |
|
|
{ |
419 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
420 |
|
|
|
421 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
422 |
|
✗ |
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget)); |
423 |
|
|
|
424 |
|
✗ |
if (priv->activatable_widget == widget) |
425 |
|
✗ |
return; |
426 |
|
|
|
427 |
|
✗ |
if (priv->activatable_widget) |
428 |
|
✗ |
g_object_weak_unref (G_OBJECT (priv->activatable_widget), |
429 |
|
|
activatable_widget_weak_notify, |
430 |
|
|
self); |
431 |
|
|
|
432 |
|
✗ |
priv->activatable_widget = widget; |
433 |
|
|
|
434 |
|
✗ |
if (priv->activatable_widget != NULL) { |
435 |
|
✗ |
g_object_weak_ref (G_OBJECT (priv->activatable_widget), |
436 |
|
|
activatable_widget_weak_notify, |
437 |
|
|
self); |
438 |
|
✗ |
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (self), TRUE); |
439 |
|
✗ |
gtk_accessible_update_relation (GTK_ACCESSIBLE (priv->activatable_widget), |
440 |
|
|
GTK_ACCESSIBLE_RELATION_LABELLED_BY, priv->title, NULL, |
441 |
|
|
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, priv->subtitle, NULL, |
442 |
|
|
-1); |
443 |
|
|
|
444 |
|
|
} |
445 |
|
|
|
446 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVATABLE_WIDGET]); |
447 |
|
|
} |
448 |
|
|
|
449 |
|
|
gboolean |
450 |
|
✗ |
cc_vertical_row_get_use_underline (CcVerticalRow *self) |
451 |
|
|
{ |
452 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
453 |
|
|
|
454 |
|
✗ |
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), FALSE); |
455 |
|
|
|
456 |
|
✗ |
return priv->use_underline; |
457 |
|
|
} |
458 |
|
|
|
459 |
|
|
void |
460 |
|
✗ |
cc_vertical_row_set_use_underline (CcVerticalRow *self, |
461 |
|
|
gboolean use_underline) |
462 |
|
|
{ |
463 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
464 |
|
|
|
465 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
466 |
|
|
|
467 |
|
✗ |
use_underline = !!use_underline; |
468 |
|
|
|
469 |
|
✗ |
if (priv->use_underline == use_underline) |
470 |
|
✗ |
return; |
471 |
|
|
|
472 |
|
✗ |
priv->use_underline = use_underline; |
473 |
|
✗ |
adw_preferences_row_set_use_underline (ADW_PREFERENCES_ROW (self), priv->use_underline); |
474 |
|
✗ |
gtk_label_set_use_underline (priv->title, priv->use_underline); |
475 |
|
✗ |
gtk_label_set_use_underline (priv->subtitle, priv->use_underline); |
476 |
|
✗ |
gtk_label_set_mnemonic_widget (priv->title, GTK_WIDGET (self)); |
477 |
|
✗ |
gtk_label_set_mnemonic_widget (priv->subtitle, GTK_WIDGET (self)); |
478 |
|
|
|
479 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_USE_UNDERLINE]); |
480 |
|
|
} |
481 |
|
|
|
482 |
|
|
gint |
483 |
|
✗ |
cc_vertical_row_get_title_lines (CcVerticalRow *self) |
484 |
|
|
{ |
485 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
486 |
|
|
|
487 |
|
✗ |
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), 0); |
488 |
|
|
|
489 |
|
✗ |
return priv->title_lines; |
490 |
|
|
} |
491 |
|
|
|
492 |
|
|
void |
493 |
|
✗ |
cc_vertical_row_set_title_lines (CcVerticalRow *self, |
494 |
|
|
gint title_lines) |
495 |
|
|
{ |
496 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
497 |
|
|
|
498 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
499 |
|
✗ |
g_return_if_fail (title_lines >= 0); |
500 |
|
|
|
501 |
|
✗ |
if (priv->title_lines == title_lines) |
502 |
|
✗ |
return; |
503 |
|
|
|
504 |
|
✗ |
priv->title_lines = title_lines; |
505 |
|
|
|
506 |
|
✗ |
gtk_label_set_lines (priv->title, title_lines); |
507 |
|
✗ |
gtk_label_set_ellipsize (priv->title, title_lines == 0 ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END); |
508 |
|
|
|
509 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TITLE_LINES]); |
510 |
|
|
} |
511 |
|
|
|
512 |
|
|
gint |
513 |
|
✗ |
cc_vertical_row_get_subtitle_lines (CcVerticalRow *self) |
514 |
|
|
{ |
515 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
516 |
|
|
|
517 |
|
✗ |
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), 0); |
518 |
|
|
|
519 |
|
✗ |
return priv->subtitle_lines; |
520 |
|
|
} |
521 |
|
|
|
522 |
|
|
void |
523 |
|
✗ |
cc_vertical_row_set_subtitle_lines (CcVerticalRow *self, |
524 |
|
|
gint subtitle_lines) |
525 |
|
|
{ |
526 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
527 |
|
|
|
528 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
529 |
|
✗ |
g_return_if_fail (subtitle_lines >= 0); |
530 |
|
|
|
531 |
|
✗ |
if (priv->subtitle_lines == subtitle_lines) |
532 |
|
✗ |
return; |
533 |
|
|
|
534 |
|
✗ |
priv->subtitle_lines = subtitle_lines; |
535 |
|
|
|
536 |
|
✗ |
gtk_label_set_lines (priv->subtitle, subtitle_lines); |
537 |
|
✗ |
gtk_label_set_ellipsize (priv->subtitle, subtitle_lines == 0 ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END); |
538 |
|
|
|
539 |
|
✗ |
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SUBTITLE_LINES]); |
540 |
|
|
} |
541 |
|
|
|
542 |
|
|
void |
543 |
|
✗ |
cc_vertical_row_add_prefix (CcVerticalRow *self, |
544 |
|
|
GtkWidget *widget) |
545 |
|
|
{ |
546 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
547 |
|
|
|
548 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
549 |
|
✗ |
g_return_if_fail (GTK_IS_WIDGET (self)); |
550 |
|
|
|
551 |
|
✗ |
gtk_box_append (priv->prefixes, widget); |
552 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (priv->prefixes), TRUE); |
553 |
|
|
} |
554 |
|
|
|
555 |
|
|
void |
556 |
|
✗ |
cc_vertical_row_add_content (CcVerticalRow *self, |
557 |
|
|
GtkWidget *widget) |
558 |
|
|
{ |
559 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
560 |
|
|
|
561 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
562 |
|
✗ |
g_return_if_fail (GTK_IS_WIDGET (self)); |
563 |
|
|
|
564 |
|
|
/* HACK: the content box pushes the title too much to the top, so we |
565 |
|
|
* need to compensate this here. |
566 |
|
|
*/ |
567 |
|
✗ |
gtk_widget_set_margin_top (GTK_WIDGET (priv->header), 12); |
568 |
|
|
|
569 |
|
✗ |
gtk_box_append (priv->content_box, widget); |
570 |
|
✗ |
gtk_widget_set_visible (GTK_WIDGET (priv->content_box), TRUE); |
571 |
|
|
} |
572 |
|
|
|
573 |
|
|
void |
574 |
|
✗ |
cc_vertical_row_activate (CcVerticalRow *self) |
575 |
|
|
{ |
576 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
577 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
578 |
|
|
|
579 |
|
✗ |
if (priv->activatable_widget) |
580 |
|
✗ |
gtk_widget_mnemonic_activate (priv->activatable_widget, FALSE); |
581 |
|
|
|
582 |
|
✗ |
g_signal_emit (self, signals[SIGNAL_ACTIVATED], 0); |
583 |
|
|
} |
584 |
|
|
|
585 |
|
|
void |
586 |
|
✗ |
cc_vertical_row_remove (CcVerticalRow *self, |
587 |
|
|
GtkWidget *child) |
588 |
|
|
{ |
589 |
|
✗ |
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self); |
590 |
|
|
GtkWidget *parent; |
591 |
|
|
|
592 |
|
✗ |
g_return_if_fail (CC_IS_VERTICAL_ROW (self)); |
593 |
|
✗ |
g_return_if_fail (GTK_IS_WIDGET (child)); |
594 |
|
|
|
595 |
|
✗ |
parent = gtk_widget_get_parent (child); |
596 |
|
|
|
597 |
|
✗ |
if (parent == GTK_WIDGET (priv->prefixes)) |
598 |
|
✗ |
gtk_box_remove (priv->prefixes, child); |
599 |
|
✗ |
else if (parent == GTK_WIDGET (priv->suffixes)) |
600 |
|
✗ |
gtk_box_remove (priv->suffixes, child); |
601 |
|
✗ |
else if (parent == GTK_WIDGET (priv->content_box)) |
602 |
|
✗ |
gtk_box_remove (priv->content_box, child); |
603 |
|
|
else |
604 |
|
✗ |
g_warning ("%p is not a child of %p", child, self); |
605 |
|
|
} |
606 |
|
|
|
607 |
|
|
|