From f803d89f52dc5a975cf55b5f41edaf3befbec62b Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 9 Nov 2024 09:41:59 +0200 Subject: [PATCH] draft widget actions --- src/app/browser/widget/action.rs | 67 ++++++++++++++++++++++++++ src/app/browser/widget/action/close.rs | 40 +++++++++++++++ src/app/browser/widget/action/debug.rs | 40 +++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/app/browser/widget/action.rs create mode 100644 src/app/browser/widget/action/close.rs create mode 100644 src/app/browser/widget/action/debug.rs diff --git a/src/app/browser/widget/action.rs b/src/app/browser/widget/action.rs new file mode 100644 index 00000000..4c15a704 --- /dev/null +++ b/src/app/browser/widget/action.rs @@ -0,0 +1,67 @@ +mod close; +mod debug; + +use close::Close; +use debug::Debug; + +use gtk::{ + gio::SimpleActionGroup, + glib::{gformat, uuid_string_random, GString}, + prelude::{IsA, WidgetExt}, + Window, +}; + +pub struct Action { + // Actions + close: Close, + debug: Debug, + // Group + gobject: SimpleActionGroup, + name: GString, +} + +impl Action { + // Constructors + + /// Create **activated** [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) set + /// with new [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) + /// for given [Window](https://docs.gtk.org/gtk4/class.Window.html) + /// * useful for object-oriented work with GTK `detailed_name`, e.g. on GTK [Menu](https://docs.gtk.org/gio/class.Menu.html) build + /// * this implementation also encapsulates `GObject` to prevent unexpected assignments + /// * children actions implemented as wrapper also, that extend default [Variant](https://docs.gtk.org/glib/struct.Variant.html) features, etc + pub fn new_for(window: &(impl IsA + WidgetExt)) -> Self { + // Init group + let name = uuid_string_random(); + let gobject = SimpleActionGroup::new(); + + // Add group to window + window.insert_action_group(&name, Some(&gobject)); + + // Init actions + let close = Close::new_for(&gobject, window.clone()); + let debug = Debug::new_for(&gobject, window.clone()); + + Self { + close, + debug, + gobject, + name, + } + } + + // Getters + + pub fn debug(&self) -> GString { + self.detailed_name(self.debug.name()) + } + + pub fn close(&self) -> GString { + self.detailed_name(self.close.name()) + } + + // Helpers + + fn detailed_name(&self, action_name: GString) -> GString { + gformat!("{}.{}", self.name, action_name) + } +} diff --git a/src/app/browser/widget/action/close.rs b/src/app/browser/widget/action/close.rs new file mode 100644 index 00000000..131c736d --- /dev/null +++ b/src/app/browser/widget/action/close.rs @@ -0,0 +1,40 @@ +use gtk::{ + gio::{SimpleAction, SimpleActionGroup}, + glib::{uuid_string_random, GString}, + prelude::{ActionExt, ActionMapExt, GtkWindowExt, IsA}, + Window, +}; + +pub struct Close { + gobject: SimpleAction, +} + +impl Close { + // Constructors + + /// Create new [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) + /// for given [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) + /// and [Window](https://docs.gtk.org/gtk4/class.Window.html) + /// * this constructor **activate** default feature + pub fn new_for(group: &SimpleActionGroup, window: impl IsA) -> Self { + // Init action GObject + let gobject = SimpleAction::new(&uuid_string_random(), None); + + // Add action to given group + group.add_action(&gobject); + + // Connect default feature on activate + gobject.connect_activate(move |_, _| { + window.close(); + }); + + // Done + Self { gobject } + } + + // Getters + + pub fn name(&self) -> GString { + self.gobject.name() + } +} diff --git a/src/app/browser/widget/action/debug.rs b/src/app/browser/widget/action/debug.rs new file mode 100644 index 00000000..147592fd --- /dev/null +++ b/src/app/browser/widget/action/debug.rs @@ -0,0 +1,40 @@ +use gtk::{ + gio::{SimpleAction, SimpleActionGroup}, + glib::{uuid_string_random, GString}, + prelude::{ActionExt, ActionMapExt, GtkWindowExt, IsA}, + Window, +}; + +pub struct Debug { + gobject: SimpleAction, +} + +impl Debug { + // Constructors + + /// Create new [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) + /// for given [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) + /// and [Window](https://docs.gtk.org/gtk4/class.Window.html) + /// * this constructor **activate** default feature + pub fn new_for(group: &SimpleActionGroup, window: impl IsA) -> Self { + // Init action GObject + let gobject = SimpleAction::new(&uuid_string_random(), None); + + // Add action to given group + group.add_action(&gobject); + + // Connect default feature on activate + gobject.connect_activate(move |_, _| { + window.emit_enable_debugging(true); + }); + + // Done + Self { gobject } + } + + // Getters + + pub fn name(&self) -> GString { + self.gobject.name() + } +}