mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 18:30:08 +00:00
gtk-demo: Add alternative settings demo
This one displays a long list of all settings with sections and allows filtering the list to quickly search for keys.
This commit is contained in:
parent
435a405c55
commit
ddefbfa8b5
@ -195,6 +195,9 @@
|
||||
<gresource prefix="/listview_settings">
|
||||
<file>listview_settings.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listview_settings2">
|
||||
<file>listview_settings2.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listview_ucd_data/">
|
||||
<file>ucdnames.data</file>
|
||||
</gresource>
|
||||
@ -312,6 +315,7 @@
|
||||
<file>listview_minesweeper.c</file>
|
||||
<file>listview_selections.c</file>
|
||||
<file>listview_settings.c</file>
|
||||
<file>listview_settings2.c</file>
|
||||
<file>listview_ucd.c</file>
|
||||
<file>listview_weather.c</file>
|
||||
<file>listview_words.c</file>
|
||||
|
230
demos/gtk-demo/listview_settings2.c
Normal file
230
demos/gtk-demo/listview_settings2.c
Normal file
@ -0,0 +1,230 @@
|
||||
/* Lists/Settings v2
|
||||
* #Keywords: GtkListHeaderFactory, GtkSectionModel
|
||||
*
|
||||
* This demo shows a settings viewer for GSettings.
|
||||
*
|
||||
* It demonstrates how to implement support for sections with GtkListView.
|
||||
*
|
||||
* It also shows how to quickly flatten a large tree of items into a list
|
||||
* that can be filtered to find the itmes one is looking for.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "settings-key.h"
|
||||
|
||||
static void
|
||||
item_value_changed (GtkEditableLabel *label,
|
||||
GParamSpec *pspec,
|
||||
GtkColumnViewCell *cell)
|
||||
{
|
||||
SettingsKey *self;
|
||||
GSettingsSchemaKey *key;
|
||||
const char *text;
|
||||
const GVariantType *type;
|
||||
GVariant *variant;
|
||||
GError *error = NULL;
|
||||
const char *name;
|
||||
char *value;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (label));
|
||||
|
||||
self = gtk_column_view_cell_get_item (cell);
|
||||
key = settings_key_get_key (self);
|
||||
|
||||
type = g_settings_schema_key_get_value_type (key);
|
||||
name = g_settings_schema_key_get_name (key);
|
||||
|
||||
variant = g_variant_parse (type, text, NULL, NULL, &error);
|
||||
if (!variant)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_clear_error (&error);
|
||||
goto revert;
|
||||
}
|
||||
|
||||
if (!g_settings_schema_key_range_check (key, variant))
|
||||
{
|
||||
g_warning ("Not a valid value for %s", name);
|
||||
goto revert;
|
||||
}
|
||||
|
||||
g_settings_set_value (settings_key_get_settings (self), name, variant);
|
||||
g_variant_unref (variant);
|
||||
return;
|
||||
|
||||
revert:
|
||||
gtk_widget_error_bell (GTK_WIDGET (label));
|
||||
|
||||
g_object_get (self, "value", &value, NULL);
|
||||
gtk_editable_set_text (GTK_EDITABLE (label), value);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
static int
|
||||
strvcmp (gconstpointer p1,
|
||||
gconstpointer p2)
|
||||
{
|
||||
const char * const *s1 = p1;
|
||||
const char * const *s2 = p2;
|
||||
|
||||
return strcmp (*s1, *s2);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
map_settings_to_keys (gpointer item,
|
||||
gpointer unused)
|
||||
{
|
||||
GSettings *settings = item;
|
||||
GSettingsSchema *schema;
|
||||
GListStore *store;
|
||||
char **keys;
|
||||
guint i;
|
||||
|
||||
g_object_get (settings, "settings-schema", &schema, NULL);
|
||||
|
||||
store = g_list_store_new (SETTINGS_TYPE_KEY);
|
||||
|
||||
keys = g_settings_schema_list_keys (schema);
|
||||
|
||||
for (i = 0; keys[i] != NULL; i++)
|
||||
{
|
||||
GSettingsSchemaKey *almost_there = g_settings_schema_get_key (schema, keys[i]);
|
||||
SettingsKey *finally = settings_key_new (settings, almost_there);
|
||||
g_list_store_append (store, finally);
|
||||
g_object_unref (finally);
|
||||
g_settings_schema_key_unref (almost_there);
|
||||
}
|
||||
|
||||
g_strfreev (keys);
|
||||
g_settings_schema_unref (schema);
|
||||
g_object_unref (settings);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
create_settings_model (gpointer item,
|
||||
gpointer unused)
|
||||
{
|
||||
GSettings *settings = item;
|
||||
char **schemas;
|
||||
GListStore *result;
|
||||
guint i;
|
||||
|
||||
if (settings == NULL)
|
||||
{
|
||||
g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (),
|
||||
TRUE,
|
||||
&schemas,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
schemas = g_settings_list_children (settings);
|
||||
}
|
||||
|
||||
if (schemas == NULL || schemas[0] == NULL)
|
||||
{
|
||||
g_free (schemas);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qsort (schemas, g_strv_length (schemas), sizeof (char *), strvcmp);
|
||||
|
||||
result = g_list_store_new (G_TYPE_SETTINGS);
|
||||
for (i = 0; schemas[i] != NULL; i++)
|
||||
{
|
||||
GSettings *child;
|
||||
|
||||
if (settings == NULL)
|
||||
child = g_settings_new (schemas[i]);
|
||||
else
|
||||
child = g_settings_get_child (settings, schemas[i]);
|
||||
|
||||
g_list_store_append (result, child);
|
||||
g_object_unref (child);
|
||||
}
|
||||
|
||||
g_strfreev (schemas);
|
||||
|
||||
return G_LIST_MODEL (result);
|
||||
}
|
||||
|
||||
static void
|
||||
search_enabled (GtkSearchEntry *entry)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), "");
|
||||
}
|
||||
|
||||
static void
|
||||
stop_search (GtkSearchEntry *entry,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), "");
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
do_listview_settings2 (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkListView *listview;
|
||||
GListModel *model;
|
||||
GtkTreeListModel *treemodel;
|
||||
GtkNoSelection *selection;
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
GError *error = NULL;
|
||||
GtkFilter *filter;
|
||||
|
||||
g_type_ensure (SETTINGS_TYPE_KEY);
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback (scope, search_enabled);
|
||||
gtk_builder_cscope_add_callback (scope, stop_search);
|
||||
gtk_builder_cscope_add_callback (scope, settings_key_get_search_string);
|
||||
gtk_builder_cscope_add_callback (scope, item_value_changed);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
g_object_unref (scope);
|
||||
|
||||
gtk_builder_add_from_resource (builder, "/listview_settings2/listview_settings2.ui", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
|
||||
listview = GTK_LIST_VIEW (gtk_builder_get_object (builder, "listview"));
|
||||
filter = GTK_FILTER (gtk_builder_get_object (builder, "filter"));
|
||||
|
||||
model = create_settings_model (NULL, NULL);
|
||||
treemodel = gtk_tree_list_model_new (model,
|
||||
TRUE,
|
||||
TRUE,
|
||||
create_settings_model,
|
||||
NULL,
|
||||
NULL);
|
||||
model = G_LIST_MODEL (gtk_map_list_model_new (G_LIST_MODEL (treemodel), map_settings_to_keys, NULL, NULL));
|
||||
model = G_LIST_MODEL (gtk_flatten_list_model_new (model));
|
||||
model = G_LIST_MODEL (gtk_filter_list_model_new (model, g_object_ref (filter)));
|
||||
selection = gtk_no_selection_new (model);
|
||||
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), GTK_SELECTION_MODEL (selection));
|
||||
g_object_unref (selection);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_set_visible (window, TRUE);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
130
demos/gtk-demo/listview_settings2.ui
Normal file
130
demos/gtk-demo/listview_settings2.ui
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkStringFilter" id="filter">
|
||||
<property name="expression">
|
||||
<closure type="gchararray" function="settings_key_get_search_string" />
|
||||
</property>
|
||||
<property name="search" bind-source="entry" bind-property="text" />
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">Settings</property>
|
||||
<property name="default-width">640</property>
|
||||
<property name="default-height">480</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="search_button">
|
||||
<property name="icon-name">system-search-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSearchBar">
|
||||
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional"/>
|
||||
<signal name="notify::search-mode-enabled" handler="search_enabled" object="entry"/>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="entry">
|
||||
<signal name="stop-search" handler="stop_search"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<property name="vexpand">1</property>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
<property name="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">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="name" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<binding name="label">
|
||||
<lookup name="summary" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">end</property>
|
||||
<binding name="text">
|
||||
<lookup name="value" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<signal name="notify::label" handler="item_value_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="header-factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListHeader">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="schema" type="GSettings">
|
||||
<lookup name="settings" type="SettingsKey">
|
||||
<lookup name="item">GtkListHeader</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@ -57,6 +57,7 @@ demos = files([
|
||||
'listview_minesweeper.c',
|
||||
'listview_selections.c',
|
||||
'listview_settings.c',
|
||||
'listview_settings2.c',
|
||||
'listview_ucd.c',
|
||||
'listview_weather.c',
|
||||
'listview_words.c',
|
||||
|
Loading…
Reference in New Issue
Block a user