[dconf-editor] Add a right-click menu.
- From: Arnaud Bonatti <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf-editor] Add a right-click menu.
- Date: Sat, 26 Sep 2015 18:13:31 +0000 (UTC)
commit e3a3f6a06fe9fb3ed8b3e43aeb492a6f96a7def9
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Sat Sep 26 20:12:44 2015 +0200
Add a right-click menu.
editor/dconf-view.vala | 98 +++++-----------------------
editor/dconf-window.vala | 163 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 179 insertions(+), 82 deletions(-)
---
diff --git a/editor/dconf-view.vala b/editor/dconf-view.vala
index d059d0e..c03d376 100644
--- a/editor/dconf-view.vala
+++ b/editor/dconf-view.vala
@@ -74,12 +74,12 @@ private class KeyEditor : Dialog
private KeyEditorChild create_child ()
{
if (key.schema.choices != null)
- return new KeyEditorChildChoices (key);
+ return new KeyEditorChildMulti (key);
switch (key.type_string)
{
case "<enum>":
- return new KeyEditorChildEnum (key);
+ return new KeyEditorChildMulti (key);
case "b":
return new KeyEditorChildBool (key.value.get_boolean ());
case "s":
@@ -171,18 +171,14 @@ public interface KeyEditorChild : Widget
private class KeyEditorChildMulti : Grid, KeyEditorChild
{
- private static const string ACTION_NAME = "key_value";
- private static const string GROUP_PREFIX = "bool_switch";
+ private ContextPopover popover;
- private SimpleAction action;
- private VariantType variant_type;
-
- private Grid grid;
- private MenuButton button;
- private Popover popover;
+ private Variant variant;
- public KeyEditorChildMulti ()
+ public KeyEditorChildMulti (Key key)
{
+ this.variant = key.value;
+
this.visible = true;
this.hexpand = true;
@@ -192,88 +188,28 @@ private class KeyEditorChildMulti : Grid, KeyEditorChild
label.hexpand = true;
this.attach (label, 0, 0, 1, 1);
- button = new MenuButton ();
+ MenuButton button = new MenuButton ();
button.visible = true;
button.use_popover = true;
button.halign = Align.END;
button.width_request = 100;
+ button.label = variant.get_type () == VariantType.STRING ? variant.get_string () : variant.print
(false);
this.attach (button, 1, 0, 1, 1);
- popover = new Popover (button);
- button.set_popover (popover);
-
- grid = new Grid ();
- grid.orientation = Orientation.VERTICAL;
- grid.visible = true;
- grid.row_homogeneous = true;
- // grid.width_request = 100;
- popover.add (grid);
- }
- protected void init (VariantType _type, Variant initial_value)
- {
- variant_type = _type;
- set_text (initial_value);
-
- action = new SimpleAction.stateful (ACTION_NAME, variant_type, initial_value);
- SimpleActionGroup group = new SimpleActionGroup ();
- ((ActionMap) group).add_action (action);
- grid.insert_action_group (GROUP_PREFIX, group);
-
- group.action_state_changed [ACTION_NAME].connect ((unknown_string, variant) => {
- set_text (variant);
+ popover = new ContextPopover ();
+ popover.create_buttons_list (key, false);
+ popover.set_relative_to (button);
+ popover.value_changed.connect ((bytes) => {
+ variant = new Variant.from_bytes (key.value.get_type (), bytes, true);
+ button.label = variant.get_type () == VariantType.STRING ? variant.get_string () :
variant.print (false);
popover.closed ();
});
- }
-
- private void set_text (Variant variant)
- {
- button.label = variant_type == VariantType.STRING ? variant.get_string () : variant.print (false);
- }
-
- protected void add_model_button (string text, Variant variant)
- {
- ModelButton button = new ModelButton ();
- button.visible = true;
- button.text = text;
- button.action_name = GROUP_PREFIX + "." + ACTION_NAME;
- button.action_target = variant;
- grid.add (button);
+ button.set_popover ((Popover) popover);
}
public Variant get_variant ()
{
- return action.get_state ();
- }
-}
-
-private class KeyEditorChildChoices : KeyEditorChildMulti
-{
- public KeyEditorChildChoices (Key key)
- {
- init (VariantType.ANY, key.value);
-
- foreach (SchemaChoice choice in key.schema.choices)
- add_model_button (choice.name, choice.value);
- }
-}
-
-private class KeyEditorChildEnum : KeyEditorChildMulti
-{
- public KeyEditorChildEnum (Key key)
- {
- init (VariantType.STRING, key.value);
-
- SchemaEnum schema_enum = key.schema.schema.list.enums.lookup (key.schema.enum_name);
- if (schema_enum.values.length () <= 0)
- assert_not_reached (); // TODO special case 0?
-// else if (schema_enum.values.length () == 1)
-// assert_not_reached (); // TODO
-
- for (uint index = 0; index < schema_enum.values.length (); index++)
- {
- string nick = schema_enum.values.nth_data (index).nick; // value.get_string ()); ?
key.value.get_string () ? key.value.print (false) ? nick ?
- add_model_button (nick, new Variant.string (nick));
- }
+ return variant;
}
}
diff --git a/editor/dconf-window.vala b/editor/dconf-window.vala
index 56f5365..afec874 100644
--- a/editor/dconf-window.vala
+++ b/editor/dconf-window.vala
@@ -69,6 +69,7 @@ class DConfWindow : ApplicationWindow
if (key.has_schema)
{
KeyListBoxRowEditable key_list_box_row = new KeyListBoxRowEditable (key);
+ key_list_box_row.button_press_event.connect (on_button_pressed);
key_list_box_row.show_dialog.connect (() => {
KeyEditor key_editor = new KeyEditor (key);
key_editor.set_transient_for (this);
@@ -79,6 +80,7 @@ class DConfWindow : ApplicationWindow
else
{
KeyListBoxRow key_list_box_row = new KeyListBoxRow.fixed_strings (key.name, key.cool_text_value
());
+ key_list_box_row.button_press_event.connect (on_button_pressed);
key_list_box_row.show_dialog.connect (() => {
MessageDialog dialog = new MessageDialog (this, DialogFlags.MODAL, MessageType.WARNING,
ButtonsType.OK, _("No Schema, cannot edit value.")); // TODO with or without punctuation? // TODO
insert key name/path/..?
dialog.run ();
@@ -86,6 +88,15 @@ class DConfWindow : ApplicationWindow
});
return key_list_box_row;
}
+ // TODO bug: list_box_row is always activated after the dialog destruction if mouse is over at this
time
+ }
+
+ private bool on_button_pressed (Widget widget, Gdk.EventButton event)
+ {
+ ListBoxRow list_box_row = (ListBoxRow) ((KeyListBoxRow) widget).get_parent ();
+ key_list_box.select_row (list_box_row);
+ list_box_row.grab_focus ();
+ return false;
}
[GtkCallback]
@@ -225,6 +236,30 @@ private class KeyListBoxRow : EventBox
key_value_label.label = key_value;
key_info_label.set_markup ("<i>" + _("No Schema") + "</i>");
}
+
+ protected ContextPopover? popover = null;
+ protected virtual bool generate_popover () { return false; }
+
+ public override bool button_press_event (Gdk.EventButton event) // list_box_row selection is done
elsewhere
+ {
+ if (event.button == Gdk.BUTTON_SECONDARY)
+ {
+ if (popover != null) // TODO remove? put in generate_popover?
+ popover.destroy ();
+ if (!generate_popover ())
+ return false;
+
+ Gdk.Rectangle rect;
+ popover.set_relative_to (this);
+ popover.position = PositionType.BOTTOM;
+ popover.get_pointing_to (out rect);
+ rect.x = (int) (event.x - this.get_allocated_width () / 2.0);
+ popover.set_pointing_to (rect);
+ popover.show ();
+ }
+
+ return false;
+ }
}
private class KeyListBoxRowEditable : KeyListBoxRow
@@ -249,7 +284,33 @@ private class KeyListBoxRowEditable : KeyListBoxRow
summary = dgettext (gettext_domain, summary);
key_info_label.label = summary.strip ();
- key.value_changed.connect (() => { update (); });
+ key.value_changed.connect (() => { update (); if (popover != null) popover.destroy (); });
+ }
+
+ protected override bool generate_popover ()
+ {
+ popover = new ContextPopover ();
+ popover.add_action_button (_("Customize…"), () => { show_dialog (); });
+ popover.add_action_button (_("Copy"), () => {
+ Clipboard clipboard = Clipboard.get_default (Gdk.Display.get_default ());
+ string copy = key.schema.schema.id + " " + key.name + " " + key.value.print (false);
+ clipboard.set_text (copy, copy.length);
+ });
+
+ if (key.type_string == "b" || key.type_string == "<enum>" || key.schema.choices != null)
+ {
+ popover.add_separator ();
+ popover.create_buttons_list (key, true);
+
+ popover.set_to_default.connect (() => { key.set_to_default (); popover.destroy (); });
+ popover.value_changed.connect ((bytes) => { key.value = new Variant.from_bytes
(key.value.get_type (), bytes, true); popover.destroy (); });
+ }
+ else if (!key.is_default)
+ {
+ popover.add_separator ();
+ popover.add_action_button (_("Set to default"), () => { key.set_to_default (); });
+ }
+ return true;
}
private void update ()
@@ -261,3 +322,103 @@ private class KeyListBoxRowEditable : KeyListBoxRow
key_value_label.label = key.cool_text_value ();
}
}
+
+private class ContextPopover : Popover
+{
+ public signal void set_to_default ();
+ public signal void value_changed (Bytes bytes);
+
+ private static const string ACTION_NAME = "key_value";
+ private static const string GROUP_PREFIX = "group";
+
+ private Grid grid;
+
+ public ContextPopover ()
+ {
+ grid = new Grid ();
+ grid.orientation = Orientation.VERTICAL;
+ grid.visible = true;
+ // grid.width_request = 100; // TODO
+ grid.margin = 4;
+ grid.row_spacing = 2;
+ this.add (grid);
+ }
+
+ public delegate void button_action ();
+ public void add_action_button (string label, button_action action)
+ {
+ ModelButton button = new ModelButton ();
+ button.visible = true;
+ button.text = label;
+ button.clicked.connect (() => { action (); });
+ grid.add (button);
+ }
+
+ public void add_separator ()
+ {
+ Separator separator = new Separator (Orientation.HORIZONTAL);
+ separator.visible = true;
+ grid.add (separator);
+ }
+
+ public void create_buttons_list (Key key, bool nullable)
+ {
+ if ("m" in key.value.get_type_string ()) // TODO better; is it really needed? ("mmmb"?)
+ assert_not_reached ();
+
+ VariantType original_type = key.value.get_type ();
+ VariantType nullable_type = new VariantType.maybe (original_type);
+ Variant variant = new Variant.maybe (original_type, key.is_default ? null : key.value);
+
+ SimpleAction simple_action = new SimpleAction.stateful (ACTION_NAME, nullable_type, variant);
+ SimpleActionGroup group = new SimpleActionGroup ();
+ ((ActionMap) group).add_action (simple_action);
+ grid.insert_action_group (GROUP_PREFIX, group);
+
+ if (nullable)
+ add_model_button (_("Default value"), new Variant.maybe (original_type, null));
+
+ if (key.schema.choices != null)
+ {
+ foreach (SchemaChoice choice in key.schema.choices)
+ add_model_button (choice.name, new Variant.maybe (original_type, choice.value));
+ }
+ else if (key.type_string == "b")
+ {
+ add_model_button (_("True"), new Variant.maybe (original_type, new Variant.boolean (true)));
// TODO string duplication
+ add_model_button (_("False"), new Variant.maybe (original_type, new Variant.boolean (false)));
// TODO string duplication
+ }
+ else if (key.type_string == "<enum>")
+ {
+ SchemaEnum schema_enum = key.schema.schema.list.enums.lookup (key.schema.enum_name);
+ if (schema_enum.values.length () <= 0)
+ assert_not_reached (); // TODO special case 0?
+ // else if (schema_enum.values.length () == 1)
+ // assert_not_reached (); // TODO
+
+ for (uint index = 0; index < schema_enum.values.length (); index++)
+ {
+ string nick = schema_enum.values.nth_data (index).nick;
+ add_model_button (nick, new Variant.maybe (VariantType.STRING, new Variant.string (nick)));
// FIXME in internals, it’s an int!
+ }
+ }
+
+ group.action_state_changed [ACTION_NAME].connect ((unknown_string, tmp_variant) => {
+ Variant? new_variant = tmp_variant.get_maybe ();
+ if (new_variant == null)
+ set_to_default ();
+ else
+ value_changed (new_variant.get_data_as_bytes ());
+ });
+ }
+
+ private void add_model_button (string text, Variant variant)
+ {
+ ModelButton button = new ModelButton ();
+ button.visible = true;
+ button.text = text;
+ button.action_name = GROUP_PREFIX + "." + ACTION_NAME;
+ button.action_target = variant;
+ grid.add (button);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]