hdy-preferences-page.c 9.82 KB
Newer Older
Adrien Plazas's avatar
Adrien Plazas committed
1
2
3
/*
 * Copyright (C) 2019 Purism SPC
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
Adrien Plazas's avatar
Adrien Plazas committed
5
6
7
8
9
10
11
12
13
14
 */

#include "config.h"
#include <glib/gi18n-lib.h>

#include "hdy-preferences-page-private.h"

#include "hdy-preferences-group-private.h"

/**
15
 * HdyPreferencesPage:
Adrien Plazas's avatar
Adrien Plazas committed
16
 *
17
18
19
 * A page from [class@PreferencesWindow].
 *
 * The `HdyPreferencesPage` widget gathers preferences groups into a single page
Adrien Plazas's avatar
Adrien Plazas committed
20
21
 * of a preferences window.
 *
22
 * ## CSS nodes
23
 *
24
 * `HdyPreferencesPage` has a single CSS node with name `preferencespage`.
25
 *
26
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
27
28
29
30
31
 */

typedef struct
{
  GtkBox *box;
32
  GtkScrolledWindow *scrolled_window;
Adrien Plazas's avatar
Adrien Plazas committed
33
34
35
36
37

  gchar *icon_name;
  gchar *title;
} HdyPreferencesPagePrivate;

38
G_DEFINE_TYPE_WITH_PRIVATE (HdyPreferencesPage, hdy_preferences_page, GTK_TYPE_BIN)
Adrien Plazas's avatar
Adrien Plazas committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

enum {
  PROP_0,
  PROP_ICON_NAME,
  PROP_TITLE,
  LAST_PROP,
};

static GParamSpec *props[LAST_PROP];

