[gnome-builder] libide/tweaks: add support for combo selections



commit 3f4d8c30d7e45ed158d608bfc39fd796f717e558
Author: Christian Hergert <chergert redhat com>
Date:   Fri Aug 12 23:13:21 2022 -0700

    libide/tweaks: add support for combo selections

 src/libide/tweaks/ide-tweaks-choice.c         | 211 ++++++++++++++++++
 src/libide/tweaks/ide-tweaks-choice.h         |  54 +++++
 src/libide/tweaks/ide-tweaks-combo-row.c      | 169 ++++++++++++++
 src/libide/tweaks/ide-tweaks-combo-row.h      |  31 +++
 src/libide/tweaks/ide-tweaks-combo-row.ui     |  52 +++++
 src/libide/tweaks/ide-tweaks-combo.c          | 310 ++++++++++++++++++++++++++
 src/libide/tweaks/ide-tweaks-combo.h          |  60 +++++
 src/libide/tweaks/ide-tweaks-init.c           |   2 +
 src/libide/tweaks/libide-tweaks.gresource.xml |   1 +
 src/libide/tweaks/libide-tweaks.h             |   2 +
 src/libide/tweaks/meson.build                 |   5 +
 11 files changed, 897 insertions(+)
---
diff --git a/src/libide/tweaks/ide-tweaks-choice.c b/src/libide/tweaks/ide-tweaks-choice.c
new file mode 100644
index 000000000..b43fba338
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-choice.c
@@ -0,0 +1,211 @@
+/* ide-tweaks-choice.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-tweaks-choice"
+
+#include "config.h"
+
+#include "ide-tweaks-choice.h"
+
+struct _IdeTweaksChoice
+{
+  IdeTweaksItem parent_instance;
+  char *title;
+  char *subtitle;
+  GVariant *action_target;
+};
+
+enum {
+  PROP_0,
+  PROP_ACTION_TARGET,
+  PROP_SUBTITLE,
+  PROP_TITLE,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (IdeTweaksChoice, ide_tweaks_choice, IDE_TYPE_TWEAKS_ITEM)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_tweaks_choice_dispose (GObject *object)
+{
+  IdeTweaksChoice *self = (IdeTweaksChoice *)object;
+
+  g_clear_pointer (&self->title, g_free);
+  g_clear_pointer (&self->subtitle, g_free);
+  g_clear_pointer (&self->action_target, g_variant_unref);
+
+  G_OBJECT_CLASS (ide_tweaks_choice_parent_class)->dispose (object);
+}
+
+static void
+ide_tweaks_choice_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  IdeTweaksChoice *self = IDE_TWEAKS_CHOICE (object);
+
+  switch (prop_id)
+    {
+    case PROP_TITLE:
+      g_value_set_string (value, ide_tweaks_choice_get_title (self));
+      break;
+
+    case PROP_SUBTITLE:
+      g_value_set_string (value, ide_tweaks_choice_get_subtitle (self));
+      break;
+
+    case PROP_ACTION_TARGET:
+      g_value_set_variant (value, ide_tweaks_choice_get_action_target (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_choice_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  IdeTweaksChoice *self = IDE_TWEAKS_CHOICE (object);
+
+  switch (prop_id)
+    {
+    case PROP_TITLE:
+      ide_tweaks_choice_set_title (self, g_value_get_string (value));
+      break;
+
+    case PROP_SUBTITLE:
+      ide_tweaks_choice_set_subtitle (self, g_value_get_string (value));
+      break;
+
+    case PROP_ACTION_TARGET:
+      ide_tweaks_choice_set_action_target (self, g_value_get_variant (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_choice_class_init (IdeTweaksChoiceClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = ide_tweaks_choice_dispose;
+  object_class->get_property = ide_tweaks_choice_get_property;
+  object_class->set_property = ide_tweaks_choice_set_property;
+
+  properties[PROP_TITLE] =
+    g_param_spec_string ("title", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_SUBTITLE] =
+    g_param_spec_string ("subtitle", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_ACTION_TARGET] =
+    g_param_spec_variant ("action-target", NULL, NULL,
+                          G_VARIANT_TYPE_ANY,
+                          NULL,
+                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_tweaks_choice_init (IdeTweaksChoice *self)
+{
+}
+
+const char *
+ide_tweaks_choice_get_title (IdeTweaksChoice *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_CHOICE (self), NULL);
+
+  return self->title;
+}
+
+const char *
+ide_tweaks_choice_get_subtitle (IdeTweaksChoice *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_CHOICE (self), NULL);
+
+  return self->subtitle;
+}
+
+/**
+ * ide_tweaks_choice_get_action_target:
+ * @self: a #IdeTweaksChoice
+ *
+ * Returns: (transfer none) (nullable): A #GVariant or %NULL
+ */
+GVariant *
+ide_tweaks_choice_get_action_target (IdeTweaksChoice *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_CHOICE (self), NULL);
+
+  return self->action_target;
+}
+
+void
+ide_tweaks_choice_set_action_target (IdeTweaksChoice *self,
+                                     GVariant        *action_target)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_CHOICE (self));
+
+  if (action_target == self->action_target)
+    return;
+
+  if (action_target != NULL)
+    g_variant_ref (action_target);
+
+  g_clear_pointer (&self->action_target, g_variant_unref);
+  self->action_target = action_target;
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ACTION_TARGET]);
+}
+
+void
+ide_tweaks_choice_set_title (IdeTweaksChoice *self,
+                             const char      *title)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_CHOICE (self));
+
+  if (ide_set_string (&self->title, title))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
+}
+
+void
+ide_tweaks_choice_set_subtitle (IdeTweaksChoice *self,
+                                const char      *subtitle)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_CHOICE (self));
+
+  if (ide_set_string (&self->subtitle, subtitle))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SUBTITLE]);
+}
diff --git a/src/libide/tweaks/ide-tweaks-choice.h b/src/libide/tweaks/ide-tweaks-choice.h
new file mode 100644
index 000000000..b1cafb003
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-choice.h
@@ -0,0 +1,54 @@
+/* ide-tweaks-choice.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#if !defined (IDE_TWEAKS_INSIDE) && !defined (IDE_TWEAKS_COMPILATION)
+# error "Only <libide-tweaks.h> can be included directly."
+#endif
+
+#include "ide-tweaks-item.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_TWEAKS_CHOICE (ide_tweaks_choice_get_type())
+
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdeTweaksChoice, ide_tweaks_choice, IDE, TWEAKS_CHOICE, IdeTweaksItem)
+
+IDE_AVAILABLE_IN_ALL
+IdeTweaksChoice *ide_tweaks_choice_new               (void);
+IDE_AVAILABLE_IN_ALL
+const char      *ide_tweaks_choice_get_title         (IdeTweaksChoice *self);
+IDE_AVAILABLE_IN_ALL
+void             ide_tweaks_choice_set_title         (IdeTweaksChoice *self,
+                                                      const char      *title);
+IDE_AVAILABLE_IN_ALL
+const char      *ide_tweaks_choice_get_subtitle      (IdeTweaksChoice *self);
+IDE_AVAILABLE_IN_ALL
+void             ide_tweaks_choice_set_subtitle      (IdeTweaksChoice *self,
+                                                      const char      *subtitle);
+IDE_AVAILABLE_IN_ALL
+GVariant        *ide_tweaks_choice_get_action_target (IdeTweaksChoice *self);
+IDE_AVAILABLE_IN_ALL
+void             ide_tweaks_choice_set_action_target (IdeTweaksChoice *self,
+                                                      GVariant        *action_target);
+
+G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-combo-row.c b/src/libide/tweaks/ide-tweaks-combo-row.c
new file mode 100644
index 000000000..03f0aebe8
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-combo-row.c
@@ -0,0 +1,169 @@
+/* ide-tweaks-combo-row.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-tweaks-combo-row"
+
+#include "config.h"
+
+#include <libide-core.h>
+
+#include "ide-tweaks-choice.h"
+#include "ide-tweaks-combo-row.h"
+#include "ide-tweaks-settings.h"
+
+struct _IdeTweaksComboRow
+{
+  AdwComboRow parent_instance;
+  IdeSettings *settings;
+  char *key;
+};
+
+G_DEFINE_FINAL_TYPE (IdeTweaksComboRow, ide_tweaks_combo_row, ADW_TYPE_COMBO_ROW)
+
+enum {
+  PROP_0,
+  PROP_KEY,
+  PROP_SETTINGS,
+  N_PROPS
+};
+
+static GParamSpec *properties[N_PROPS];
+
+static void
+ide_tweaks_combo_row_notify_selected_item (IdeTweaksComboRow *self,
+                                           GParamSpec        *pspec)
+{
+  IdeTweaksChoice *choice;
+
+  g_assert (IDE_IS_TWEAKS_COMBO_ROW (self));
+  g_assert (self->settings != NULL);
+  g_assert (self->key != NULL);
+
+  if ((choice = adw_combo_row_get_selected_item (ADW_COMBO_ROW (self))))
+    {
+      GVariant *action_target = ide_tweaks_choice_get_action_target (choice);
+
+      ide_settings_set_value (self->settings, self->key, action_target);
+    }
+}
+
+static void
+ide_tweaks_combo_row_constructed (GObject *object)
+{
+  IdeTweaksComboRow *self = (IdeTweaksComboRow *)object;
+
+  G_OBJECT_CLASS (ide_tweaks_combo_row_parent_class)->constructed (object);
+
+  g_signal_connect (self,
+                    "notify::selected-item",
+                    G_CALLBACK (ide_tweaks_combo_row_notify_selected_item),
+                    NULL);
+}
+
+static void
+ide_tweaks_combo_row_dispose (GObject *object)
+{
+  IdeTweaksComboRow *self = (IdeTweaksComboRow *)object;
+
+  g_clear_object (&self->settings);
+  g_clear_pointer (&self->key, g_free);
+
+  G_OBJECT_CLASS (ide_tweaks_combo_row_parent_class)->dispose (object);
+}
+
+static void
+ide_tweaks_combo_row_get_property (GObject    *object,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  IdeTweaksComboRow *self = IDE_TWEAKS_COMBO_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_KEY:
+      g_value_set_string (value, self->key);
+      break;
+
+    case PROP_SETTINGS:
+      g_value_set_object (value, self->settings);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_combo_row_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  IdeTweaksComboRow *self = IDE_TWEAKS_COMBO_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_KEY:
+      if (ide_set_string (&self->key, g_value_get_string (value)))
+        g_object_notify_by_pspec (object, pspec);
+      break;
+
+    case PROP_SETTINGS:
+      if (g_set_object (&self->settings, g_value_get_object (value)))
+        g_object_notify_by_pspec (object, pspec);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_combo_row_class_init (IdeTweaksComboRowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->constructed = ide_tweaks_combo_row_constructed;
+  object_class->dispose = ide_tweaks_combo_row_dispose;
+  object_class->get_property = ide_tweaks_combo_row_get_property;
+  object_class->set_property = ide_tweaks_combo_row_set_property;
+
+  properties[PROP_KEY] =
+    g_param_spec_string ("key", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_SETTINGS] =
+    g_param_spec_object ("settings", NULL, NULL,
+                         IDE_TYPE_SETTINGS,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/libide-tweaks/ide-tweaks-combo-row.ui");
+}
+
+static void
+ide_tweaks_combo_row_init (IdeTweaksComboRow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/src/libide/tweaks/ide-tweaks-combo-row.h b/src/libide/tweaks/ide-tweaks-combo-row.h
new file mode 100644
index 000000000..c75913dd5
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-combo-row.h
@@ -0,0 +1,31 @@
+/* ide-tweaks-combo-row.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <adwaita.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_TWEAKS_COMBO_ROW (ide_tweaks_combo_row_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeTweaksComboRow, ide_tweaks_combo_row, IDE, TWEAKS_COMBO_ROW, AdwComboRow)
+
+G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-combo-row.ui b/src/libide/tweaks/ide-tweaks-combo-row.ui
new file mode 100644
index 000000000..e29b46221
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-combo-row.ui
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="IdeTweaksComboRow" parent="AdwComboRow">
+    <property name="expression">
+      <lookup name="title" type="IdeTweaksChoice"/>
+    </property>
+    <property name="list-factory">
+      <object class="GtkBuilderListItemFactory">
+        <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <property name="child">
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="xalign">0</property>
+            <property name="hexpand">true</property>
+            <binding name="label">
+              <lookup name="title" type="IdeTweaksChoice">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="xalign">0</property>
+            <property name="hexpand">true</property>
+            <property name="visible">false</property>
+            <style>
+              <class name="caption"/>
+              <class name="dim-label"/>
+            </style>
+            <binding name="label">
+              <lookup name="subtitle" type="IdeTweaksChoice">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+      </object>
+    </property>
+  </template>
+</interface>
+]]>
+        </property>
+      </object>
+    </property>
+  </template>
+</interface>
diff --git a/src/libide/tweaks/ide-tweaks-combo.c b/src/libide/tweaks/ide-tweaks-combo.c
new file mode 100644
index 000000000..3026f912b
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-combo.c
@@ -0,0 +1,310 @@
+/* ide-tweaks-combo.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-tweaks-combo"
+
+#include "config.h"
+
+#include <adwaita.h>
+
+#include "ide-tweaks.h"
+#include "ide-tweaks-choice.h"
+#include "ide-tweaks-combo.h"
+#include "ide-tweaks-combo-row.h"
+
+struct _IdeTweaksCombo
+{
+  IdeTweaksWidget parent_instance;
+  IdeTweaksSettings *settings;
+  char *title;
+  char *subtitle;
+  char *key;
+};
+
+enum {
+  PROP_0,
+  PROP_KEY,
+  PROP_SETTINGS,
+  PROP_TITLE,
+  PROP_SUBTITLE,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (IdeTweaksCombo, ide_tweaks_combo, IDE_TYPE_TWEAKS_WIDGET)
+
+static GParamSpec *properties [N_PROPS];
+
+static GtkWidget *
+ide_tweaks_combo_create (IdeTweaksWidget *widget)
+{
+  IdeTweaksCombo *self = (IdeTweaksCombo *)widget;
+  g_autoptr(IdeSettings) settings = NULL;
+  g_autoptr(GListStore) store = NULL;
+  g_autoptr(GVariant) value = NULL;
+  IdeTweaksItem *root;
+  AdwComboRow *row;
+  const char *project_id;
+  int selected = -1;
+  guint i = 0;
+
+  g_assert (IDE_IS_TWEAKS_COMBO (self));
+
+  root = ide_tweaks_item_get_root (IDE_TWEAKS_ITEM (widget));
+  project_id = ide_tweaks_get_project_id (IDE_TWEAKS (root));
+  settings = IDE_SETTINGS (ide_tweaks_settings_create_action_group (self->settings, project_id));
+
+  store = g_list_store_new (IDE_TYPE_TWEAKS_CHOICE);
+  value = ide_settings_get_value (settings, self->key);
+
+  for (IdeTweaksItem *child = ide_tweaks_item_get_first_child (IDE_TWEAKS_ITEM (self));
+       child != NULL;
+       child = ide_tweaks_item_get_next_sibling (child))
+    {
+      GVariant *target = ide_tweaks_choice_get_action_target (IDE_TWEAKS_CHOICE (child));
+
+      if (g_variant_equal (value, target))
+        selected = i;
+
+      g_list_store_append (store, child);
+      i++;
+    }
+
+  row = g_object_new (IDE_TYPE_TWEAKS_COMBO_ROW,
+                      "model", store,
+                      "settings", settings,
+                      "key", self->key,
+                      "title", self->title,
+                      "subtitle", self->subtitle,
+                      "selected", selected > -1 ? selected : 0,
+                      NULL);
+
+  return GTK_WIDGET (row);
+}
+
+static gboolean
+ide_tweaks_combo_accepts (IdeTweaksItem *item,
+                          IdeTweaksItem *child)
+{
+  return IDE_IS_TWEAKS_CHOICE (child);
+}
+
+static void
+ide_tweaks_combo_dispose (GObject *object)
+{
+  IdeTweaksCombo *self = (IdeTweaksCombo *)object;
+
+  g_clear_object (&self->settings);
+  g_clear_pointer (&self->title, g_free);
+  g_clear_pointer (&self->subtitle, g_free);
+
+  G_OBJECT_CLASS (ide_tweaks_combo_parent_class)->dispose (object);
+}
+
+static void
+ide_tweaks_combo_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  IdeTweaksCombo *self = IDE_TWEAKS_COMBO (object);
+
+  switch (prop_id)
+    {
+    case PROP_SETTINGS:
+      g_value_set_object (value, ide_tweaks_combo_get_settings (self));
+      break;
+
+    case PROP_TITLE:
+      g_value_set_string (value, ide_tweaks_combo_get_title (self));
+      break;
+
+    case PROP_SUBTITLE:
+      g_value_set_string (value, ide_tweaks_combo_get_subtitle (self));
+      break;
+
+    case PROP_KEY:
+      g_value_set_string (value, ide_tweaks_combo_get_key (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_combo_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  IdeTweaksCombo *self = IDE_TWEAKS_COMBO (object);
+
+  switch (prop_id)
+    {
+    case PROP_SETTINGS:
+      ide_tweaks_combo_set_settings (self, g_value_get_object (value));
+      break;
+
+    case PROP_TITLE:
+      ide_tweaks_combo_set_title (self, g_value_get_string (value));
+      break;
+
+    case PROP_SUBTITLE:
+      ide_tweaks_combo_set_subtitle (self, g_value_get_string (value));
+      break;
+
+    case PROP_KEY:
+      ide_tweaks_combo_set_key (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_combo_class_init (IdeTweaksComboClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  IdeTweaksItemClass *item_class = IDE_TWEAKS_ITEM_CLASS (klass);
+  IdeTweaksWidgetClass *widget_class = IDE_TWEAKS_WIDGET_CLASS (klass);
+
+  object_class->dispose = ide_tweaks_combo_dispose;
+  object_class->get_property = ide_tweaks_combo_get_property;
+  object_class->set_property = ide_tweaks_combo_set_property;
+
+  item_class->accepts = ide_tweaks_combo_accepts;
+
+  widget_class->create = ide_tweaks_combo_create;
+
+  properties[PROP_SETTINGS] =
+    g_param_spec_object ("settings", NULL, NULL,
+                         IDE_TYPE_TWEAKS_SETTINGS,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_KEY] =
+    g_param_spec_string ("key", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_TITLE] =
+    g_param_spec_string ("title", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_SUBTITLE] =
+    g_param_spec_string ("subtitle", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_tweaks_combo_init (IdeTweaksCombo *self)
+{
+}
+
+IdeTweaksCombo *
+ide_tweaks_combo_new (void)
+{
+  return g_object_new (IDE_TYPE_TWEAKS_COMBO, NULL);
+}
+
+const char *
+ide_tweaks_combo_get_title (IdeTweaksCombo *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_COMBO (self), NULL);
+
+  return self->title;
+}
+
+void
+ide_tweaks_combo_set_title (IdeTweaksCombo *self,
+                            const char     *title)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_COMBO (self));
+
+  if (ide_set_string (&self->title, title))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
+}
+
+const char *
+ide_tweaks_combo_get_subtitle (IdeTweaksCombo *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_COMBO (self), NULL);
+
+  return self->subtitle;
+}
+
+void
+ide_tweaks_combo_set_subtitle (IdeTweaksCombo *self,
+                               const char     *subtitle)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_COMBO (self));
+
+  if (ide_set_string (&self->subtitle, subtitle))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SUBTITLE]);
+}
+
+const char *
+ide_tweaks_combo_get_key (IdeTweaksCombo *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_COMBO (self), NULL);
+
+  return self->key;
+}
+
+void
+ide_tweaks_combo_set_key (IdeTweaksCombo *self,
+                          const char     *key)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_COMBO (self));
+
+  if (ide_set_string (&self->key, key))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_KEY]);
+}
+
+/**
+ * ide_tweaks_combo_get_settings:
+ * @self: a #IdeTweaksCombo
+ *
+ * Gets the settings for the combo.
+ *
+ * Returns: (nullable) (transfer none): an #IdeTweaksSettings or %NULL
+ */
+IdeTweaksSettings *
+ide_tweaks_combo_get_settings (IdeTweaksCombo *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_COMBO (self), NULL);
+
+  return self->settings;
+}
+
+void
+ide_tweaks_combo_set_settings (IdeTweaksCombo    *self,
+                               IdeTweaksSettings *settings)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_COMBO (self));
+  g_return_if_fail (!settings || IDE_IS_TWEAKS_SETTINGS (settings));
+
+  if (g_set_object (&self->settings, settings))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SETTINGS]);
+}
diff --git a/src/libide/tweaks/ide-tweaks-combo.h b/src/libide/tweaks/ide-tweaks-combo.h
new file mode 100644
index 000000000..925fcdea3
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-combo.h
@@ -0,0 +1,60 @@
+/* ide-tweaks-combo.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#if !defined (IDE_TWEAKS_INSIDE) && !defined (IDE_TWEAKS_COMPILATION)
+# error "Only <libide-tweaks.h> can be included directly."
+#endif
+
+#include "ide-tweaks-settings.h"
+#include "ide-tweaks-widget.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_TWEAKS_COMBO (ide_tweaks_combo_get_type())
+
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdeTweaksCombo, ide_tweaks_combo, IDE, TWEAKS_COMBO, IdeTweaksWidget)
+
+IDE_AVAILABLE_IN_ALL
+IdeTweaksCombo    *ide_tweaks_combo_new          (void);
+IDE_AVAILABLE_IN_ALL
+const char        *ide_tweaks_combo_get_title    (IdeTweaksCombo    *self);
+IDE_AVAILABLE_IN_ALL
+void               ide_tweaks_combo_set_title    (IdeTweaksCombo    *self,
+                                                  const char        *title);
+IDE_AVAILABLE_IN_ALL
+const char        *ide_tweaks_combo_get_subtitle (IdeTweaksCombo    *self);
+IDE_AVAILABLE_IN_ALL
+void               ide_tweaks_combo_set_subtitle (IdeTweaksCombo    *self,
+                                                  const char        *subtitle);
+IDE_AVAILABLE_IN_ALL
+const char        *ide_tweaks_combo_get_key      (IdeTweaksCombo    *self);
+IDE_AVAILABLE_IN_ALL
+void               ide_tweaks_combo_set_key      (IdeTweaksCombo    *self,
+                                                  const char        *key);
+IDE_AVAILABLE_IN_ALL
+IdeTweaksSettings *ide_tweaks_combo_get_settings (IdeTweaksCombo    *self);
+IDE_AVAILABLE_IN_ALL
+void               ide_tweaks_combo_set_settings (IdeTweaksCombo    *self,
+                                                  IdeTweaksSettings *setings);
+
+G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-init.c b/src/libide/tweaks/ide-tweaks-init.c
index 36afdad69..38a40ec09 100644
--- a/src/libide/tweaks/ide-tweaks-init.c
+++ b/src/libide/tweaks/ide-tweaks-init.c
@@ -34,6 +34,8 @@ _ide_tweaks_init (void)
 
   g_type_ensure (IDE_TYPE_TWEAKS);
   g_type_ensure (IDE_TYPE_TWEAKS_ADDIN);
+  g_type_ensure (IDE_TYPE_TWEAKS_CHOICE);
+  g_type_ensure (IDE_TYPE_TWEAKS_COMBO);
   g_type_ensure (IDE_TYPE_TWEAKS_FACTORY);
   g_type_ensure (IDE_TYPE_TWEAKS_FONT);
   g_type_ensure (IDE_TYPE_TWEAKS_GROUP);
diff --git a/src/libide/tweaks/libide-tweaks.gresource.xml b/src/libide/tweaks/libide-tweaks.gresource.xml
index f575ca43e..04b2b85fe 100644
--- a/src/libide/tweaks/libide-tweaks.gresource.xml
+++ b/src/libide/tweaks/libide-tweaks.gresource.xml
@@ -5,6 +5,7 @@
     <file preprocess="xml-stripblanks">ide-tweaks-panel.ui</file>
     <file preprocess="xml-stripblanks">ide-tweaks-panel-list.ui</file>
     <file preprocess="xml-stripblanks">ide-tweaks-panel-list-row.ui</file>
+    <file preprocess="xml-stripblanks">ide-tweaks-combo-row.ui</file>
     <file preprocess="xml-stripblanks">ide-tweaks-window.ui</file>
   </gresource>
 </gresources>
diff --git a/src/libide/tweaks/libide-tweaks.h b/src/libide/tweaks/libide-tweaks.h
index 014a2ef96..429847c9e 100644
--- a/src/libide/tweaks/libide-tweaks.h
+++ b/src/libide/tweaks/libide-tweaks.h
@@ -23,6 +23,8 @@
 #define IDE_TWEAKS_INSIDE
 # include "ide-tweaks.h"
 # include "ide-tweaks-addin.h"
+# include "ide-tweaks-choice.h"
+# include "ide-tweaks-combo.h"
 # include "ide-tweaks-factory.h"
 # include "ide-tweaks-font.h"
 # include "ide-tweaks-group.h"
diff --git a/src/libide/tweaks/meson.build b/src/libide/tweaks/meson.build
index 78500c327..f89887223 100644
--- a/src/libide/tweaks/meson.build
+++ b/src/libide/tweaks/meson.build
@@ -10,6 +10,8 @@ libide_tweaks_public_headers = [
   'libide-tweaks.h',
   'ide-tweaks.h',
   'ide-tweaks-addin.h',
+  'ide-tweaks-choice.h',
+  'ide-tweaks-combo.h',
   'ide-tweaks-factory.h',
   'ide-tweaks-font.h',
   'ide-tweaks-group.h',
@@ -34,6 +36,8 @@ install_headers(libide_tweaks_public_headers, subdir: libide_tweaks_header_subdi
 libide_tweaks_public_sources = [
   'ide-tweaks.c',
   'ide-tweaks-addin.c',
+  'ide-tweaks-choice.c',
+  'ide-tweaks-combo.c',
   'ide-tweaks-factory.c',
   'ide-tweaks-font.c',
   'ide-tweaks-group.c',
@@ -50,6 +54,7 @@ libide_tweaks_public_sources = [
 ]
 
 libide_tweaks_private_sources = [
+  'ide-tweaks-combo-row.c',
   'ide-tweaks-init.c',
   'ide-tweaks-model.c',
   'ide-tweaks-panel.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]