Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-share-dialog-row"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <adwaita.h>
9 : : #include <gtk/gtk.h>
10 : : #include <valent.h>
11 : :
12 : : #include "valent-share-dialog-row.h"
13 : :
14 : :
15 : : struct _ValentShareDialogRow
16 : : {
17 : : GtkListBoxRow parent_instance;
18 : :
19 : : ValentDevice *device;
20 : : AdwAnimation *animation;
21 : : unsigned int selected : 1;
22 : : unsigned int selection_mode : 1;
23 : :
24 : : /* template */
25 : : GtkRevealer *revealer;
26 : : GtkCheckButton *selected_button;
27 : : GtkImage *icon_image;
28 : : GtkLabel *name_label;
29 : : GtkImage *next_image;
30 : : };
31 : :
32 [ + + + - ]: 8 : G_DEFINE_FINAL_TYPE (ValentShareDialogRow, valent_share_dialog_row, GTK_TYPE_LIST_BOX_ROW)
33 : :
34 : :
35 : : enum {
36 : : PROP_0,
37 : : PROP_DEVICE,
38 : : PROP_SELECTED,
39 : : PROP_SELECTION_MODE,
40 : : N_PROPERTIES
41 : : };
42 : :
43 : : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
44 : :
45 : :
46 : : static void
47 : 0 : on_selection_enable (ValentShareDialogRow *self)
48 : : {
49 : 0 : GtkRoot *root = NULL;
50 : :
51 [ # # ]: 0 : if (self->selection_mode)
52 : : return;
53 : :
54 [ # # ]: 0 : if ((root = gtk_widget_get_root (GTK_WIDGET (self))) == NULL)
55 : : return;
56 : :
57 : 0 : g_object_set (root, "selection-mode", TRUE, NULL);
58 : 0 : valent_share_dialog_row_set_selected (self, TRUE);
59 : : }
60 : :
61 : : static void
62 : 0 : on_selection_disable (ValentShareDialogRow *self)
63 : : {
64 [ # # ]: 0 : if (!gtk_revealer_get_child_revealed (self->revealer))
65 : 0 : valent_share_dialog_row_set_selected (self, FALSE);
66 : 0 : }
67 : :
68 : : /*
69 : : * ValentShareDialogRow
70 : : */
71 : : static void
72 : 1 : valent_share_dialog_row_set_device (ValentShareDialogRow *self,
73 : : ValentDevice *device)
74 : : {
75 [ + - ]: 1 : g_assert (VALENT_IS_SHARE_DIALOG_ROW (self));
76 [ + - - + ]: 1 : g_assert (device == NULL || VALENT_IS_DEVICE (device));
77 : :
78 [ + - ]: 1 : if (!g_set_object (&self->device, device))
79 : : return;
80 : :
81 : 1 : g_object_bind_property (device, "icon-name",
82 : 1 : self->icon_image, "icon-name",
83 : : G_BINDING_SYNC_CREATE);
84 : 1 : g_object_bind_property (device, "name",
85 : 1 : self->name_label, "label",
86 : : G_BINDING_SYNC_CREATE);
87 : :
88 : 1 : g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEVICE]);
89 : : }
90 : :
91 : : /*
92 : : * GObject
93 : : */
94 : : static void
95 : 1 : valent_share_dialog_row_dispose (GObject *object)
96 : : {
97 : 1 : ValentShareDialogRow *self = VALENT_SHARE_DIALOG_ROW (object);
98 : :
99 [ + - ]: 1 : if (self->animation != NULL)
100 : : {
101 : 1 : adw_animation_skip (self->animation);
102 [ + - ]: 1 : g_clear_object (&self->animation);
103 : : }
104 : :
105 [ + - ]: 1 : g_clear_object (&self->device);
106 : 1 : gtk_widget_dispose_template (GTK_WIDGET (self), VALENT_TYPE_SHARE_DIALOG_ROW);
107 : :
108 : 1 : G_OBJECT_CLASS (valent_share_dialog_row_parent_class)->dispose (object);
109 : 1 : }
110 : :
111 : : static void
112 : 1 : valent_share_dialog_row_get_property (GObject *object,
113 : : guint prop_id,
114 : : GValue *value,
115 : : GParamSpec *pspec)
116 : : {
117 : 1 : ValentShareDialogRow *self = VALENT_SHARE_DIALOG_ROW (object);
118 : :
119 [ - - + - ]: 1 : switch (prop_id)
120 : : {
121 : 0 : case PROP_DEVICE:
122 : 0 : g_value_set_object (value, self->device);
123 : 0 : break;
124 : :
125 : 0 : case PROP_SELECTED:
126 : 0 : g_value_set_boolean (value, self->selected);
127 : 0 : break;
128 : :
129 : 1 : case PROP_SELECTION_MODE:
130 : 1 : g_value_set_boolean (value, self->selection_mode);
131 : 1 : break;
132 : :
133 : 0 : default:
134 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
135 : : }
136 : 1 : }
137 : :
138 : : static void
139 : 4 : valent_share_dialog_row_set_property (GObject *object,
140 : : guint prop_id,
141 : : const GValue *value,
142 : : GParamSpec *pspec)
143 : : {
144 : 4 : ValentShareDialogRow *self = VALENT_SHARE_DIALOG_ROW (object);
145 : :
146 [ + + + - ]: 4 : switch (prop_id)
147 : : {
148 : 1 : case PROP_DEVICE:
149 : 1 : valent_share_dialog_row_set_device (self, g_value_get_object (value));
150 : 1 : break;
151 : :
152 : 1 : case PROP_SELECTED:
153 : 1 : valent_share_dialog_row_set_selected (self, g_value_get_boolean (value));
154 : 1 : break;
155 : :
156 : 2 : case PROP_SELECTION_MODE:
157 : 2 : valent_share_dialog_row_set_selection_mode (self, g_value_get_boolean (value));
158 : 2 : break;
159 : :
160 : 0 : default:
161 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
162 : : }
163 : 4 : }
164 : :
165 : : static void
166 : 1 : valent_share_dialog_row_class_init (ValentShareDialogRowClass *klass)
167 : : {
168 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
169 : 1 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
170 : :
171 : 1 : object_class->dispose = valent_share_dialog_row_dispose;
172 : 1 : object_class->get_property = valent_share_dialog_row_get_property;
173 : 1 : object_class->set_property = valent_share_dialog_row_set_property;
174 : :
175 : : /**
176 : : * ValentShareDialogRow:device: (getter get_device)
177 : : *
178 : : * The [class@Valent.Device] this row displays.
179 : : */
180 : 2 : properties [PROP_DEVICE] =
181 : 1 : g_param_spec_object ("device", NULL, NULL,
182 : : VALENT_TYPE_DEVICE,
183 : : (G_PARAM_READWRITE |
184 : : G_PARAM_EXPLICIT_NOTIFY |
185 : : G_PARAM_STATIC_STRINGS));
186 : :
187 : : /**
188 : : * ValentShareDialogRow:selected: (getter get_selected) (setter set_selected)
189 : : *
190 : : * Whether the row is selected.
191 : : */
192 : 2 : properties [PROP_SELECTED] =
193 : 1 : g_param_spec_boolean ("selected", NULL, NULL,
194 : : FALSE,
195 : : (G_PARAM_READWRITE |
196 : : G_PARAM_EXPLICIT_NOTIFY |
197 : : G_PARAM_STATIC_STRINGS));
198 : :
199 : : /**
200 : : * ValentShareDialogRow:selection-mode: (getter get_selection_mode) (setter set_selection_mode)
201 : : *
202 : : * Whether the row is in selection mode.
203 : : */
204 : 2 : properties [PROP_SELECTION_MODE] =
205 : 1 : g_param_spec_boolean ("selection-mode", NULL, NULL,
206 : : FALSE,
207 : : (G_PARAM_READWRITE |
208 : : G_PARAM_CONSTRUCT |
209 : : G_PARAM_EXPLICIT_NOTIFY |
210 : : G_PARAM_STATIC_STRINGS));
211 : :
212 : 1 : g_object_class_install_properties (object_class, N_PROPERTIES, properties);
213 : :
214 : 1 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/share/valent-share-dialog-row.ui");
215 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, revealer);
216 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, selected_button);
217 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, icon_image);
218 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, name_label);
219 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, next_image);
220 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_selection_enable);
221 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_selection_disable);
222 : 1 : }
223 : :
224 : : static void
225 : 1 : valent_share_dialog_row_init (ValentShareDialogRow *self)
226 : : {
227 : 1 : AdwAnimationTarget *target = NULL;
228 : :
229 : 1 : gtk_widget_init_template (GTK_WIDGET (self));
230 : :
231 : 1 : target = adw_property_animation_target_new (G_OBJECT (self->next_image),
232 : : "opacity");
233 : 1 : self->animation = adw_timed_animation_new (GTK_WIDGET (self),
234 : : 0.0, 1.0, 250,
235 : : target);
236 : 1 : }
237 : :
238 : : /**
239 : : * valent_share_dialog_row_get_device: (set-property device)
240 : : * @row: a `ValentShareDialogRow`
241 : : *
242 : : * Get the device.
243 : : *
244 : : * Returns: (transfer none) (nullable): a `ValentDevice`
245 : : */
246 : : ValentDevice *
247 : 0 : valent_share_dialog_row_get_device (ValentShareDialogRow *row)
248 : : {
249 [ # # ]: 0 : g_return_val_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row), NULL);
250 : :
251 : 0 : return row->device;
252 : : }
253 : :
254 : : /**
255 : : * valent_share_dialog_row_get_selected: (get-property selected)
256 : : * @row: a `ValentShareDialogRow`
257 : : *
258 : : * Get whether the row is selected.
259 : : *
260 : : * Returns: %TRUE if the row is selected, or %FALSE if not
261 : : */
262 : : gboolean
263 : 0 : valent_share_dialog_row_get_selected (ValentShareDialogRow *row)
264 : : {
265 [ # # ]: 0 : g_return_val_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row), FALSE);
266 : :
267 : 0 : return row->selected;
268 : : }
269 : :
270 : : /**
271 : : * valent_share_dialog_row_set_selected: (set-property selected)
272 : : * @row: a `ValentShareDialogRow`
273 : : * @selected: whether to select the row
274 : : *
275 : : * Set whether the row is selected.
276 : : */
277 : : void
278 : 1 : valent_share_dialog_row_set_selected (ValentShareDialogRow *row,
279 : : gboolean selected)
280 : : {
281 [ + - ]: 1 : g_return_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row));
282 : :
283 : 1 : selected = !!selected;
284 [ - + ]: 1 : if (row->selected == selected)
285 : : return;
286 : :
287 : 0 : gtk_accessible_update_state (GTK_ACCESSIBLE (row),
288 : : GTK_ACCESSIBLE_STATE_SELECTED, selected,
289 : : -1);
290 : :
291 : 0 : row->selected = selected;
292 : 0 : g_object_notify_by_pspec (G_OBJECT (row), properties [PROP_SELECTED]);
293 : : }
294 : :
295 : : /**
296 : : * valent_share_dialog_row_get_selection_mode:
297 : : * @row: a `ValentShareDialogRow`
298 : : *
299 : : * Get whether selection mode is enabled.
300 : : *
301 : : * Returns: %TRUE if selection mode is enabled, or %FALSE if not
302 : : */
303 : : gboolean
304 : 0 : valent_share_dialog_row_get_selection_mode (ValentShareDialogRow *row)
305 : : {
306 [ # # ]: 0 : g_return_val_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row), FALSE);
307 : :
308 : 0 : return row->selection_mode;
309 : : }
310 : :
311 : : /**
312 : : * valent_share_dialog_row_set_selection_mode: (set-property selection-mode)
313 : : * @row: a `ValentShareDialogRow`
314 : : * @selection_mode: whether to select the row
315 : : *
316 : : * Set whether selection mode is enabled.
317 : : */
318 : : void
319 : 2 : valent_share_dialog_row_set_selection_mode (ValentShareDialogRow *row,
320 : : gboolean selection_mode)
321 : : {
322 [ + - ]: 2 : g_return_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row));
323 : :
324 : 2 : selection_mode = !!selection_mode;
325 [ - + ]: 2 : if (row->selection_mode == selection_mode)
326 : : return;
327 : :
328 [ # # ]: 0 : if (selection_mode)
329 : : {
330 : 0 : gtk_accessible_update_state (GTK_ACCESSIBLE (row),
331 : : GTK_ACCESSIBLE_STATE_SELECTED, FALSE,
332 : : -1);
333 : : }
334 : : else
335 : : {
336 : 0 : gtk_accessible_reset_state (GTK_ACCESSIBLE (row),
337 : : GTK_ACCESSIBLE_STATE_SELECTED);
338 : : }
339 : :
340 : 0 : adw_animation_skip (row->animation);
341 : 0 : adw_timed_animation_set_reverse (ADW_TIMED_ANIMATION (row->animation),
342 : : selection_mode);
343 : 0 : adw_animation_play (row->animation);
344 : :
345 : 0 : row->selection_mode = selection_mode;
346 : 0 : g_object_notify_by_pspec (G_OBJECT (row), properties [PROP_SELECTION_MODE]);
347 : : }
348 : :
|