--- a/gplugin-gtk4/gplugin-gtk-plugin-settings-list.c Thu Jan 05 22:37:06 2023 -0600
+++ b/gplugin-gtk4/gplugin-gtk-plugin-settings-list.c Tue Jan 17 01:39:15 2023 -0600
@@ -15,6 +15,8 @@
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
+#include <glib/gi18n-lib.h> #include <gplugin-gtk-plugin-settings-list.h>
@@ -51,39 +53,419 @@
/******************************************************************************
+ *****************************************************************************/ +gplugin_gtk_plugin_settings_row_byte_to_double( + G_GNUC_UNUSED gpointer data) + g_value_set_double(value, (gdouble)g_variant_get_byte(variant)); +gplugin_gtk_plugin_settings_row_double_to_byte( + G_GNUC_UNUSED const GVariantType *expected_type, + G_GNUC_UNUSED gpointer data) + return g_variant_new_byte((char)g_value_get_double(value)); +gplugin_gtk_plugin_settings_row_enum_to_selected( + GListModel *model = data; + const char *string = NULL; + string = g_variant_get_string(variant, NULL); + n_items = g_list_model_get_n_items(model); + for(guint index = 0; index < n_items; index++) { + GtkStringObject *obj = g_list_model_get_item(model, index); + if(g_str_equal(string, gtk_string_object_get_string(obj))) { + g_value_set_uint(value, index); +gplugin_gtk_plugin_settings_row_selected_to_enum( + G_GNUC_UNUSED const GVariantType *expected_type, + GListModel *model = data; + GtkStringObject *obj = NULL; + GVariant *result = NULL; + obj = g_list_model_get_item(model, g_value_get_uint(value)); + result = g_variant_new_string(gtk_string_object_get_string(obj)); +/****************************************************************************** *****************************************************************************/
+gplugin_gtk_plugin_settings_row_new_for_enum( + GtkWidget *dropdown = NULL; + const gchar **allowed_values = NULL; + GListModel *model = NULL; + allowed_values = g_variant_get_strv(range_value, NULL); + dropdown = gtk_drop_down_new_from_strings(allowed_values); + g_free(allowed_values); + model = gtk_drop_down_get_model(GTK_DROP_DOWN(dropdown)); + g_settings_bind_with_mapping( + G_SETTINGS_BIND_DEFAULT, + gplugin_gtk_plugin_settings_row_enum_to_selected, + gplugin_gtk_plugin_settings_row_selected_to_enum, +gplugin_gtk_plugin_settings_row_new_for_flags( + G_GNUC_UNUSED GSettings *settings, + G_GNUC_UNUSED const char *name, + G_GNUC_UNUSED GVariant *range_value) + GtkWidget *dropdown = NULL; + /* TODO: Implement this. */ + dropdown = gtk_label_new("Unimplemented flags setting"); +gplugin_gtk_plugin_settings_row_new_for_range( + GtkWidget *spin = NULL; + const char *type = NULL; + gdouble min, max, step; + /* By default, for integers, pick a step of 1, which in GtkSpinButton + * limits it to displaying only integers. */ + /* The range value is a tuple with a pair of the type of the expected value + * (e.g., "(ii)" for int16 or "(dd)" for double), so look at second + type = g_variant_get_type_string(range_value); + g_variant_get_child(range_value, 0, "y", &mini); + g_variant_get_child(range_value, 1, "y", &maxi); + g_variant_get_child(range_value, 0, "n", &mini); + g_variant_get_child(range_value, 1, "n", &maxi); + g_variant_get_child(range_value, 0, "q", &mini); + g_variant_get_child(range_value, 1, "q", &maxi); + g_variant_get_child(range_value, 0, "i", &mini); + g_variant_get_child(range_value, 1, "i", &maxi); + g_variant_get_child(range_value, 0, "u", &mini); + g_variant_get_child(range_value, 1, "u", &maxi); + g_variant_get_child(range_value, 0, "x", &mini); + g_variant_get_child(range_value, 1, "x", &maxi); + g_variant_get_child(range_value, 0, "t", &mini); + g_variant_get_child(range_value, 1, "t", &maxi); + /* For doubles, arbitrarily pick a step of 1% of the range. */ + g_variant_get_child(range_value, 0, "d", &min); + g_variant_get_child(range_value, 1, "d", &max); + step = (max - min) / 100; + g_warning("Unknown range type: %s", type); + spin = gtk_spin_button_new_with_range(min, max, step); + /* For some reason, Gio's default bindings understand + * double-to-int conversions for any bit size other than + * bytes, so manually set up mappings for bytes... */ + g_settings_bind_with_mapping( + G_SETTINGS_BIND_DEFAULT, + gplugin_gtk_plugin_settings_row_byte_to_double, + gplugin_gtk_plugin_settings_row_double_to_byte, + /* ... and use default binding everywhere else. */ + g_settings_bind(settings, name, spin, "value", G_SETTINGS_BIND_DEFAULT); +gplugin_gtk_plugin_settings_row_new_for_type( + GtkWidget *entry = NULL; + /* The range value is an array with type of the expected value (e.g., "ab" + * for boolean or "as" for string), so look at second character. */ + type = g_variant_get_type_string(range_value)[1]; + entry = gtk_switch_new(); + gtk_widget_set_halign(entry, GTK_ALIGN_END); + gtk_widget_set_valign(entry, GTK_ALIGN_CENTER); + G_SETTINGS_BIND_DEFAULT); + /* Set range for the spin button. */ + max = (gdouble)G_MAXINT64; + max = (gdouble)G_MAXUINT64; + entry = gtk_spin_button_new_with_range(min, max, 1.0); + /* For some reason, Gio's default bindings understand + * double-to-int conversions for any bit size other than + * bytes, so manually set up mappings for bytes... */ + g_settings_bind_with_mapping( + G_SETTINGS_BIND_DEFAULT, + gplugin_gtk_plugin_settings_row_byte_to_double, + gplugin_gtk_plugin_settings_row_double_to_byte, + /* ... and use default binding everywhere else. */ + G_SETTINGS_BIND_DEFAULT); + entry = gtk_spin_button_new(NULL, 1.0, 5); + G_SETTINGS_BIND_DEFAULT); + entry = gtk_entry_new(); + gtk_entry_get_buffer(GTK_ENTRY(entry)), + G_SETTINGS_BIND_DEFAULT); + entry = gtk_label_new(_("Unknown setting type")); gplugin_gtk_plugin_settings_row_new_for_key(
- GSettingsSchemaKey *key)
+ GSettingsSchemaKey *key, - /* TODO: Make real widgets. */
GtkWidget *widget = NULL;
- GVariant *value = NULL;
- char *value_str = NULL;
+ const char *summary = NULL; + GVariant *range = NULL; + gchar *range_type = NULL; + GVariant *range_value = NULL; widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
- label = gtk_label_new(g_settings_schema_key_get_name(key));
+ summary = g_settings_schema_key_get_summary(key); + label = gtk_label_new((summary != NULL) ? summary : name); gtk_label_set_xalign(GTK_LABEL(label), 0);
gtk_box_append(GTK_BOX(widget), label);
+ gtk_size_group_add_widget(sg, label); - value = g_settings_get_value(settings, name);
- value_str = g_variant_print(value, TRUE);
- g_variant_unref(value);
+ gtk_widget_set_tooltip_text( + g_settings_schema_key_get_description(key)); + range = g_settings_schema_key_get_range(key); + g_variant_get_child(range, 0, "s", &range_type); + g_variant_get_child(range, 1, "v", &range_value); - entry = gtk_entry_new();
- gtk_editable_set_text(GTK_EDITABLE(entry), value_str);
- gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
+ if(g_str_equal(range_type, "enum")) { + entry = gplugin_gtk_plugin_settings_row_new_for_enum( + } else if(g_str_equal(range_type, "flags")) { + entry = gplugin_gtk_plugin_settings_row_new_for_flags( + } else if(g_str_equal(range_type, "range")) { + entry = gplugin_gtk_plugin_settings_row_new_for_range( + } else if(g_str_equal(range_type, "type")) { + entry = gplugin_gtk_plugin_settings_row_new_for_type( + /* No other documented types for g_settings_schema_key_get_range. */ + entry = gtk_label_new(_("Unknown setting type")); + g_variant_unref(range_value); + g_variant_unref(range); gtk_widget_set_hexpand(entry, TRUE);
gtk_box_append(GTK_BOX(widget), entry);
@@ -94,6 +476,7 @@
GSettingsSchema *schema = NULL;
+ GtkSizeGroup *sg = NULL; gtk_list_box_remove(list->list_box, list->rows->data);
@@ -106,6 +489,7 @@
g_object_get(G_OBJECT(settings), "settings-schema", &schema, NULL);
names = g_settings_schema_list_keys(schema);
+ sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); for(gint i = 0; names[i] != NULL; i++) {
GSettingsSchemaKey *key = NULL;
@@ -116,7 +500,8 @@
widget = gplugin_gtk_plugin_settings_row_new_for_key(
row = gtk_list_box_row_new();
gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(row), widget);