static void
hdy_preferences_page_get_property (GObject    *object,
                                   guint       prop_id,
                                   GValue     *value,
                                   GParamSpec *pspec)
{
  HdyPreferencesPage *self = HDY_PREFERENCES_PAGE (object);

  switch (prop_id) {
  case PROP_ICON_NAME:
    g_value_set_string (value, hdy_preferences_page_get_icon_name (self));
    break;
  case PROP_TITLE:
    g_value_set_string (value, hdy_preferences_page_get_title (self));
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}

static void
hdy_preferences_page_set_property (GObject      *object,
                                   guint         prop_id,
                                   const GValue *value,
                                   GParamSpec   *pspec)
{
  HdyPreferencesPage *self = HDY_PREFERENCES_PAGE (object);

  switch (prop_id) {
  case PROP_ICON_NAME:
    hdy_preferences_page_set_icon_name (self, g_value_get_string (value));
    break;
  case PROP_TITLE:
    hdy_preferences_page_set_title (self, g_value_get_string (value));
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}

static void
hdy_preferences_page_finalize (GObject *object)
{
  HdyPreferencesPage *self = HDY_PREFERENCES_PAGE (object);
  HdyPreferencesPagePrivate *priv = hdy_preferences_page_get_instance_private (self);

  g_clear_pointer (&priv->icon_name, g_free);
  g_clear_pointer (&priv->title, g_free);

  G_OBJECT_CLASS (hdy_preferences_page_parent_class)->finalize (object);
}

static void
hdy_preferences_page_add (GtkContainer *container,
                          GtkWidget    *child)
{
  HdyPreferencesPage *self = HDY_PREFERENCES_PAGE (container);
  HdyPreferencesPagePrivate *priv = hdy_preferences_page_get_instance_private (self);

108
  if (priv->scrolled_window == NULL)
Adrien Plazas's avatar
Adrien Plazas committed
109
110
111
112
113
114
115
116
117
    GTK_CONTAINER_CLASS (hdy_preferences_page_parent_class)->add (container, child);
  else if (HDY_IS_PREFERENCES_GROUP (child))
    gtk_container_add (GTK_CONTAINER (priv->box), child);
  else
    g_warning ("Can't add children of type %s to %s",
               G_OBJECT_TYPE_NAME (child),
               G_OBJECT_TYPE_NAME (container));
}

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
static void
hdy_preferences_page_remove (GtkContainer *container,
                             GtkWidget    *child)
{
  HdyPreferencesPage *self = HDY_PREFERENCES_PAGE (container);
  HdyPreferencesPagePrivate *priv = hdy_preferences_page_get_instance_private (self);

  if (child == GTK_WIDGET (priv->scrolled_window))
    GTK_CONTAINER_CLASS (hdy_preferences_page_parent_class)->remove (container, child);
  else
    gtk_container_remove (GTK_CONTAINER (priv->box), child);
}

static void
hdy_preferences_page_forall (GtkContainer *container,
                             gboolean      include_internals,
                             GtkCallback   callback,
                             gpointer      callback_data)
{
  HdyPreferencesPage *self = HDY_PREFERENCES_PAGE (container);
  HdyPreferencesPagePrivate *priv = hdy_preferences_page_get_instance_private (self);

  if (include_internals)
    GTK_CONTAINER_CLASS (hdy_preferences_page_parent_class)->forall (container,
                                                                     include_internals,
                                                                     callback,
                                                                     callback_data);
  else if (priv->box)
    gtk_container_foreach (GTK_CONTAINER (priv->box), callback, callback_data);
}

Adrien Plazas's avatar
Adrien Plazas committed
149
150
151
152
153
154
155
156
157
158
159
160
static void
hdy_preferences_page_class_init (HdyPreferencesPageClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);

  object_class->get_property = hdy_preferences_page_get_property;
  object_class->set_property = hdy_preferences_page_set_property;
  object_class->finalize = hdy_preferences_page_finalize;

  container_class->add = hdy_preferences_page_add;
161
162
  container_class->remove = hdy_preferences_page_remove;
  container_class->forall = hdy_preferences_page_forall;
Adrien Plazas's avatar
Adrien Plazas committed
163
164

  /**
165
   * HdyPreferencesPage:icon-name: (attributes org.gtk.Property.get=hdy_preferences_page_get_icon_name org.gtk.Property.set=hdy_preferences_page_set_icon_name)
Adrien Plazas's avatar
Adrien Plazas committed
166
167
168
   *
   * The icon name for this page of preferences.
   *
169
   * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
170
171
172
173
174
175
176
177
178
   */
  props[PROP_ICON_NAME] =
    g_param_spec_string ("icon-name",
                         _("Icon name"),
                         _("Icon name"),
                         "",
                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);

  /**
179
   * HdyPreferencesPage:title: (attributes org.gtk.Property.get=hdy_preferences_page_get_title org.gtk.Property.set=hdy_preferences_page_set_title)
Adrien Plazas's avatar
Adrien Plazas committed
180
181
182
   *
   * The title for this page of preferences.
   *
183
   * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
184
185
186
187
188
189
190
191
192
193
194
195
196
   */
  props[PROP_TITLE] =
    g_param_spec_string ("title",
                         _("Title"),
                         _("Title"),
                         "",
                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);

  g_object_class_install_properties (object_class, LAST_PROP, props);

  gtk_widget_class_set_template_from_resource (widget_class,
                                               "/sm/puri/handy/ui/hdy-preferences-page.ui");
  gtk_widget_class_bind_template_child_private (widget_class, HdyPreferencesPage, box);
197
  gtk_widget_class_bind_template_child_private (widget_class, HdyPreferencesPage, scrolled_window);
Adrien Plazas's avatar
Adrien Plazas committed
198

199
  gtk_widget_class_set_css_name (widget_class, "preferencespage");
Adrien Plazas's avatar
Adrien Plazas committed
200
201
202
203
204
205
206
207
208
209
210
}

static void
hdy_preferences_page_init (HdyPreferencesPage *self)
{
  gtk_widget_init_template (GTK_WIDGET (self));
}

/**
 * hdy_preferences_page_new:
 *
211
 * Creates a new `HdyPreferencesPage`.
Adrien Plazas's avatar
Adrien Plazas committed
212
 *
213
 * Returns: the newly created `HdyPreferencesPage`
Adrien Plazas's avatar
Adrien Plazas committed
214
 *
215
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
216
 */
Ujjwal Kumar's avatar
Ujjwal Kumar committed
217
GtkWidget *
Adrien Plazas's avatar
Adrien Plazas committed
218
219
220
221
222
223
hdy_preferences_page_new (void)
{
  return g_object_new (HDY_TYPE_PREFERENCES_PAGE, NULL);
}

/**
224
225
 * hdy_preferences_page_get_icon_name: (attributes org.gtk.Method.get_property=icon-name)
 * @self: a preferences page
Adrien Plazas's avatar
Adrien Plazas committed
226
 *
227
 * Gets the icon name for @self.
Adrien Plazas's avatar
Adrien Plazas committed
228
 *
229
 * Returns: (transfer none) (nullable): the icon name for @self
Adrien Plazas's avatar
Adrien Plazas committed
230
 *
231
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
 */
const gchar *
hdy_preferences_page_get_icon_name (HdyPreferencesPage *self)
{
  HdyPreferencesPagePrivate *priv;

  g_return_val_if_fail (HDY_IS_PREFERENCES_PAGE (self), NULL);

  priv = hdy_preferences_page_get_instance_private (self);

  return priv->icon_name;
}

/**
246
247
248
 * hdy_preferences_page_set_icon_name: (attributes org.gtk.Method.set_property=icon-name)
 * @self: a preferences page
 * @icon_name: (nullable): the icon name
Adrien Plazas's avatar
Adrien Plazas committed
249
250
251
 *
 * Sets the icon name for @self.
 *
252
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
 */
void
hdy_preferences_page_set_icon_name (HdyPreferencesPage *self,
                                    const gchar        *icon_name)
{
  HdyPreferencesPagePrivate *priv;

  g_return_if_fail (HDY_IS_PREFERENCES_PAGE (self));

  priv = hdy_preferences_page_get_instance_private (self);

  if (g_strcmp0 (priv->icon_name, icon_name) == 0)
    return;

  g_clear_pointer (&priv->icon_name, g_free);
  priv->icon_name = g_strdup (icon_name);

  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
}

/**
274
275
 * hdy_preferences_page_get_title: (attributes org.gtk.Method.get_property=title)
 * @self: a preferences page
Adrien Plazas's avatar
Adrien Plazas committed
276
 *
277
 * Gets the title of @self.
Adrien Plazas's avatar
Adrien Plazas committed
278
 *
279
 * Returns: (transfer none) (nullable): the title of the @self
Adrien Plazas's avatar
Adrien Plazas committed
280
 *
281
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
282
283
284
285
286
287
288
289
290
291
292
293
294
295
 */
const gchar *
hdy_preferences_page_get_title (HdyPreferencesPage *self)
{
  HdyPreferencesPagePrivate *priv;

  g_return_val_if_fail (HDY_IS_PREFERENCES_PAGE (self), NULL);

  priv = hdy_preferences_page_get_instance_private (self);

  return priv->title;
}

/**
296
297
298
 * hdy_preferences_page_set_title: (attributes org.gtk.Method.set_property=title)
 * @self: a preferences page
 * @title: (nullable): the title of the page
Adrien Plazas's avatar
Adrien Plazas committed
299
300
301
 *
 * Sets the title of @self.
 *
302
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
 */
void
hdy_preferences_page_set_title (HdyPreferencesPage *self,
                                const gchar        *title)
{
  HdyPreferencesPagePrivate *priv;

  g_return_if_fail (HDY_IS_PREFERENCES_PAGE (self));

  priv = hdy_preferences_page_get_instance_private (self);

  if (g_strcmp0 (priv->title, title) == 0)
    return;

  g_clear_pointer (&priv->title, g_free);
  priv->title = g_strdup (title);

  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TITLE]);
}

323
324
325
/*< private >
 * hdy_preferences_page_add_preferences_to_model:
 * @self: a preferences page
Adrien Plazas's avatar
Adrien Plazas committed
326
327
328
329
 * @model: the model
 *
 * Add preferences from @self to the model.
 *
330
 * Since: 1.0
Adrien Plazas's avatar
Adrien Plazas committed
331
332
333
334
335
336
337
338
339
340
 */
void
hdy_preferences_page_add_preferences_to_model (HdyPreferencesPage *self,
                                               GListStore         *model)
{
  HdyPreferencesPagePrivate *priv;

  g_return_if_fail (HDY_IS_PREFERENCES_PAGE (self));
  g_return_if_fail (G_IS_LIST_STORE (model));

341
342
343
  if (!gtk_widget_get_visible (GTK_WIDGET (self)))
    return;

Adrien Plazas's avatar
Adrien Plazas committed
344
345
346
347
  priv = hdy_preferences_page_get_instance_private (self);

  gtk_container_foreach (GTK_CONTAINER (priv->box), (GtkCallback) hdy_preferences_group_add_preferences_to_model, model);
}