[gnome-builder/wip/chergert/perspective] prefs: start on preferences perspective
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/perspective] prefs: start on preferences perspective
- Date: Fri, 6 Nov 2015 09:54:45 +0000 (UTC)
commit a4e49a060e196da534ab777513f87c384dcaa475
Author: Christian Hergert <chergert redhat com>
Date: Fri Nov 6 01:54:34 2015 -0800
prefs: start on preferences perspective
The goal of this is to allow for editing preferences from the workbench
window without having to open a transient dialog. While we have an
IdePreferences interface that can be implemented for a dialog as well,
I doubt we will do that as this seems much more convenient.
We might consider embedding the persepctive in a dialog for a case where
the user just wants to edit preferences and not run Builder, but not too
worried about that case.
data/theme/shared.css | 8 +
data/ui/ide-preferences-font-button.ui | 37 ++
data/ui/ide-preferences-group.ui | 49 ++
data/ui/ide-preferences-page.ui | 21 +
data/ui/ide-preferences-perspective.ui | 29 +
data/ui/ide-preferences-switch.ui | 52 ++
libide/Makefile.am | 25 +-
libide/ide-preferences.h | 105 ----
libide/ide-workbench-private.h | 24 +-
libide/ide-workbench.c | 71 +++-
libide/ide.h | 4 +-
libide/{ => preferences}/ide-preferences-addin.c | 0
libide/{ => preferences}/ide-preferences-addin.h | 0
libide/preferences/ide-preferences-builtin.c | 110 ++++
libide/preferences/ide-preferences-builtin.h | 30 ++
libide/preferences/ide-preferences-container.c | 129 +++++
libide/preferences/ide-preferences-container.h | 37 ++
libide/preferences/ide-preferences-font-button.c | 219 ++++++++
libide/preferences/ide-preferences-font-button.h | 32 ++
libide/preferences/ide-preferences-group.c | 174 ++++++
libide/preferences/ide-preferences-group.h | 35 ++
libide/preferences/ide-preferences-page.c | 151 ++++++
libide/preferences/ide-preferences-page.h | 39 ++
libide/preferences/ide-preferences-perspective.c | 607 ++++++++++++++++++++++
libide/preferences/ide-preferences-perspective.h | 32 ++
libide/preferences/ide-preferences-spin-button.c | 93 ++++
libide/preferences/ide-preferences-spin-button.h | 32 ++
libide/preferences/ide-preferences-switch.c | 269 ++++++++++
libide/preferences/ide-preferences-switch.h | 32 ++
libide/{ => preferences}/ide-preferences.c | 85 +++-
libide/preferences/ide-preferences.h | 153 ++++++
libide/resources/libide.gresource.xml | 5 +
32 files changed, 2543 insertions(+), 146 deletions(-)
---
diff --git a/data/theme/shared.css b/data/theme/shared.css
index e5dd4f8..140d2fc 100644
--- a/data/theme/shared.css
+++ b/data/theme/shared.css
@@ -188,3 +188,11 @@ IdeWorkbench > GtkStack > GtkBox.horizontal > GtkStackSwitcher > button:hover {
background-color: mix(@theme_bg_color, @borders, 0.25);
}
*/
+
+IdeWorkbench IdePreferencesPerspective IdePreferencesGroup GtkListBoxRow {
+ border-bottom: 1px solid shade(@borders, 1.2);
+ padding: 10px;
+}
+IdeWorkbench IdePreferencesPerspective IdePreferencesGroup GtkListBoxRow:last-child {
+ border-bottom: none;
+}
diff --git a/data/ui/ide-preferences-font-button.ui b/data/ui/ide-preferences-font-button.ui
new file mode 100644
index 0000000..ccf5243
--- /dev/null
+++ b/data/ui/ide-preferences-font-button.ui
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.18 -->
+ <template class="IdePreferencesFontButton" parent="IdePreferencesContainer">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="spacing">18</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="font_family">
+ <property name="visible">true</property>
+ <property name="xalign">1.0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="font_size">
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/ide-preferences-group.ui b/data/ui/ide-preferences-group.ui
new file mode 100644
index 0000000..cd2ec25
--- /dev/null
+++ b/data/ui/ide-preferences-group.ui
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.18 -->
+ <template class="IdePreferencesGroup" parent="GtkBin">
+ <property name="vexpand">false</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">true</property>
+ <property name="hexpand">true</property>
+ <property name="xalign">0.0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="padding">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFrame" id="list_box_frame">
+ <child>
+ <object class="GtkListBox" id="list_box">
+ <property name="selection-mode">none</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/ide-preferences-page.ui b/data/ui/ide-preferences-page.ui
new file mode 100644
index 0000000..2c4269f
--- /dev/null
+++ b/data/ui/ide-preferences-page.ui
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.18 -->
+ <template class="IdePreferencesPage" parent="GtkBin">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="halign">center</property>
+ <property name="margin">24</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">24</property>
+ <property name="visible">true</property>
+ <property name="width-request">500</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/ide-preferences-perspective.ui b/data/ui/ide-preferences-perspective.ui
new file mode 100644
index 0000000..3bb5087
--- /dev/null
+++ b/data/ui/ide-preferences-perspective.ui
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.18 -->
+ <template class="IdePreferencesPerspective" parent="GtkBin">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkStackSidebar" id="page_stack_sidebar">
+ <property name="stack">page_stack</property>
+ <property name="visible">true</property>
+ <property name="width-request">200</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="page_stack">
+ <property name="transition-duration">333</property>
+ <property name="transition-type">crossfade</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="IdeWorkbenchHeaderBar" id="titlebar">
+ <property name="visible">true</property>
+ </object>
+</interface>
diff --git a/data/ui/ide-preferences-switch.ui b/data/ui/ide-preferences-switch.ui
new file mode 100644
index 0000000..e7b2613
--- /dev/null
+++ b/data/ui/ide-preferences-switch.ui
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.18 -->
+ <template class="IdePreferencesSwitch" parent="IdePreferencesContainer">
+ <property name="vexpand">false</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="hexpand">true</property>
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">true</property>
+ <property name="vexpand">true</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle">
+ <property name="visible">true</property>
+ <property name="vexpand">true</property>
+ <property name="xalign">0.0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ <attributes>
+ <attribute name="scale" value="0.83333"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="icon-name">object-select-symbolic</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="widget">
+ <property name="visible">true</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/libide/Makefile.am b/libide/Makefile.am
index e7ab03b..2f10411 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -99,10 +99,6 @@ libide_1_0_la_public_sources = \
ide-macros.h \
ide-perspective.c \
ide-perspective.h \
- ide-preferences.c \
- ide-preferences.h \
- ide-preferences-addin.c \
- ide-preferences-addin.h \
ide-object.c \
ide-object.h \
ide-pattern-spec.c \
@@ -204,6 +200,10 @@ libide_1_0_la_public_sources = \
ide.h \
local/ide-local-device.c \
local/ide-local-device.h \
+ preferences/ide-preferences.c \
+ preferences/ide-preferences.h \
+ preferences/ide-preferences-addin.c \
+ preferences/ide-preferences-addin.h \
$(NULL)
libide_1_0_la_SOURCES = \
@@ -270,6 +270,22 @@ libide_1_0_la_SOURCES = \
modelines/ide-modelines-file-settings.h \
modelines/modeline-parser.c \
modelines/modeline-parser.h \
+ preferences/ide-preferences-builtin.c \
+ preferences/ide-preferences-builtin.h \
+ preferences/ide-preferences-container.c \
+ preferences/ide-preferences-container.h \
+ preferences/ide-preferences-font-button.c \
+ preferences/ide-preferences-font-button.h \
+ preferences/ide-preferences-group.c \
+ preferences/ide-preferences-group.h \
+ preferences/ide-preferences-page.c \
+ preferences/ide-preferences-page.h \
+ preferences/ide-preferences-perspective.c \
+ preferences/ide-preferences-perspective.h \
+ preferences/ide-preferences-spin-button.c \
+ preferences/ide-preferences-spin-button.h \
+ preferences/ide-preferences-switch.c \
+ preferences/ide-preferences-switch.h \
theatrics/ide-box-theatric.c \
theatrics/ide-box-theatric.h \
util/ide-cairo.c \
@@ -312,6 +328,7 @@ libide_1_0_la_includes = \
-I$(srcdir)/gsettings \
-I$(srcdir)/local \
-I$(srcdir)/modelines \
+ -I$(srcdir)/preferences \
-I$(srcdir)/resources \
-I$(srcdir)/theatrics \
-I$(srcdir)/util \
diff --git a/libide/ide-workbench-private.h b/libide/ide-workbench-private.h
index f917bdc..ec8cecd 100644
--- a/libide/ide-workbench-private.h
+++ b/libide/ide-workbench-private.h
@@ -23,26 +23,28 @@
#include "ide-editor-perspective.h"
#include "ide-greeter-perspective.h"
+#include "ide-preferences-perspective.h"
#include "ide-workbench.h"
G_BEGIN_DECLS
struct _IdeWorkbench
{
- GtkApplicationWindow parent;
+ GtkApplicationWindow parent;
- IdeContext *context;
- PeasExtensionSet *addins;
+ IdeContext *context;
+ PeasExtensionSet *addins;
- IdePerspective *perspective;
+ IdePerspective *perspective;
- GtkStack *top_stack;
- GtkStack *titlebar_stack;
- IdeEditorPerspective *editor_perspective;
- IdeGreeterPerspective *greeter_perspective;
- GtkStack *perspectives_stack;
- GtkStackSwitcher *perspectives_stack_switcher;
- GtkPopover *perspectives_popover;
+ GtkStack *top_stack;
+ GtkStack *titlebar_stack;
+ IdeEditorPerspective *editor_perspective;
+ IdeGreeterPerspective *greeter_perspective;
+ IdePreferencesPerspective *preferences_perspective;
+ GtkStack *perspectives_stack;
+ GtkStackSwitcher *perspectives_stack_switcher;
+ GtkPopover *perspectives_popover;
};
typedef struct
diff --git a/libide/ide-workbench.c b/libide/ide-workbench.c
index 9332d96..c09a8c9 100644
--- a/libide/ide-workbench.c
+++ b/libide/ide-workbench.c
@@ -36,6 +36,34 @@ enum {
static GParamSpec *properties [LAST_PROP];
static void
+ide_workbench_notify_visible_child (IdeWorkbench *self,
+ GParamSpec *pspec,
+ GtkStack *stack)
+{
+ IdePerspective *perspective;
+
+ g_assert (IDE_IS_WORKBENCH (self));
+ g_assert (GTK_IS_STACK (stack));
+
+ perspective = IDE_PERSPECTIVE (gtk_stack_get_visible_child (stack));
+
+ if (perspective != NULL)
+ {
+ GActionGroup *actions;
+ gchar *id;
+
+ id = ide_perspective_get_id (perspective);
+ gtk_stack_set_visible_child_name (self->titlebar_stack, id);
+
+ actions = ide_perspective_get_actions (perspective);
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "perspective", actions);
+
+ g_clear_object (&actions);
+ g_free (id);
+ }
+}
+
+static void
ide_workbench_finalize (GObject *object)
{
IdeWorkbench *self = (IdeWorkbench *)object;
@@ -163,15 +191,32 @@ ide_workbench_init_editor (IdeWorkbench *self)
}
static void
+ide_workbench_init_preferences (IdeWorkbench *self)
+{
+ g_assert (IDE_IS_WORKBENCH (self));
+
+ self->preferences_perspective = g_object_new (IDE_TYPE_PREFERENCES_PERSPECTIVE,
+ "visible", TRUE,
+ NULL);
+ ide_workbench_add_perspective (self, IDE_PERSPECTIVE (self->preferences_perspective));
+}
+
+static void
ide_workbench_init (IdeWorkbench *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
ide_workbench_init_greeter (self);
ide_workbench_init_editor (self);
- ide_workbench_init_editor (self);
+ ide_workbench_init_preferences (self);
ide_window_settings_register (GTK_WINDOW (self));
+ g_signal_connect_object (self->perspectives_stack,
+ "notify::visible-child",
+ G_CALLBACK (ide_workbench_notify_visible_child),
+ self,
+ G_CONNECT_SWAPPED);
+
gtk_stack_set_visible_child (self->top_stack, GTK_WIDGET (self->greeter_perspective));
}
@@ -375,23 +420,35 @@ void
ide_workbench_set_perspective (IdeWorkbench *self,
IdePerspective *perspective)
{
- GActionGroup *actions;
- const gchar *id;
GtkStack *stack;
+ gchar *id;
g_return_if_fail (IDE_IS_WORKBENCH (self));
g_return_if_fail (IDE_IS_PERSPECTIVE (perspective));
+ /*
+ * NOTE:
+ *
+ * The greeter perspective is special cased. We want to use the same window for the greeter
+ * and the workbench, so it has a toplevel stack with slightly different semantics than the
+ * other perspectives. We don't show the perspective sidebar, and we use a slide-right-left
+ * animation.
+ *
+ * Once we leave the greeter, we do not come back to it. We only use crossfade animations from
+ * then on.
+ */
+
if (IDE_IS_GREETER_PERSPECTIVE (perspective))
stack = self->top_stack;
else
stack = self->perspectives_stack;
id = ide_perspective_get_id (perspective);
- gtk_stack_set_visible_child_name (self->titlebar_stack, id);
gtk_stack_set_visible_child_name (stack, id);
+ gtk_stack_set_visible_child_name (self->titlebar_stack, id);
+
+ if (!IDE_IS_GREETER_PERSPECTIVE (perspective))
+ gtk_stack_set_transition_type (self->titlebar_stack, GTK_STACK_TRANSITION_TYPE_CROSSFADE);
- actions = ide_perspective_get_actions (perspective);
- gtk_widget_insert_action_group (GTK_WIDGET (self), "perspective", actions);
- g_clear_object (&actions);
+ g_free (id);
}
diff --git a/libide/ide.h b/libide/ide.h
index f50106c..7168b3b 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -63,8 +63,6 @@ G_BEGIN_DECLS
#include "ide-object.h"
#include "ide-pattern-spec.h"
#include "ide-perspective.h"
-#include "ide-preferences.h"
-#include "ide-preferences-addin.h"
#include "ide-process.h"
#include "ide-progress.h"
#include "ide-project.h"
@@ -109,6 +107,8 @@ G_BEGIN_DECLS
#include "git/ide-git-remote-callbacks.h"
#include "git/ide-git-vcs.h"
#include "local/ide-local-device.h"
+#include "preferences/ide-preferences.h"
+#include "preferences/ide-preferences-addin.h"
#include "util/ide-line-reader.h"
#include "util/ide-list-inline.h"
diff --git a/libide/ide-preferences-addin.c b/libide/preferences/ide-preferences-addin.c
similarity index 100%
rename from libide/ide-preferences-addin.c
rename to libide/preferences/ide-preferences-addin.c
diff --git a/libide/ide-preferences-addin.h b/libide/preferences/ide-preferences-addin.h
similarity index 100%
rename from libide/ide-preferences-addin.h
rename to libide/preferences/ide-preferences-addin.h
diff --git a/libide/preferences/ide-preferences-builtin.c b/libide/preferences/ide-preferences-builtin.c
new file mode 100644
index 0000000..3f8594c
--- /dev/null
+++ b/libide/preferences/ide-preferences-builtin.c
@@ -0,0 +1,110 @@
+/* ide-preferences-builtin.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include <glib/gi18n.h>
+#include <gtksourceview/gtksource.h>
+#include <libpeas/peas.h>
+
+#include "ide-preferences-builtin.h"
+
+static void
+ide_preferences_builtin_register_plugins (IdePreferences *preferences)
+{
+ PeasEngine *engine;
+ const GList *list;
+ guint i = 0;
+
+ g_assert (IDE_IS_PREFERENCES (preferences));
+
+ engine = peas_engine_get_default ();
+ list = peas_engine_get_plugin_list (engine);
+
+ ide_preferences_add_page (preferences, "plugins", _("Plugins"), 700);
+ ide_preferences_add_list_group (preferences, "plugins", "plugins", _("Installed Plugins"), 0);
+
+ for (; list; list = list->next, i++)
+ {
+ PeasPluginInfo *plugin_info = list->data;
+ const gchar *desc;
+ const gchar *name;
+
+ name = peas_plugin_info_get_name (plugin_info);
+ desc = peas_plugin_info_get_description (plugin_info);
+
+ /* TODO: support custom path (and use right schema/key) */
+ ide_preferences_add_switch (preferences, "plugins", "plugins", "org.gnome.builder.editor",
"show-line-numbers", NULL, name, desc, NULL, i);
+ }
+}
+
+static void
+ide_preferences_builtin_register_appearance (IdePreferences *preferences)
+{
+ GtkSourceStyleSchemeManager *manager;
+ const gchar * const *scheme_ids;
+ gint i;
+
+ ide_preferences_add_page (preferences, "appearance", _("Appearance"), 0);
+
+ ide_preferences_add_group (preferences, "appearance", "basic", NULL, 0);
+ ide_preferences_add_switch (preferences, "appearance", "basic", "org.gnome.builder", "night-mode", NULL,
_("Dark Theme"), _("Whether Builder should use a dark theme"), _("dark theme"), 0);
+ ide_preferences_add_switch (preferences, "appearance", "basic", "org.gnome.builder", "animations", NULL,
_("Animations"), _("Whether animations should be used when appropriate"), _("animations"), 100);
+
+ ide_preferences_add_list_group (preferences, "appearance", "font", _("Font"), 100);
+ ide_preferences_add_font_button (preferences, "appearance", "font", "org.gnome.builder.editor",
"font-name", _("Editor"), _("editor font monospace"), 0);
+
+ ide_preferences_add_list_group (preferences, "appearance", "schemes", _("Themes"), 200);
+
+ manager = gtk_source_style_scheme_manager_get_default ();
+ scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
+
+ for (i = 0; scheme_ids [i]; i++)
+ {
+ g_autofree gchar *variant_str = NULL;
+ GtkSourceStyleScheme *scheme;
+ const gchar *title;
+
+ variant_str = g_strdup_printf ("\"%s\"", scheme_ids [i]);
+ scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_ids [i]);
+ title = gtk_source_style_scheme_get_name (scheme);
+
+ ide_preferences_add_radio (preferences, "appearance", "schemes", "org.gnome.builder.editor",
"style-scheme-name", variant_str, title, NULL, title, i);
+ }
+
+ ide_preferences_add_list_group (preferences, "appearance", "draw-spaces", _("Whitespace Characters"), 300);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"space\"", _("Spaces"), NULL, NULL, 0);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"tab\"", _("Tabs"), NULL, NULL, 1);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"newline\"", _("New line and carriage return"), NULL, NULL, 2);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"nbsp\"", _("Non-breaking spaces"), NULL, NULL, 3);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"text\"", _("Spaces inside of text"), NULL, NULL, 4);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"trailing\"", _("Trailing Only"), NULL, NULL, 5);
+ ide_preferences_add_switch (preferences, "appearance", "draw-spaces", "org.gnome.builder.editor",
"draw-spaces", "\"leading\"", _("Leading Only"), NULL, NULL, 6);
+}
+
+void
+_ide_preferences_builtin_register (IdePreferences *preferences)
+{
+ ide_preferences_builtin_register_appearance (preferences);
+
+ ide_preferences_add_page (preferences, "editor", _("Editor"), 100);
+ ide_preferences_add_page (preferences, "languages", _("Programming Languages"), 200);
+ ide_preferences_add_page (preferences, "code-insight", _("Code Insight"), 300);
+ ide_preferences_add_page (preferences, "keyboard", _("Keyboard"), 400);
+ ide_preferences_add_page (preferences, "vcs", _("Version Control"), 600);
+
+ ide_preferences_builtin_register_plugins (preferences);
+}
diff --git a/libide/preferences/ide-preferences-builtin.h b/libide/preferences/ide-preferences-builtin.h
new file mode 100644
index 0000000..c4bdc6c
--- /dev/null
+++ b/libide/preferences/ide-preferences-builtin.h
@@ -0,0 +1,30 @@
+/* ide-preferences-builtin.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_BUILTIN_H
+#define IDE_PREFERENCES_BUILTIN_H
+
+#include "ide-preferences.h"
+
+G_BEGIN_DECLS
+
+void _ide_preferences_builtin_register (IdePreferences *preferences);
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_BUILTIN_H */
diff --git a/libide/preferences/ide-preferences-container.c b/libide/preferences/ide-preferences-container.c
new file mode 100644
index 0000000..b2259f7
--- /dev/null
+++ b/libide/preferences/ide-preferences-container.c
@@ -0,0 +1,129 @@
+/* ide-preferences-container.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include "ide-preferences-container.h"
+
+typedef struct
+{
+ GtkBin parent_instance;
+ gint priority;
+ gchar *keywords;
+} IdePreferencesContainerPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IdePreferencesContainer, ide_preferences_container, GTK_TYPE_BIN)
+
+enum {
+ PROP_0,
+ PROP_KEYWORDS,
+ PROP_PRIORITY,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_preferences_container_finalize (GObject *object)
+{
+ IdePreferencesContainer *self = (IdePreferencesContainer *)object;
+ IdePreferencesContainerPrivate *priv = ide_preferences_container_get_instance_private (self);
+
+ g_clear_pointer (&priv->keywords, g_free);
+
+ G_OBJECT_CLASS (ide_preferences_container_parent_class)->finalize (object);
+}
+
+static void
+ide_preferences_container_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesContainer *self = IDE_PREFERENCES_CONTAINER (object);
+ IdePreferencesContainerPrivate *priv = ide_preferences_container_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_KEYWORDS:
+ g_value_set_string (value, priv->keywords);
+ break;
+
+ case PROP_PRIORITY:
+ g_value_set_int (value, priv->priority);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_container_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesContainer *self = IDE_PREFERENCES_CONTAINER (object);
+ IdePreferencesContainerPrivate *priv = ide_preferences_container_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_KEYWORDS:
+ priv->keywords = g_value_dup_string (value);
+ break;
+
+ case PROP_PRIORITY:
+ priv->priority = g_value_get_int (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_container_class_init (IdePreferencesContainerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_preferences_container_finalize;
+ object_class->get_property = ide_preferences_container_get_property;
+ object_class->set_property = ide_preferences_container_set_property;
+
+ properties [PROP_KEYWORDS] =
+ g_param_spec_string ("keywords",
+ "Keywords",
+ "Search keywords for the widget.",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_PRIORITY] =
+ g_param_spec_int ("priority",
+ "Priority",
+ "The widget priority within the group.",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+}
+
+static void
+ide_preferences_container_init (IdePreferencesContainer *self)
+{
+}
diff --git a/libide/preferences/ide-preferences-container.h b/libide/preferences/ide-preferences-container.h
new file mode 100644
index 0000000..c5b2cad
--- /dev/null
+++ b/libide/preferences/ide-preferences-container.h
@@ -0,0 +1,37 @@
+/* ide-preferences-container.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_CONTAINER_H
+#define IDE_PREFERENCES_CONTAINER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_CONTAINER (ide_preferences_container_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (IdePreferencesContainer, ide_preferences_container, IDE, PREFERENCES_CONTAINER,
GtkBin)
+
+struct _IdePreferencesContainerClass
+{
+ GtkBinClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_CONTAINER_H */
diff --git a/libide/preferences/ide-preferences-font-button.c
b/libide/preferences/ide-preferences-font-button.c
new file mode 100644
index 0000000..ecb247d
--- /dev/null
+++ b/libide/preferences/ide-preferences-font-button.c
@@ -0,0 +1,219 @@
+/* ide-preferences-font-button.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include "ide-preferences-font-button.h"
+
+struct _IdePreferencesFontButton
+{
+ GtkBin parent_instance;
+
+ GSettings *settings;
+ gchar *schema_id;
+ gchar *key;
+
+ GtkLabel *title;
+ GtkLabel *font_family;
+ GtkLabel *font_size;
+};
+
+G_DEFINE_TYPE (IdePreferencesFontButton, ide_preferences_font_button, IDE_TYPE_PREFERENCES_CONTAINER)
+
+enum {
+ PROP_0,
+ PROP_KEY,
+ PROP_SCHEMA_ID,
+ PROP_TITLE,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_preferences_font_button_changed (IdePreferencesFontButton *self,
+ const gchar *key,
+ GSettings *settings)
+{
+ PangoFontDescription *font_desc;
+ gchar *name;
+
+ g_assert (IDE_IS_PREFERENCES_FONT_BUTTON (self));
+ g_assert (key != NULL);
+ g_assert (G_IS_SETTINGS (settings));
+
+ name = g_settings_get_string (settings, key);
+ font_desc = pango_font_description_from_string (name);
+
+ if (font_desc != NULL)
+ {
+ gchar *font_size;
+
+ gtk_label_set_label (self->font_family, pango_font_description_get_family (font_desc));
+ font_size = g_strdup_printf ("%dpt", pango_font_description_get_size (font_desc) / PANGO_SCALE);
+ gtk_label_set_label (self->font_size, font_size);
+ g_free (font_size);
+ }
+
+ g_clear_pointer (&font_desc, pango_font_description_free);
+ g_free (name);
+}
+
+static void
+ide_preferences_font_button_constructed (GObject *object)
+{
+ IdePreferencesFontButton *self = (IdePreferencesFontButton *)object;
+ GSettingsSchemaSource *source;
+ g_autoptr(GSettingsSchema) schema = NULL;
+ g_autofree gchar *signal_detail = NULL;
+
+ g_assert (IDE_IS_PREFERENCES_FONT_BUTTON (self));
+
+ source = g_settings_schema_source_get_default ();
+ schema = g_settings_schema_source_lookup (source, self->schema_id, TRUE);
+
+ if (schema == NULL || !g_settings_schema_has_key (schema, self->key))
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ goto chainup;
+ }
+
+ self->settings = g_settings_new (self->schema_id);
+ signal_detail = g_strdup_printf ("changed::%s", self->key);
+
+ g_signal_connect_object (self->settings,
+ signal_detail,
+ G_CALLBACK (ide_preferences_font_button_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ ide_preferences_font_button_changed (self, self->key, self->settings);
+
+chainup:
+ G_OBJECT_CLASS (ide_preferences_font_button_parent_class)->constructed (object);
+}
+
+static void
+ide_preferences_font_button_finalize (GObject *object)
+{
+ IdePreferencesFontButton *self = (IdePreferencesFontButton *)object;
+
+ g_clear_object (&self->settings);
+ g_clear_pointer (&self->schema_id, g_free);
+ g_clear_pointer (&self->key, g_free);
+
+ G_OBJECT_CLASS (ide_preferences_font_button_parent_class)->finalize (object);
+}
+
+static void
+ide_preferences_font_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesFontButton *self = IDE_PREFERENCES_FONT_BUTTON (object);
+
+ switch (prop_id)
+ {
+ case PROP_KEY:
+ g_value_set_string (value, self->key);
+ break;
+
+ case PROP_SCHEMA_ID:
+ g_value_set_string (value, self->schema_id);
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, gtk_label_get_label (self->title));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_font_button_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesFontButton *self = IDE_PREFERENCES_FONT_BUTTON (object);
+
+ switch (prop_id)
+ {
+ case PROP_KEY:
+ self->key = g_value_dup_string (value);
+ break;
+
+ case PROP_SCHEMA_ID:
+ self->schema_id = g_value_dup_string (value);
+ break;
+
+ case PROP_TITLE:
+ gtk_label_set_label (self->title, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_font_button_class_init (IdePreferencesFontButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = ide_preferences_font_button_constructed;
+ object_class->finalize = ide_preferences_font_button_finalize;
+ object_class->get_property = ide_preferences_font_button_get_property;
+ object_class->set_property = ide_preferences_font_button_set_property;
+
+ properties [PROP_KEY] =
+ g_param_spec_string ("key",
+ "Key",
+ "Key",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_SCHEMA_ID] =
+ g_param_spec_string ("schema-id",
+ "Schema Id",
+ "Schema Id",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_TITLE] =
+ g_param_spec_string ("title",
+ "Title",
+ "Title",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-preferences-font-button.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesFontButton, title);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesFontButton, font_family);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesFontButton, font_size);
+}
+
+static void
+ide_preferences_font_button_init (IdePreferencesFontButton *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/libide/preferences/ide-preferences-font-button.h
b/libide/preferences/ide-preferences-font-button.h
new file mode 100644
index 0000000..50a7acd
--- /dev/null
+++ b/libide/preferences/ide-preferences-font-button.h
@@ -0,0 +1,32 @@
+/* ide-preferences-font-button.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_FONT_BUTTON_H
+#define IDE_PREFERENCES_FONT_BUTTON_H
+
+#include "ide-preferences-container.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_FONT_BUTTON (ide_preferences_font_button_get_type())
+
+G_DECLARE_FINAL_TYPE (IdePreferencesFontButton, ide_preferences_font_button, IDE, PREFERENCES_FONT_BUTTON,
GtkBin)
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_FONT_BUTTON_H */
diff --git a/libide/preferences/ide-preferences-group.c b/libide/preferences/ide-preferences-group.c
new file mode 100644
index 0000000..10cc4e6
--- /dev/null
+++ b/libide/preferences/ide-preferences-group.c
@@ -0,0 +1,174 @@
+/* ide-preferences-group.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include "ide-preferences-container.h"
+#include "ide-preferences-group.h"
+
+struct _IdePreferencesGroup
+{
+ GtkBin parent_instance;
+
+ gint priority;
+ guint is_list : 1;
+
+ GtkLabel *title;
+ GtkBox *box;
+ GtkListBox *list_box;
+ GtkFrame *list_box_frame;
+};
+
+G_DEFINE_TYPE (IdePreferencesGroup, ide_preferences_group, GTK_TYPE_BIN)
+
+enum {
+ PROP_0,
+ PROP_IS_LIST,
+ PROP_PRIORITY,
+ PROP_TITLE,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_preferences_group_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesGroup *self = IDE_PREFERENCES_GROUP (object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_LIST:
+ g_value_set_boolean (value, self->is_list);
+ break;
+
+ case PROP_PRIORITY:
+ g_value_set_int (value, self->priority);
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, gtk_label_get_label (self->title));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_group_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesGroup *self = IDE_PREFERENCES_GROUP (object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_LIST:
+ self->is_list = g_value_get_boolean (value);
+ gtk_widget_set_visible (GTK_WIDGET (self->box), !self->is_list);
+ gtk_widget_set_visible (GTK_WIDGET (self->list_box_frame), self->is_list);
+ break;
+
+ case PROP_PRIORITY:
+ self->priority = g_value_get_int (value);
+ break;
+
+ case PROP_TITLE:
+ gtk_label_set_label (self->title, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_group_class_init (IdePreferencesGroupClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = ide_preferences_group_get_property;
+ object_class->set_property = ide_preferences_group_set_property;
+
+ properties [PROP_IS_LIST] =
+ g_param_spec_boolean ("is-list",
+ "Is List",
+ "If the group should be rendered as a listbox.",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_PRIORITY] =
+ g_param_spec_int ("priority",
+ "Priority",
+ "Priority",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_TITLE] =
+ g_param_spec_string ("title",
+ "Title",
+ "Title",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-preferences-group.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesGroup, box);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesGroup, list_box);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesGroup, list_box_frame);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesGroup, title);
+}
+
+static void
+ide_preferences_group_init (IdePreferencesGroup *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+void
+ide_preferences_group_add (IdePreferencesGroup *self,
+ GtkWidget *widget)
+{
+ gint position = -1;
+
+ g_return_if_fail (IDE_IS_PREFERENCES_GROUP (self));
+ g_return_if_fail (IDE_IS_PREFERENCES_CONTAINER (widget));
+
+ if (self->is_list)
+ {
+ GtkWidget *row;
+
+ row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
+ "child", widget,
+ "focus-on-click", FALSE,
+ "visible", TRUE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (self->list_box), row);
+ }
+ else
+ gtk_container_add_with_properties (GTK_CONTAINER (self->box), widget,
+ "position", position,
+ NULL);
+}
diff --git a/libide/preferences/ide-preferences-group.h b/libide/preferences/ide-preferences-group.h
new file mode 100644
index 0000000..c4b0be9
--- /dev/null
+++ b/libide/preferences/ide-preferences-group.h
@@ -0,0 +1,35 @@
+/* ide-preferences-group.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_GROUP_H
+#define IDE_PREFERENCES_GROUP_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_GROUP (ide_preferences_group_get_type())
+
+G_DECLARE_FINAL_TYPE (IdePreferencesGroup, ide_preferences_group, IDE, PREFERENCES_GROUP, GtkBin)
+
+void ide_preferences_group_add (IdePreferencesGroup *self,
+ GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_GROUP_H */
diff --git a/libide/preferences/ide-preferences-page.c b/libide/preferences/ide-preferences-page.c
new file mode 100644
index 0000000..7a680a1
--- /dev/null
+++ b/libide/preferences/ide-preferences-page.c
@@ -0,0 +1,151 @@
+/* ide-preferences-page.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "ide-preferences-group.h"
+#include "ide-preferences-page.h"
+
+struct _IdePreferencesPage
+{
+ GtkBin parent_instance;
+
+ gint priority;
+
+ GtkBox *box;
+ GHashTable *groups_by_name;
+};
+
+enum {
+ PROP_0,
+ PROP_PRIORITY,
+ LAST_PROP
+};
+
+G_DEFINE_TYPE (IdePreferencesPage, ide_preferences_page, GTK_TYPE_BIN)
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_preferences_page_finalize (GObject *object)
+{
+ IdePreferencesPage *self = (IdePreferencesPage *)object;
+
+ g_clear_pointer (&self->groups_by_name, g_hash_table_unref);
+
+ G_OBJECT_CLASS (ide_preferences_page_parent_class)->finalize (object);
+}
+
+static void
+ide_preferences_page_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesPage *self = IDE_PREFERENCES_PAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PRIORITY:
+ g_value_set_int (value, self->priority);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_page_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesPage *self = IDE_PREFERENCES_PAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PRIORITY:
+ self->priority = g_value_get_int (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_page_class_init (IdePreferencesPageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_preferences_page_finalize;
+ object_class->get_property = ide_preferences_page_get_property;
+ object_class->set_property = ide_preferences_page_set_property;
+
+ properties [PROP_PRIORITY] =
+ g_param_spec_int ("priority",
+ "Priority",
+ "Priority",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-preferences-page.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesPage, box);
+}
+
+static void
+ide_preferences_page_init (IdePreferencesPage *self)
+{
+ self->groups_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+void
+ide_preferences_page_add_group (IdePreferencesPage *self,
+ IdePreferencesGroup *group)
+{
+ gchar *name = NULL;
+ gint position = -1;
+
+ g_return_if_fail (IDE_IS_PREFERENCES_PAGE (self));
+ g_return_if_fail (IDE_IS_PREFERENCES_GROUP (group));
+
+ gtk_container_add_with_properties (GTK_CONTAINER (self->box), GTK_WIDGET (group),
+ "position", position,
+ NULL);
+
+ g_object_get (group, "name", &name, NULL);
+ g_hash_table_insert (self->groups_by_name, name, group);
+}
+
+IdePreferencesGroup *
+ide_preferences_page_get_group (IdePreferencesPage *self,
+ const gchar *name)
+{
+ g_return_val_if_fail (IDE_IS_PREFERENCES_PAGE (self), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return g_hash_table_lookup (self->groups_by_name, name);
+}
diff --git a/libide/preferences/ide-preferences-page.h b/libide/preferences/ide-preferences-page.h
new file mode 100644
index 0000000..840fe10
--- /dev/null
+++ b/libide/preferences/ide-preferences-page.h
@@ -0,0 +1,39 @@
+/* ide-preferences-page.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_PAGE_H
+#define IDE_PREFERENCES_PAGE_H
+
+#include <gtk/gtk.h>
+
+#include "ide-preferences-group.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_PAGE (ide_preferences_page_get_type())
+
+G_DECLARE_FINAL_TYPE (IdePreferencesPage, ide_preferences_page, IDE, PREFERENCES_PAGE, GtkBin)
+
+void ide_preferences_page_add_group (IdePreferencesPage *self,
+ IdePreferencesGroup *group);
+IdePreferencesGroup *ide_preferences_page_get_group (IdePreferencesPage *self,
+ const gchar *group_name);
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_PAGE_H */
diff --git a/libide/preferences/ide-preferences-perspective.c
b/libide/preferences/ide-preferences-perspective.c
new file mode 100644
index 0000000..2a80e7f
--- /dev/null
+++ b/libide/preferences/ide-preferences-perspective.c
@@ -0,0 +1,607 @@
+/* ide-preferences-perspective.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-preferences-perspective"
+
+#include <glib/gi18n.h>
+
+#include "ide-perspective.h"
+#include "ide-preferences.h"
+#include "ide-preferences-builtin.h"
+#include "ide-preferences-container.h"
+#include "ide-preferences-font-button.h"
+#include "ide-preferences-group.h"
+#include "ide-preferences-page.h"
+#include "ide-preferences-perspective.h"
+#include "ide-preferences-spin-button.h"
+#include "ide-preferences-switch.h"
+#include "ide-workbench-header-bar.h"
+
+struct _IdePreferencesPerspective
+{
+ GtkBin parent_instance;
+
+ guint last_widget_id;
+
+ GSequence *pages;
+ GHashTable *widgets;
+
+ GtkStack *page_stack;
+ GtkStackSwitcher *page_stack_sidebar;
+ IdeWorkbenchHeaderBar *titlebar;
+};
+
+static void ide_preferences_iface_init (IdePreferencesInterface *iface);
+static void ide_perspective_iface_init (IdePerspectiveInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (IdePreferencesPerspective, ide_preferences_perspective, GTK_TYPE_BIN, 0,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES, ide_preferences_iface_init)
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE, ide_perspective_iface_init))
+
+enum {
+ PROP_0,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static gint
+sort_by_priority (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ gint prioritya = 0;
+ gint priorityb = 0;
+
+ g_object_get ((gpointer)a, "priority", &prioritya, NULL);
+ g_object_get ((gpointer)b, "priority", &priorityb, NULL);
+
+ return prioritya - priorityb;
+}
+
+static void
+ide_preferences_perspective_constructed (GObject *object)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)object;
+
+ G_OBJECT_CLASS (ide_preferences_perspective_parent_class)->constructed (object);
+
+ _ide_preferences_builtin_register (IDE_PREFERENCES (self));
+}
+
+static void
+ide_preferences_perspective_finalize (GObject *object)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)object;
+
+ g_clear_pointer (&self->pages, g_sequence_free);
+ g_clear_pointer (&self->widgets, g_hash_table_unref);
+
+ G_OBJECT_CLASS (ide_preferences_perspective_parent_class)->finalize (object);
+}
+
+static void
+ide_preferences_perspective_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ //IdePreferencesPerspective *self = IDE_PREFERENCES_PERSPECTIVE (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_perspective_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ //IdePreferencesPerspective *self = IDE_PREFERENCES_PERSPECTIVE (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_perspective_class_init (IdePreferencesPerspectiveClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = ide_preferences_perspective_constructed;
+ object_class->finalize = ide_preferences_perspective_finalize;
+ object_class->get_property = ide_preferences_perspective_get_property;
+ object_class->set_property = ide_preferences_perspective_set_property;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-preferences-perspective.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, page_stack_sidebar);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, page_stack);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, titlebar);
+}
+
+static void
+ide_preferences_perspective_init (IdePreferencesPerspective *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->pages = g_sequence_new (NULL);
+ self->widgets = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+static void
+ide_preferences_perspective_add_page (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *title,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesPage *page;
+ GSequenceIter *iter;
+
+ g_assert (IDE_IS_PREFERENCES (preferences));
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (title != NULL);
+
+ if (gtk_stack_get_child_by_name (self->page_stack, page_name))
+ {
+ g_warning ("A preference page named %s has already been registered.",
+ page_name);
+ return;
+ }
+
+ page = g_object_new (IDE_TYPE_PREFERENCES_PAGE,
+ "priority", priority,
+ "visible", TRUE,
+ NULL);
+ iter = g_sequence_insert_sorted (self->pages, page, sort_by_priority, NULL);
+ gtk_container_add_with_properties (GTK_CONTAINER (self->page_stack), GTK_WIDGET (page),
+ "position", g_sequence_iter_get_position (iter),
+ "name", page_name,
+ "title", title,
+ NULL);
+}
+
+static void
+ide_preferences_perspective_add_group (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesGroup *group;
+ GtkWidget *page;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return;
+ }
+
+ group = g_object_new (IDE_TYPE_PREFERENCES_GROUP,
+ "name", group_name,
+ "priority", priority,
+ "title", title,
+ "visible", TRUE,
+ NULL);
+ ide_preferences_page_add_group (IDE_PREFERENCES_PAGE (page), group);
+}
+
+static void
+ide_preferences_perspective_add_list_group (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesGroup *group;
+ GtkWidget *page;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return;
+ }
+
+ group = g_object_new (IDE_TYPE_PREFERENCES_GROUP,
+ "is-list", TRUE,
+ "name", group_name,
+ "priority", priority,
+ "title", title,
+ "visible", TRUE,
+ NULL);
+ ide_preferences_page_add_group (IDE_PREFERENCES_PAGE (page), group);
+}
+
+static guint
+ide_preferences_perspective_add_radio (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesSwitch *widget;
+ IdePreferencesGroup *group;
+ g_autoptr(GVariant) variant = NULL;
+ GtkWidget *page;
+ guint widget_id;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+ g_assert (schema_id != NULL);
+ g_assert (key != NULL);
+ g_assert (title != NULL);
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return 0;
+ }
+
+ group = ide_preferences_page_get_group (IDE_PREFERENCES_PAGE (page), group_name);
+
+ if (group == NULL)
+ {
+ g_warning ("No such preferences group \"%s\" in page \"%s\"",
+ group_name, page_name);
+ return 0;
+ }
+
+ if (variant_string != NULL)
+ {
+ g_autoptr(GError) error = NULL;
+
+ variant = g_variant_parse (NULL, variant_string, NULL, NULL, &error);
+
+ if (variant == NULL)
+ g_warning ("%s", error->message);
+ else
+ g_variant_ref_sink (variant);
+ }
+
+ widget = g_object_new (IDE_TYPE_PREFERENCES_SWITCH,
+ "key", key,
+ "keywords", keywords,
+ "priority", priority,
+ "is-radio", TRUE,
+ "schema-id", schema_id,
+ "subtitle", subtitle,
+ "target", variant,
+ "title", title,
+ "visible", TRUE,
+ NULL);
+
+ ide_preferences_group_add (group, GTK_WIDGET (widget));
+
+ widget_id = ++self->last_widget_id;
+ g_hash_table_insert (self->widgets, GINT_TO_POINTER (widget_id), widget);
+
+ return widget_id;
+}
+
+static guint
+ide_preferences_perspective_add_switch (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesSwitch *widget;
+ IdePreferencesGroup *group;
+ g_autoptr(GVariant) variant = NULL;
+ GtkWidget *page;
+ guint widget_id;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+ g_assert (schema_id != NULL);
+ g_assert (key != NULL);
+ g_assert (title != NULL);
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return 0;
+ }
+
+ group = ide_preferences_page_get_group (IDE_PREFERENCES_PAGE (page), group_name);
+
+ if (group == NULL)
+ {
+ g_warning ("No such preferences group \"%s\" in page \"%s\"",
+ group_name, page_name);
+ return 0;
+ }
+
+ if (variant_string != NULL)
+ {
+ g_autoptr(GError) error = NULL;
+
+ variant = g_variant_parse (NULL, variant_string, NULL, NULL, &error);
+
+ if (variant == NULL)
+ g_warning ("%s", error->message);
+ else
+ g_variant_ref_sink (variant);
+ }
+
+ widget = g_object_new (IDE_TYPE_PREFERENCES_SWITCH,
+ "key", key,
+ "keywords", keywords,
+ "priority", priority,
+ "schema-id", schema_id,
+ "subtitle", subtitle,
+ "title", title,
+ "target", variant,
+ "visible", TRUE,
+ NULL);
+
+ ide_preferences_group_add (group, GTK_WIDGET (widget));
+
+ widget_id = ++self->last_widget_id;
+ g_hash_table_insert (self->widgets, GINT_TO_POINTER (widget_id), widget);
+
+ return widget_id;
+}
+
+static guint
+ide_preferences_perspective_add_spin_button (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesSpinButton *widget;
+ IdePreferencesGroup *group;
+ GtkWidget *page;
+ guint widget_id;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+ g_assert (schema_id != NULL);
+ g_assert (key != NULL);
+ g_assert (title != NULL);
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return 0;
+ }
+
+ group = ide_preferences_page_get_group (IDE_PREFERENCES_PAGE (page), group_name);
+
+
+ if (group == NULL)
+ {
+ g_warning ("No such preferences group \"%s\" in page \"%s\"",
+ group_name, page_name);
+ return 0;
+ }
+
+ widget = g_object_new (IDE_TYPE_PREFERENCES_SPIN_BUTTON,
+ "key", key,
+ "keywords", keywords,
+ "priority", priority,
+ "schema-id", schema_id,
+ "subtitle", subtitle,
+ "title", title,
+ "visible", TRUE,
+ NULL);
+
+ ide_preferences_group_add (group, GTK_WIDGET (widget));
+
+ widget_id = ++self->last_widget_id;
+ g_hash_table_insert (self->widgets, GINT_TO_POINTER (widget_id), widget);
+
+ return widget_id;
+}
+
+static guint
+ide_preferences_perspective_add_font_button (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *keywords,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesSwitch *widget;
+ IdePreferencesGroup *group;
+ GtkWidget *page;
+ guint widget_id;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+ g_assert (schema_id != NULL);
+ g_assert (key != NULL);
+ g_assert (title != NULL);
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return 0;
+ }
+
+ group = ide_preferences_page_get_group (IDE_PREFERENCES_PAGE (page), group_name);
+
+ if (group == NULL)
+ {
+ g_warning ("No such preferences group \"%s\" in page \"%s\"",
+ group_name, page_name);
+ return 0;
+ }
+
+ widget = g_object_new (IDE_TYPE_PREFERENCES_FONT_BUTTON,
+ "key", key,
+ "keywords", keywords,
+ "priority", priority,
+ "schema-id", schema_id,
+ "title", title,
+ "visible", TRUE,
+ NULL);
+
+ ide_preferences_group_add (group, GTK_WIDGET (widget));
+
+ widget_id = ++self->last_widget_id;
+ g_hash_table_insert (self->widgets, GINT_TO_POINTER (widget_id), widget);
+
+ return widget_id;
+}
+
+static guint
+ide_preferences_perspective_add_custom (IdePreferences *preferences,
+ const gchar *page_name,
+ const gchar *group_name,
+ GtkWidget *widget,
+ const gchar *keywords,
+ gint priority)
+{
+ IdePreferencesPerspective *self = (IdePreferencesPerspective *)preferences;
+ IdePreferencesContainer *container;
+ IdePreferencesGroup *group;
+ GtkWidget *page;
+ guint widget_id;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (page_name != NULL);
+ g_assert (group_name != NULL);
+ g_assert (GTK_IS_WIDGET (widget));
+
+ page = gtk_stack_get_child_by_name (self->page_stack, page_name);
+
+ if (page == NULL)
+ {
+ g_warning ("No page named \"%s\" could be found.", page_name);
+ return 0;
+ }
+
+ group = ide_preferences_page_get_group (IDE_PREFERENCES_PAGE (page), group_name);
+
+ if (group == NULL)
+ {
+ g_warning ("No such preferences group \"%s\" in page \"%s\"",
+ group_name, page_name);
+ return 0;
+ }
+
+ container = g_object_new (IDE_TYPE_PREFERENCES_CONTAINER,
+ "child", widget,
+ "keywords", keywords,
+ "priority", priority,
+ "visible", TRUE,
+ NULL);
+
+ ide_preferences_group_add (group, GTK_WIDGET (container));
+
+ widget_id = ++self->last_widget_id;
+ g_hash_table_insert (self->widgets, GINT_TO_POINTER (widget_id), widget);
+
+ return widget_id;
+}
+
+static void
+ide_preferences_iface_init (IdePreferencesInterface *iface)
+{
+ iface->add_page = ide_preferences_perspective_add_page;
+ iface->add_group = ide_preferences_perspective_add_group;
+ iface->add_list_group = ide_preferences_perspective_add_list_group ;
+ iface->add_radio = ide_preferences_perspective_add_radio;
+ iface->add_font_button = ide_preferences_perspective_add_font_button;
+ iface->add_switch = ide_preferences_perspective_add_switch;
+ iface->add_spin_button = ide_preferences_perspective_add_spin_button;
+ iface->add_custom = ide_preferences_perspective_add_custom;
+}
+
+static gchar *
+ide_preferences_perspective_get_title (IdePerspective *perspective)
+{
+ return g_strdup (_("Preferences"));
+}
+
+static gchar *
+ide_preferences_perspective_get_icon_name (IdePerspective *perspective)
+{
+ return g_strdup ("preferences-system-symbolic");
+}
+
+static GtkWidget *
+ide_preferences_perspective_get_titlebar (IdePerspective *perspective)
+{
+ return GTK_WIDGET (IDE_PREFERENCES_PERSPECTIVE (perspective)->titlebar);
+}
+
+static void
+ide_perspective_iface_init (IdePerspectiveInterface *iface)
+{
+ iface->get_icon_name = ide_preferences_perspective_get_icon_name;
+ iface->get_title = ide_preferences_perspective_get_title;
+ iface->get_titlebar = ide_preferences_perspective_get_titlebar;
+}
diff --git a/libide/preferences/ide-preferences-perspective.h
b/libide/preferences/ide-preferences-perspective.h
new file mode 100644
index 0000000..c5b2a4b
--- /dev/null
+++ b/libide/preferences/ide-preferences-perspective.h
@@ -0,0 +1,32 @@
+/* ide-preferences-perspective.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_PERSPECTIVE_H
+#define IDE_PREFERENCES_PERSPECTIVE_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_PERSPECTIVE (ide_preferences_perspective_get_type())
+
+G_DECLARE_FINAL_TYPE (IdePreferencesPerspective, ide_preferences_perspective, IDE, PREFERENCES_PERSPECTIVE,
GtkBin)
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_PERSPECTIVE_H */
diff --git a/libide/preferences/ide-preferences-spin-button.c
b/libide/preferences/ide-preferences-spin-button.c
new file mode 100644
index 0000000..0f67def
--- /dev/null
+++ b/libide/preferences/ide-preferences-spin-button.c
@@ -0,0 +1,93 @@
+/* ide-preferences-spin-button.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include "ide-preferences-spin-button.h"
+
+struct _IdePreferencesSpinButton
+{
+ GtkBin parent_instance;
+
+ GtkSpinButton *spin_button;
+};
+
+G_DEFINE_TYPE (IdePreferencesSpinButton, ide_preferences_spin_button, GTK_TYPE_BIN)
+
+enum {
+ PROP_0,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_preferences_spin_button_finalize (GObject *object)
+{
+ IdePreferencesSpinButton *self = (IdePreferencesSpinButton *)object;
+
+ G_OBJECT_CLASS (ide_preferences_spin_button_parent_class)->finalize (object);
+}
+
+static void
+ide_preferences_spin_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesSpinButton *self = IDE_PREFERENCES_SPIN_BUTTON (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_spin_button_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesSpinButton *self = IDE_PREFERENCES_SPIN_BUTTON (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_spin_button_class_init (IdePreferencesSpinButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_preferences_spin_button_finalize;
+ object_class->get_property = ide_preferences_spin_button_get_property;
+ object_class->set_property = ide_preferences_spin_button_set_property;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-preferences-spin-button.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesSpinButton, spin_button);
+}
+
+static void
+ide_preferences_spin_button_init (IdePreferencesSpinButton *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/libide/preferences/ide-preferences-spin-button.h
b/libide/preferences/ide-preferences-spin-button.h
new file mode 100644
index 0000000..07beec5
--- /dev/null
+++ b/libide/preferences/ide-preferences-spin-button.h
@@ -0,0 +1,32 @@
+/* ide-preferences-spin-button.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_SPIN_BUTTON_H
+#define IDE_PREFERENCES_SPIN_BUTTON_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_SPIN_BUTTON (ide_preferences_spin_button_get_type())
+
+G_DECLARE_FINAL_TYPE (IdePreferencesSpinButton, ide_preferences_spin_button, IDE, PREFERENCES_SPIN_BUTTON,
GtkBin)
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_SPIN_BUTTON_H */
diff --git a/libide/preferences/ide-preferences-switch.c b/libide/preferences/ide-preferences-switch.c
new file mode 100644
index 0000000..ca68192
--- /dev/null
+++ b/libide/preferences/ide-preferences-switch.c
@@ -0,0 +1,269 @@
+/* ide-preferences-switch.c
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#include "ide-preferences-switch.h"
+
+struct _IdePreferencesSwitch
+{
+ IdePreferencesContainer parent_instance;
+
+ guint is_radio : 1;
+
+ gchar *key;
+ gchar *schema_id;
+ GSettings *settings;
+ GVariant *target;
+
+ GtkLabel *subtitle;
+ GtkLabel *title;
+ GtkSwitch *widget;
+ GtkImage *image;
+};
+
+G_DEFINE_TYPE (IdePreferencesSwitch, ide_preferences_switch, IDE_TYPE_PREFERENCES_CONTAINER)
+
+enum {
+ PROP_0,
+ PROP_IS_RADIO,
+ PROP_SUBTITLE,
+ PROP_TARGET,
+ PROP_TITLE,
+ PROP_SCHEMA_ID,
+ PROP_KEY,
+ LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_preferences_switch_changed (IdePreferencesSwitch *self,
+ const gchar *key,
+ GSettings *settings)
+{
+ GVariant *value;
+ gboolean active;
+
+ g_assert (IDE_IS_PREFERENCES_SWITCH (self));
+ g_assert (key != NULL);
+ g_assert (G_IS_SETTINGS (settings));
+
+ value = g_settings_get_value (settings, key);
+ active = g_variant_equal (value, self->target);
+
+ gtk_switch_set_active (self->widget, active);
+ gtk_widget_set_visible (GTK_WIDGET (self->image), active);
+}
+
+static void
+ide_preferences_switch_constructed (GObject *object)
+{
+ IdePreferencesSwitch *self = (IdePreferencesSwitch *)object;
+ GSettingsSchemaSource *source;
+ g_autoptr(GSettingsSchema) schema = NULL;
+ g_autofree gchar *signal_detail = NULL;
+
+ g_assert (IDE_IS_PREFERENCES_SWITCH (self));
+
+ source = g_settings_schema_source_get_default ();
+ schema = g_settings_schema_source_lookup (source, self->schema_id, TRUE);
+
+ if (schema == NULL || !g_settings_schema_has_key (schema, self->key))
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ goto chainup;
+ }
+
+ self->settings = g_settings_new (self->schema_id);
+ signal_detail = g_strdup_printf ("changed::%s", self->key);
+
+ g_signal_connect_object (self->settings,
+ signal_detail,
+ G_CALLBACK (ide_preferences_switch_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ ide_preferences_switch_changed (self, self->key, self->settings);
+
+chainup:
+ G_OBJECT_CLASS (ide_preferences_switch_parent_class)->constructed (object);
+}
+
+static void
+ide_preferences_switch_finalize (GObject *object)
+{
+ IdePreferencesSwitch *self = (IdePreferencesSwitch *)object;
+
+ g_clear_pointer (&self->key, g_free);
+ g_clear_pointer (&self->schema_id, g_free);
+ g_clear_pointer (&self->target, g_variant_unref);
+ g_clear_object (&self->settings);
+
+ G_OBJECT_CLASS (ide_preferences_switch_parent_class)->finalize (object);
+}
+
+static void
+ide_preferences_switch_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesSwitch *self = IDE_PREFERENCES_SWITCH (object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_RADIO:
+ g_value_set_boolean (value, self->is_radio);
+ break;
+
+ case PROP_SCHEMA_ID:
+ g_value_set_string (value, self->schema_id);
+ break;
+
+ case PROP_KEY:
+ g_value_set_string (value, self->key);
+ break;
+
+ case PROP_TARGET:
+ g_value_set_variant (value, self->target);
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, gtk_label_get_label (self->title));
+ break;
+
+ case PROP_SUBTITLE:
+ g_value_set_string (value, gtk_label_get_label (self->subtitle));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_switch_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdePreferencesSwitch *self = IDE_PREFERENCES_SWITCH (object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_RADIO:
+ self->is_radio = g_value_get_boolean (value);
+ gtk_widget_set_visible (GTK_WIDGET (self->widget), !self->is_radio);
+ gtk_widget_set_visible (GTK_WIDGET (self->image), self->is_radio);
+ break;
+
+ case PROP_SCHEMA_ID:
+ self->schema_id = g_value_dup_string (value);
+ break;
+
+ case PROP_KEY:
+ self->key = g_value_dup_string (value);
+ break;
+
+ case PROP_TARGET:
+ self->target = g_value_dup_variant (value);
+ break;
+
+ case PROP_TITLE:
+ gtk_label_set_label (self->title, g_value_get_string (value));
+ break;
+
+ case PROP_SUBTITLE:
+ g_object_set (self->subtitle,
+ "label", g_value_get_string (value),
+ "visible", !!g_value_get_string (value),
+ NULL);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_preferences_switch_class_init (IdePreferencesSwitchClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = ide_preferences_switch_constructed;
+ object_class->finalize = ide_preferences_switch_finalize;
+ object_class->get_property = ide_preferences_switch_get_property;
+ object_class->set_property = ide_preferences_switch_set_property;
+
+ properties [PROP_IS_RADIO] =
+ g_param_spec_boolean ("is-radio",
+ "Is Radio",
+ "If a radio style should be used instead of a switch.",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_SCHEMA_ID] =
+ g_param_spec_string ("schema-id",
+ "Schema Id",
+ "Schema Id",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_TARGET] =
+ g_param_spec_variant ("target",
+ "Target",
+ "Target",
+ G_VARIANT_TYPE_ANY,
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_KEY] =
+ g_param_spec_string ("key",
+ "Key",
+ "Key",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_TITLE] =
+ g_param_spec_string ("title",
+ "Title",
+ "Title",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_SUBTITLE] =
+ g_param_spec_string ("subtitle",
+ "Subtitle",
+ "Subtitle",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-preferences-switch.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesSwitch, image);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesSwitch, subtitle);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesSwitch, title);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesSwitch, widget);
+}
+
+static void
+ide_preferences_switch_init (IdePreferencesSwitch *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/libide/preferences/ide-preferences-switch.h b/libide/preferences/ide-preferences-switch.h
new file mode 100644
index 0000000..f4b2cdd
--- /dev/null
+++ b/libide/preferences/ide-preferences-switch.h
@@ -0,0 +1,32 @@
+/* ide-preferences-switch.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_SWITCH_H
+#define IDE_PREFERENCES_SWITCH_H
+
+#include "ide-preferences-container.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES_SWITCH (ide_preferences_switch_get_type())
+
+G_DECLARE_FINAL_TYPE (IdePreferencesSwitch, ide_preferences_switch, IDE, PREFERENCES_SWITCH,
IdePreferencesContainer)
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_SWITCH_H */
diff --git a/libide/ide-preferences.c b/libide/preferences/ide-preferences.c
similarity index 51%
rename from libide/ide-preferences.c
rename to libide/preferences/ide-preferences.c
index eaae59d..3253773 100644
--- a/libide/ide-preferences.c
+++ b/libide/preferences/ide-preferences.c
@@ -48,7 +48,6 @@ ide_preferences_add_group (IdePreferences *self,
g_return_if_fail (IDE_IS_PREFERENCES (self));
g_return_if_fail (page_name != NULL);
g_return_if_fail (group_name != NULL);
- g_return_if_fail (title != NULL);
IDE_PREFERENCES_GET_IFACE (self)->add_group (self, page_name, group_name, title, priority);
}
@@ -59,6 +58,7 @@ ide_preferences_add_switch (IdePreferences *self,
const gchar *group_name,
const gchar *schema_id,
const gchar *key,
+ const gchar *variant_string,
const gchar *title,
const gchar *subtitle,
const gchar *keywords,
@@ -71,20 +71,19 @@ ide_preferences_add_switch (IdePreferences *self,
g_return_val_if_fail (key != NULL, 0);
g_return_val_if_fail (title != NULL, 0);
- return IDE_PREFERENCES_GET_IFACE (self)->add_switch (self, page_name, group_name, schema_id, key,
- title, subtitle, keywords, priority);
+ return IDE_PREFERENCES_GET_IFACE (self)->add_switch (self, page_name, group_name, schema_id, key,
variant_string, title, subtitle, keywords, priority);
}
guint
-ide_preferences_add_spinbutton (IdePreferences *self,
- const gchar *page_name,
- const gchar *group_name,
- const gchar *schema_id,
- const gchar *key,
- const gchar *title,
- const gchar *subtitle,
- const gchar *keywords,
- gint priority)
+ide_preferences_add_spin_button (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority)
{
g_return_val_if_fail (IDE_IS_PREFERENCES (self), 0);
g_return_val_if_fail (page_name != NULL, 0);
@@ -93,9 +92,7 @@ ide_preferences_add_spinbutton (IdePreferences *self,
g_return_val_if_fail (key != NULL, 0);
g_return_val_if_fail (title != NULL, 0);
- return IDE_PREFERENCES_GET_IFACE (self)->add_spinbutton (self, page_name, group_name, schema_id,
- key, title, subtitle, keywords,
- priority);
+ return IDE_PREFERENCES_GET_IFACE (self)->add_spin_button (self, page_name, group_name, schema_id, key,
title, subtitle, keywords, priority);
}
guint
@@ -111,6 +108,60 @@ ide_preferences_add_custom (IdePreferences *self,
g_return_val_if_fail (group_name != NULL, 0);
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- return IDE_PREFERENCES_GET_IFACE (self)->add_custom (self, page_name, group_name, widget,
- keywords, priority);
+ return IDE_PREFERENCES_GET_IFACE (self)->add_custom (self, page_name, group_name, widget, keywords,
priority);
+}
+
+void
+ide_preferences_add_list_group (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority)
+{
+ g_return_if_fail (IDE_IS_PREFERENCES (self));
+ g_return_if_fail (page_name != NULL);
+ g_return_if_fail (group_name != NULL);
+
+ return IDE_PREFERENCES_GET_IFACE (self)->add_list_group (self, page_name, group_name, title, priority);
+}
+
+guint ide_preferences_add_radio (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority)
+{
+ g_return_val_if_fail (IDE_IS_PREFERENCES (self), 0);
+ g_return_val_if_fail (page_name != NULL, 0);
+ g_return_val_if_fail (group_name != NULL, 0);
+ g_return_val_if_fail (schema_id != NULL, 0);
+ g_return_val_if_fail (key != NULL, 0);
+ g_return_val_if_fail (title != NULL, 0);
+
+ return IDE_PREFERENCES_GET_IFACE (self)->add_radio (self, page_name, group_name, schema_id, key,
variant_string, title, subtitle, keywords, priority);
+}
+
+guint
+ide_preferences_add_font_button (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *keywords,
+ gint priority)
+{
+ g_return_val_if_fail (IDE_IS_PREFERENCES (self), 0);
+ g_return_val_if_fail (page_name != NULL, 0);
+ g_return_val_if_fail (group_name != NULL, 0);
+ g_return_val_if_fail (schema_id != NULL, 0);
+ g_return_val_if_fail (key != NULL, 0);
+ g_return_val_if_fail (title != NULL, 0);
+
+ return IDE_PREFERENCES_GET_IFACE (self)->add_font_button (self, page_name, group_name, schema_id, key,
title, keywords, priority);
}
diff --git a/libide/preferences/ide-preferences.h b/libide/preferences/ide-preferences.h
new file mode 100644
index 0000000..1c56a3d
--- /dev/null
+++ b/libide/preferences/ide-preferences.h
@@ -0,0 +1,153 @@
+/* ide-preferences.h
+ *
+ * Copyright (C) 2015 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/>.
+ */
+
+#ifndef IDE_PREFERENCES_H
+#define IDE_PREFERENCES_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_PREFERENCES (ide_preferences_get_type())
+
+G_DECLARE_INTERFACE (IdePreferences, ide_preferences, IDE, PREFERENCES, GObject)
+
+struct _IdePreferencesInterface
+{
+ GTypeInterface parent_interface;
+
+ void (*add_page) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *title,
+ gint priority);
+ void (*add_group) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority);
+ void (*add_list_group ) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority);
+ guint (*add_radio) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority);
+ guint (*add_font_button) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *keywords,
+ gint priority);
+ guint (*add_switch) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority);
+ guint (*add_spin_button) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority);
+ guint (*add_custom) (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ GtkWidget *widget,
+ const gchar *keywords,
+ gint priority);
+};
+
+void ide_preferences_add_page (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *title,
+ gint priority);
+void ide_preferences_add_group (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority);
+void ide_preferences_add_list_group (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *title,
+ gint priority);
+guint ide_preferences_add_radio (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority);
+guint ide_preferences_add_switch (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *variant_string,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority);
+guint ide_preferences_add_spin_button (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *subtitle,
+ const gchar *keywords,
+ gint priority);
+guint ide_preferences_add_custom (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ GtkWidget *widget,
+ const gchar *keywords,
+ gint priority);
+guint ide_preferences_add_font_button (IdePreferences *self,
+ const gchar *page_name,
+ const gchar *group_name,
+ const gchar *schema_id,
+ const gchar *key,
+ const gchar *title,
+ const gchar *keywords,
+ gint priority);
+
+G_END_DECLS
+
+#endif /* IDE_PREFERENCES_H */
diff --git a/libide/resources/libide.gresource.xml b/libide/resources/libide.gresource.xml
index 55ee581..24b9646 100644
--- a/libide/resources/libide.gresource.xml
+++ b/libide/resources/libide.gresource.xml
@@ -25,6 +25,11 @@
<file alias="ui/ide-editor-perspective.ui">../../data/ui/ide-editor-perspective.ui</file>
<file alias="ui/ide-greeter-perspective.ui">../../data/ui/ide-greeter-perspective.ui</file>
<file alias="ui/ide-greeter-project-row.ui">../../data/ui/ide-greeter-project-row.ui</file>
+ <file alias="ui/ide-preferences-font-button.ui">../../data/ui/ide-preferences-font-button.ui</file>
+ <file alias="ui/ide-preferences-page.ui">../../data/ui/ide-preferences-page.ui</file>
+ <file alias="ui/ide-preferences-perspective.ui">../../data/ui/ide-preferences-perspective.ui</file>
+ <file alias="ui/ide-preferences-group.ui">../../data/ui/ide-preferences-group.ui</file>
+ <file alias="ui/ide-preferences-switch.ui">../../data/ui/ide-preferences-switch.ui</file>
<file alias="ui/ide-workbench.ui">../../data/ui/ide-workbench.ui</file>
<file alias="ui/ide-workbench-header-bar.ui">../../data/ui/ide-workbench-header-bar.ui</file>
</gresource>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]