From 8113022cd441b596b746be9f7ea242697bcf57be Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 10 Nov 2024 11:53:43 +0200 Subject: [PATCH] create separated wrappers for history, close action group --- src/app.rs | 48 +++++----- src/app/browser.rs | 89 ++----------------- src/app/browser/widget.rs | 14 +-- src/app/browser/window.rs | 73 +++++++-------- src/app/browser/window/action.rs | 44 +++++++++ src/app/browser/window/action/close.rs | 85 ++++++++++++++++++ src/app/browser/window/action/close_all.rs | 85 ++++++++++++++++++ src/app/browser/window/action/history_back.rs | 85 ++++++++++++++++++ .../browser/window/action/history_forward.rs | 85 ++++++++++++++++++ src/app/browser/window/header.rs | 15 +--- src/app/browser/window/header/bar.rs | 15 +--- src/app/browser/window/header/bar/menu.rs | 42 +++++---- src/app/browser/window/tab.rs | 80 ++++------------- src/app/browser/window/tab/item.rs | 16 +--- src/app/browser/window/tab/item/page.rs | 4 - .../window/tab/item/page/navigation.rs | 4 +- .../tab/item/page/navigation/history.rs | 12 ++- .../tab/item/page/navigation/history/back.rs | 16 ++-- .../page/navigation/history/back/widget.rs | 10 +-- .../item/page/navigation/history/forward.rs | 16 ++-- .../page/navigation/history/forward/widget.rs | 10 +-- src/app/browser/window/tab/menu.rs | 44 ++++----- 22 files changed, 557 insertions(+), 335 deletions(-) create mode 100644 src/app/browser/window/action/close.rs create mode 100644 src/app/browser/window/action/close_all.rs create mode 100644 src/app/browser/window/action/history_back.rs create mode 100644 src/app/browser/window/action/history_forward.rs diff --git a/src/app.rs b/src/app.rs index b99e8196..9cff49c2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -7,11 +7,8 @@ use database::Database; use crate::profile::Profile; use adw::Application; use gtk::{ - gio::SimpleAction, - glib::{uuid_string_random, ExitCode}, - prelude::{ - ActionExt, ApplicationExt, ApplicationExtManual, GtkApplicationExt, GtkWindowExt, ToVariant, - }, + glib::ExitCode, + prelude::{ApplicationExt, ApplicationExtManual, GtkApplicationExt, GtkWindowExt}, }; use sqlite::Transaction; use std::rc::Rc; @@ -29,30 +26,13 @@ impl App { // Init profile let profile = Rc::new(Profile::new()); - // @TODO - let default_state = (-1).to_variant(); - - let action_page_close = - SimpleAction::new_stateful(&uuid_string_random(), None, &default_state); - let action_page_close_all = SimpleAction::new(&uuid_string_random(), None); - let action_page_history_back = - SimpleAction::new_stateful(&uuid_string_random(), None, &default_state); - let action_page_history_forward = - SimpleAction::new_stateful(&uuid_string_random(), None, &default_state); - // Init GTK let gobject = Application::builder() .application_id(APPLICATION_ID) .build(); // Init components - let browser = Rc::new(Browser::new( - profile.clone(), - action_page_close.clone(), - action_page_close_all.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), - )); + let browser = Rc::new(Browser::new(profile.clone())); // Init events gobject.connect_activate({ @@ -219,16 +199,30 @@ impl App { ), &["h"], ), - // @TODO ( - format!("win.{}", action_page_history_back.name()), + format!( + "{}.{}", + browser.window().action().id(), + browser.window().action().history_back().id() + ), &["Left"], ), ( - format!("win.{}", action_page_history_forward.name()), + format!( + "{}.{}", + browser.window().action().id(), + browser.window().action().history_forward().id() + ), &["Right"], ), - // @TODO page close missed + ( + format!( + "{}.{}", + browser.window().action().id(), + browser.window().action().close().id() + ), + &["q"], + ), ] { gobject.set_accels_for_action(detailed_action_name, &accels); } diff --git a/src/app/browser.rs b/src/app/browser.rs index 66112042..dc3e2b68 100644 --- a/src/app/browser.rs +++ b/src/app/browser.rs @@ -13,8 +13,8 @@ use window::Window; use crate::profile::Profile; use adw::ApplicationWindow; use gtk::{ - gio::{Cancellable, File, SimpleAction}, - prelude::{ActionExt, GtkWindowExt, WidgetExt}, + gio::{Cancellable, File}, + prelude::GtkWindowExt, FileLauncher, }; use sqlite::Transaction; @@ -28,48 +28,22 @@ pub struct Browser { impl Browser { // Construct - pub fn new( - profile: Rc, - action_page_close: SimpleAction, - action_page_close_all: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, - ) -> Browser { + pub fn new(profile: Rc) -> Browser { // Init components let action = Rc::new(Action::new()); - let window = Rc::new(Window::new( - action.clone(), - action_page_close.clone(), - action_page_close_all.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), - )); + let window = Rc::new(Window::new(action.clone())); // Init widget let widget = Rc::new(Widget::new( window.gobject(), &[ - action_page_close.clone(), - action_page_close_all.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), + // Connect action groups + (action.id(), action.gobject()), + (window.action().id(), window.action().gobject()), + (window.tab().action().id(), window.tab().action().gobject()), ], )); - // Connect actions (window required for accels) - widget - .gobject() - .insert_action_group(action.id(), Some(action.gobject())); - - widget - .gobject() - .insert_action_group(window.action().id(), Some(window.action().gobject())); - - widget.gobject().insert_action_group( - window.tab().action().id(), - Some(window.tab().action().gobject()), - ); - // Connect events action.about().connect_activate({ let window = window.clone(); @@ -109,35 +83,6 @@ impl Browser { move |tab_item_id| window.update(tab_item_id) }); - // @TODO - action_page_close.connect_activate({ - let window = window.clone(); - move |this, _| { - window.tab_close(page_position_from_action_state(this)); - } - }); - - action_page_close_all.connect_activate({ - let window = window.clone(); - move |_, _| { - window.tab_close_all(); - } - }); - - action_page_history_back.connect_activate({ - let window = window.clone(); - move |this, _| { - window.tab_page_history_back(page_position_from_action_state(this)); - } - }); - - action_page_history_forward.connect_activate({ - let window = window.clone(); - move |this, _| { - window.tab_page_history_forward(page_position_from_action_state(this)); - } - }); - // Return new activated `Self` Self { action, @@ -246,21 +191,3 @@ pub fn migrate(tx: &Transaction) -> Result<(), String> { // Success Ok(()) } - -// Private helpers @TODO move outside - -/// Extract `Optional` page position from C-based -/// [SimpleAction state](https://docs.gtk.org/gio/property.SimpleAction.state.html) -fn page_position_from_action_state(action: &SimpleAction) -> Option { - let page_position = action - .state() - .expect("Page position required for this action") - .get::() - .expect("Parameter type does not match `i32`"); - - if page_position > -1 { - Some(page_position) - } else { - None - } -} diff --git a/src/app/browser/widget.rs b/src/app/browser/widget.rs index 3f3395cc..5b127b05 100644 --- a/src/app/browser/widget.rs +++ b/src/app/browser/widget.rs @@ -3,8 +3,9 @@ use database::Database; use adw::ApplicationWindow; use gtk::{ - gio::SimpleAction, - prelude::{ActionMapExt, GtkWindowExt, IsA}, + gio::SimpleActionGroup, + glib::GString, + prelude::{GtkWindowExt, IsA, WidgetExt}, }; use sqlite::Transaction; @@ -19,7 +20,10 @@ pub struct Widget { impl Widget { // Construct - pub fn new(content: &impl IsA, actions: &[SimpleAction]) -> Self { + pub fn new( + content: &impl IsA, + action_groups: &[(&GString, &SimpleActionGroup)], + ) -> Self { // Init GTK let gobject = ApplicationWindow::builder() .content(content) @@ -29,8 +33,8 @@ impl Widget { .build(); // Register actions - for action in actions { - gobject.add_action(action); + for (name, group) in action_groups { + gobject.insert_action_group(name, Some(group.clone())); } // Return new struct diff --git a/src/app/browser/window.rs b/src/app/browser/window.rs index 89847f48..800d9bd0 100644 --- a/src/app/browser/window.rs +++ b/src/app/browser/window.rs @@ -12,7 +12,7 @@ use tab::Tab; use widget::Widget; use crate::app::browser::action::Action as BrowserAction; -use gtk::{gio::SimpleAction, glib::GString, Box}; +use gtk::{glib::GString, Box}; use std::rc::Rc; pub struct Window { @@ -27,35 +27,13 @@ impl Window { pub fn new( // Actions browser_action: Rc, - action_page_close: SimpleAction, - action_page_close_all: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, ) -> Self { // Init local actions let action = Rc::new(Action::new()); // Init components - let tab = Tab::new_rc( - browser_action.clone(), - action.clone(), - action_page_close.clone(), - action_page_close_all.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), - ); - - let header = Header::new_rc( - // Actions - browser_action, - action.clone(), - action_page_close, - action_page_close_all, - action_page_history_back, - action_page_history_forward, - // Widgets - tab.gobject(), - ); + let tab = Tab::new_rc(browser_action.clone(), action.clone()); + let header = Header::new_rc(browser_action, action.clone(), tab.gobject()); // GTK let widget = Rc::new(Widget::new(header.gobject(), tab.gobject())); @@ -83,6 +61,34 @@ impl Window { move |position| tab.page_home(position) }); + action.close().connect_activate({ + let tab = tab.clone(); + move |position| { + tab.close(position); + } + }); + + action.close_all().connect_activate({ + let tab = tab.clone(); + move |_| { + tab.close_all(); + } // @TODO position not in use + }); + + action.history_back().connect_activate({ + let tab = tab.clone(); + move |position| { + tab.page_history_back(position); + } // @TODO rename destination method + }); + + action.history_forward().connect_activate({ + let tab = tab.clone(); + move |position| { + tab.page_history_forward(position); + } // @TODO rename destination method + }); + // Init struct Self { //header, @@ -93,23 +99,6 @@ impl Window { } // Actions - pub fn tab_page_history_back(&self, page_position: Option) { - self.tab.page_history_back(page_position); - } - - pub fn tab_page_history_forward(&self, page_position: Option) { - self.tab.page_history_forward(page_position); - } - - /// Close page at given position or selected page on `None` given - pub fn tab_close(&self, page_position: Option) { - self.tab.close(page_position); - } - - pub fn tab_close_all(&self) { - self.tab.close_all(); - } - pub fn update(&self, tab_item_id: Option) { self.tab.update(tab_item_id); } diff --git a/src/app/browser/window/action.rs b/src/app/browser/window/action.rs index 6a3ceae3..bbc66cd6 100644 --- a/src/app/browser/window/action.rs +++ b/src/app/browser/window/action.rs @@ -1,9 +1,17 @@ mod append; +mod close; +mod close_all; +mod history_back; +mod history_forward; mod home; mod pin; mod reload; use append::Append; +use close::Close; +use close_all::CloseAll; +use history_back::HistoryBack; +use history_forward::HistoryForward; use home::Home; use pin::Pin; use reload::Reload; @@ -19,6 +27,10 @@ use std::rc::Rc; pub struct Action { // Actions append: Rc, + close_all: Rc, + close: Rc, + history_back: Rc, + history_forward: Rc, home: Rc, pin: Rc, reload: Rc, @@ -34,6 +46,10 @@ impl Action { pub fn new() -> Self { // Init actions let append = Rc::new(Append::new()); + let close = Rc::new(Close::new()); + let close_all = Rc::new(CloseAll::new()); + let history_back = Rc::new(HistoryBack::new()); + let history_forward = Rc::new(HistoryForward::new()); let home = Rc::new(Home::new()); let pin = Rc::new(Pin::new()); let reload = Rc::new(Reload::new()); @@ -46,6 +62,10 @@ impl Action { // Add action to given group gobject.add_action(append.gobject()); + gobject.add_action(close_all.gobject()); + gobject.add_action(close.gobject()); + gobject.add_action(history_back.gobject()); + gobject.add_action(history_forward.gobject()); gobject.add_action(home.gobject()); gobject.add_action(pin.gobject()); gobject.add_action(reload.gobject()); @@ -53,6 +73,10 @@ impl Action { // Done Self { append, + close_all, + close, + history_back, + history_forward, home, pin, reload, @@ -68,6 +92,26 @@ impl Action { &self.append } + /// Get reference `CloseAll` action + pub fn close_all(&self) -> &Rc { + &self.close_all + } + + /// Get reference `Close` action + pub fn close(&self) -> &Rc { + &self.close + } + + /// Get reference `HistoryBack` action + pub fn history_back(&self) -> &Rc { + &self.history_back + } + + /// Get reference `HistoryForward` action + pub fn history_forward(&self) -> &Rc { + &self.history_forward + } + /// Get reference `Home` action pub fn home(&self) -> &Rc { &self.home diff --git a/src/app/browser/window/action/close.rs b/src/app/browser/window/action/close.rs new file mode 100644 index 00000000..68d50eb5 --- /dev/null +++ b/src/app/browser/window/action/close.rs @@ -0,0 +1,85 @@ +use gtk::{ + gio::SimpleAction, + glib::{uuid_string_random, GString}, + prelude::{ActionExt, ToVariant}, +}; + +// Defaults + +/// C-compatible variant type +const DEFAULT_STATE: i32 = -1; + +/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `Close` action of `Window` group +pub struct Close { + gobject: SimpleAction, +} + +impl Close { + // Constructors + + /// Create new `Self` + pub fn new() -> Self { + Self { + gobject: SimpleAction::new_stateful( + &uuid_string_random(), + None, + &DEFAULT_STATE.to_variant(), + ), + } + } + + // Actions + + /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn activate(&self) { + self.gobject.activate(None); + } + + /// Change action [state](https://docs.gtk.org/gio/method.SimpleAction.set_state.html) + /// * set `DEFAULT_STATE` on `None` + pub fn change_state(&self, state: Option) { + self.gobject.change_state( + &match state { + Some(value) => value, + None => DEFAULT_STATE, + } + .to_variant(), + ) + } + + // Events + + /// Define callback function for + /// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn connect_activate(&self, callback: impl Fn(Option) + 'static) { + let state = self.state(); + self.gobject.connect_activate(move |_, _| callback(state)); + } + + // Getters + + pub fn state(&self) -> Option { + let state = self + .gobject + .state() + .expect("State value required") + .get::() + .expect("Parameter type does not match `i32`"); + + if state != DEFAULT_STATE { + Some(state) + } else { + None + } + } + + /// Get reference to [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) GObject + pub fn gobject(&self) -> &SimpleAction { + &self.gobject + } + + /// Get auto-generated [action name](https://docs.gtk.org/gio/property.SimpleAction.name.html) + pub fn id(&self) -> GString { + self.gobject.name() + } +} diff --git a/src/app/browser/window/action/close_all.rs b/src/app/browser/window/action/close_all.rs new file mode 100644 index 00000000..0aa70b4a --- /dev/null +++ b/src/app/browser/window/action/close_all.rs @@ -0,0 +1,85 @@ +use gtk::{ + gio::SimpleAction, + glib::{uuid_string_random, GString}, + prelude::{ActionExt, ToVariant}, +}; + +// Defaults + +/// C-compatible variant type +const DEFAULT_STATE: i32 = -1; + +/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `CloseAll` action of `Window` group +pub struct CloseAll { + gobject: SimpleAction, +} + +impl CloseAll { + // Constructors + + /// Create new `Self` + pub fn new() -> Self { + Self { + gobject: SimpleAction::new_stateful( + &uuid_string_random(), + None, + &DEFAULT_STATE.to_variant(), + ), + } + } + + // Actions + + /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn activate(&self) { + self.gobject.activate(None); + } + + /// Change action [state](https://docs.gtk.org/gio/method.SimpleAction.set_state.html) + /// * set `DEFAULT_STATE` on `None` + pub fn change_state(&self, state: Option) { + self.gobject.change_state( + &match state { + Some(value) => value, + None => DEFAULT_STATE, + } + .to_variant(), + ) + } + + // Events + + /// Define callback function for + /// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn connect_activate(&self, callback: impl Fn(Option) + 'static) { + let state = self.state(); + self.gobject.connect_activate(move |_, _| callback(state)); + } + + // Getters + + pub fn state(&self) -> Option { + let state = self + .gobject + .state() + .expect("State value required") + .get::() + .expect("Parameter type does not match `i32`"); + + if state != DEFAULT_STATE { + Some(state) + } else { + None + } + } + + /// Get reference to [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) GObject + pub fn gobject(&self) -> &SimpleAction { + &self.gobject + } + + /// Get auto-generated [action name](https://docs.gtk.org/gio/property.SimpleAction.name.html) + pub fn id(&self) -> GString { + self.gobject.name() + } +} diff --git a/src/app/browser/window/action/history_back.rs b/src/app/browser/window/action/history_back.rs new file mode 100644 index 00000000..ee59c0a4 --- /dev/null +++ b/src/app/browser/window/action/history_back.rs @@ -0,0 +1,85 @@ +use gtk::{ + gio::SimpleAction, + glib::{uuid_string_random, GString}, + prelude::{ActionExt, ToVariant}, +}; + +// Defaults + +/// C-compatible variant type +const DEFAULT_STATE: i32 = -1; + +/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `HistoryBack` action of `Window` group +pub struct HistoryBack { + gobject: SimpleAction, +} + +impl HistoryBack { + // Constructors + + /// Create new `Self` + pub fn new() -> Self { + Self { + gobject: SimpleAction::new_stateful( + &uuid_string_random(), + None, + &DEFAULT_STATE.to_variant(), + ), + } + } + + // Actions + + /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn activate(&self) { + self.gobject.activate(None); + } + + /// Change action [state](https://docs.gtk.org/gio/method.SimpleAction.set_state.html) + /// * set `DEFAULT_STATE` on `None` + pub fn change_state(&self, state: Option) { + self.gobject.change_state( + &match state { + Some(value) => value, + None => DEFAULT_STATE, + } + .to_variant(), + ) + } + + // Events + + /// Define callback function for + /// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn connect_activate(&self, callback: impl Fn(Option) + 'static) { + let state = self.state(); + self.gobject.connect_activate(move |_, _| callback(state)); + } + + // Getters + + pub fn state(&self) -> Option { + let state = self + .gobject + .state() + .expect("State value required") + .get::() + .expect("Parameter type does not match `i32`"); + + if state != DEFAULT_STATE { + Some(state) + } else { + None + } + } + + /// Get reference to [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) GObject + pub fn gobject(&self) -> &SimpleAction { + &self.gobject + } + + /// Get auto-generated [action name](https://docs.gtk.org/gio/property.SimpleAction.name.html) + pub fn id(&self) -> GString { + self.gobject.name() + } +} diff --git a/src/app/browser/window/action/history_forward.rs b/src/app/browser/window/action/history_forward.rs new file mode 100644 index 00000000..d1bc3a00 --- /dev/null +++ b/src/app/browser/window/action/history_forward.rs @@ -0,0 +1,85 @@ +use gtk::{ + gio::SimpleAction, + glib::{uuid_string_random, GString}, + prelude::{ActionExt, ToVariant}, +}; + +// Defaults + +/// C-compatible variant type +const DEFAULT_STATE: i32 = -1; + +/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `HistoryForward` action of `Window` group +pub struct HistoryForward { + gobject: SimpleAction, +} + +impl HistoryForward { + // Constructors + + /// Create new `Self` + pub fn new() -> Self { + Self { + gobject: SimpleAction::new_stateful( + &uuid_string_random(), + None, + &DEFAULT_STATE.to_variant(), + ), + } + } + + // Actions + + /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn activate(&self) { + self.gobject.activate(None); + } + + /// Change action [state](https://docs.gtk.org/gio/method.SimpleAction.set_state.html) + /// * set `DEFAULT_STATE` on `None` + pub fn change_state(&self, state: Option) { + self.gobject.change_state( + &match state { + Some(value) => value, + None => DEFAULT_STATE, + } + .to_variant(), + ) + } + + // Events + + /// Define callback function for + /// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn connect_activate(&self, callback: impl Fn(Option) + 'static) { + let state = self.state(); + self.gobject.connect_activate(move |_, _| callback(state)); + } + + // Getters + + pub fn state(&self) -> Option { + let state = self + .gobject + .state() + .expect("State value required") + .get::() + .expect("Parameter type does not match `i32`"); + + if state != DEFAULT_STATE { + Some(state) + } else { + None + } + } + + /// Get reference to [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) GObject + pub fn gobject(&self) -> &SimpleAction { + &self.gobject + } + + /// Get auto-generated [action name](https://docs.gtk.org/gio/property.SimpleAction.name.html) + pub fn id(&self) -> GString { + self.gobject.name() + } +} diff --git a/src/app/browser/window/header.rs b/src/app/browser/window/header.rs index 78729da3..e683c528 100644 --- a/src/app/browser/window/header.rs +++ b/src/app/browser/window/header.rs @@ -7,7 +7,6 @@ use widget::Widget; use crate::app::browser::action::Action as BrowserAction; use crate::app::browser::window::action::Action as WindowAction; use adw::{TabView, ToolbarView}; -use gtk::gio::SimpleAction; use std::rc::Rc; pub struct Header { @@ -20,23 +19,11 @@ impl Header { // Actions browser_action: Rc, window_action: Rc, - action_page_close: SimpleAction, - action_page_close_all: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, // Widgets tab_view: &TabView, ) -> Rc { // Init components - let bar = Bar::new_rc( - browser_action, - window_action, - action_page_close, - action_page_close_all, - action_page_history_back, - action_page_history_forward, - tab_view, - ); + let bar = Bar::new_rc(browser_action, window_action, tab_view); // Return new struct Rc::new(Self { diff --git a/src/app/browser/window/header/bar.rs b/src/app/browser/window/header/bar.rs index 2fb7bf00..8c4c3582 100644 --- a/src/app/browser/window/header/bar.rs +++ b/src/app/browser/window/header/bar.rs @@ -11,7 +11,7 @@ use widget::Widget; use crate::app::browser::action::Action as BrowserAction; use crate::app::browser::window::action::Action as WindowAction; use adw::TabView; -use gtk::{gio::SimpleAction, Box}; +use gtk::Box; use std::rc::Rc; pub struct Bar { @@ -23,23 +23,12 @@ impl Bar { pub fn new_rc( browser_action: Rc, window_action: Rc, - action_page_close: SimpleAction, - action_page_close_all: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, view: &TabView, ) -> Rc { // Init components let control = Control::new_rc(); let tab = Tab::new_rc(window_action.clone(), view); - let menu = Menu::new_rc( - browser_action, - window_action, - action_page_close, - action_page_close_all, - action_page_history_back, - action_page_history_forward, - ); + let menu = Menu::new_rc(browser_action, window_action); // Build result Rc::new(Self { diff --git a/src/app/browser/window/header/bar/menu.rs b/src/app/browser/window/header/bar/menu.rs index c0dcdbbc..51beb995 100644 --- a/src/app/browser/window/header/bar/menu.rs +++ b/src/app/browser/window/header/bar/menu.rs @@ -5,8 +5,7 @@ use widget::Widget; use crate::app::browser::action::Action as BrowserAction; use crate::app::browser::window::action::Action as WindowAction; use gtk::{ - gio::{self, SimpleAction}, - prelude::ActionExt, + gio::{self}, MenuButton, }; use std::rc::Rc; @@ -19,10 +18,6 @@ impl Menu { pub fn new_rc( browser_action: Rc, window_action: Rc, - action_page_close: SimpleAction, - action_page_close_all: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, ) -> Rc { // Main let main = gio::Menu::new(); @@ -58,8 +53,18 @@ impl Menu { // Main > Page > Navigation > History let main_page_navigation_history = gio::Menu::new(); - main_page_navigation_history.append(Some("Back"), Some(&detailed_action_name(&action_page_history_back))); - main_page_navigation_history.append(Some("Forward"), Some(&detailed_action_name(&action_page_history_forward))); + + main_page_navigation_history.append(Some("Back"), Some(&format!( + "{}.{}", + window_action.id(), + window_action.history_back().id() + ))); + + main_page_navigation_history.append(Some("Forward"), Some(&format!( + "{}.{}", + window_action.id(), + window_action.history_forward().id() + ))); main_page_navigation.append_submenu(Some("History"), &main_page_navigation_history); @@ -67,8 +72,18 @@ impl Menu { // Main > Page > Close let main_page_close = gio::Menu::new(); - main_page_close.append(Some("Current"), Some(&detailed_action_name(&action_page_close))); - main_page_close.append(Some("All"), Some(&detailed_action_name(&action_page_close_all))); + + main_page_close.append(Some("Current"), Some(&format!( + "{}.{}", + window_action.id(), + window_action.close().id() + ))); + + main_page_close.append(Some("All"), Some(&format!( + "{}.{}", + window_action.id(), + window_action.close_all().id() + ))); main_page.append_submenu(Some("Close"), &main_page_close); @@ -113,10 +128,3 @@ impl Menu { self.widget.gobject() } } - -// Private helpers -fn detailed_action_name(action: &SimpleAction) -> String { - format!("win.{}", action.name()) // @TODO find the way to ident parent group - // without application-wide dependencies import - // see also src/app/action.rs -} diff --git a/src/app/browser/window/tab.rs b/src/app/browser/window/tab.rs index cff4978b..c14fec70 100644 --- a/src/app/browser/window/tab.rs +++ b/src/app/browser/window/tab.rs @@ -13,22 +13,15 @@ use widget::Widget; use crate::app::browser::action::Action as BrowserAction; use crate::app::browser::window::action::Action as WindowAction; use adw::TabView; -use gtk::{ - gio::SimpleAction, - glib::{GString, Propagation}, - prelude::{ActionExt, ToVariant}, -}; +use gtk::glib::{GString, Propagation}; use sqlite::Transaction; use std::{cell::RefCell, collections::HashMap, rc::Rc}; // Main pub struct Tab { - // Global actions + // Actions browser_action: Rc, window_action: Rc, - // Page actions - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, // Dynamically allocated reference index index: Rc>>>, action: Rc, @@ -37,14 +30,7 @@ pub struct Tab { impl Tab { // Construct - pub fn new_rc( - browser_action: Rc, - window_action: Rc, - action_page_close: SimpleAction, - action_page_close_all: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, - ) -> Rc { + pub fn new_rc(browser_action: Rc, window_action: Rc) -> Rc { // Init local actions let action = Rc::new(Action::new()); @@ -52,13 +38,7 @@ impl Tab { let index = Rc::new(RefCell::new(HashMap::new())); // Init context menu - let menu = Menu::new( - window_action.clone(), - action_page_close_all.clone(), - action_page_close.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), - ); + let menu = Menu::new(window_action.clone()); // Init widget let widget = Rc::new(Widget::new(menu.gobject())); @@ -73,20 +53,14 @@ impl Tab { let window_action = window_action.clone(); let action = action.clone(); - let action_page_history_back = action_page_history_back.clone(); - let action_page_history_forward = action_page_history_forward.clone(); - move |request| { // Init new tab item let item = Item::new_rc( &gobject, - // Global actions + // Actions browser_action.clone(), window_action.clone(), action.clone(), - // Page actions - action_page_history_back.clone(), - action_page_history_forward.clone(), // Options gobject .selected_page() @@ -107,36 +81,23 @@ impl Tab { }); widget.gobject().connect_setup_menu({ - // Clone actions to update - let action_page_close = action_page_close.clone(); - let action_page_history_back = action_page_history_back.clone(); - let action_page_history_forward = action_page_history_forward.clone(); let window_action = window_action.clone(); move |tab_view, tab_page| { - // Update actions - let state_v2 = match tab_page { + // Set state + let state = match tab_page { // Context menu opened Some(this) => Some(tab_view.page_position(this)), // Context menu closed (reset state to defaults) None => None, - }; // @TODO - - window_action.pin().change_state(state_v2); - window_action.reload().change_state(state_v2); - window_action.home().change_state(state_v2); - - // @TODO old version requires update - // Setup state for selected page - let state = match tab_page { - // Context menu opened - Some(this) => tab_view.page_position(this).to_variant(), - // Context menu closed (reset state to defaults) - None => (-1).to_variant(), }; - - action_page_close.change_state(&state); - action_page_history_back.change_state(&state); - action_page_history_forward.change_state(&state); + // Update actions with new state value + window_action.close_all().change_state(state); + window_action.close().change_state(state); + window_action.history_back().change_state(state); + window_action.history_forward().change_state(state); + window_action.home().change_state(state); + window_action.pin().change_state(state); + window_action.reload().change_state(state); } }); @@ -176,10 +137,6 @@ impl Tab { Rc::new(Self { browser_action, window_action, - // Global actions - action_page_history_back, - action_page_history_forward, - // Init empty HashMap index as no tabs appended yet index, action, widget, @@ -193,11 +150,8 @@ impl Tab { self.gobject(), self.browser_action.clone(), self.window_action.clone(), - // Local actions + // Actions self.action.clone(), - // Global actions - self.action_page_history_back.clone(), - self.action_page_history_forward.clone(), // Options position, false, @@ -338,8 +292,6 @@ impl Tab { self.browser_action.clone(), self.window_action.clone(), self.action.clone(), - self.action_page_history_back.clone(), - self.action_page_history_forward.clone(), ) { Ok(items) => { for item in items { diff --git a/src/app/browser/window/tab/item.rs b/src/app/browser/window/tab/item.rs index bea44332..838f8e2c 100644 --- a/src/app/browser/window/tab/item.rs +++ b/src/app/browser/window/tab/item.rs @@ -10,10 +10,7 @@ use crate::app::browser::action::Action as BrowserAction; use crate::app::browser::window::action::Action as WindowAction; use crate::app::browser::window::tab::action::Action as TabAction; use adw::{TabPage, TabView}; -use gtk::{ - gio::SimpleAction, - glib::{uuid_string_random, GString}, -}; +use gtk::glib::{uuid_string_random, GString}; use sqlite::Transaction; use std::rc::Rc; @@ -30,13 +27,10 @@ impl Item { // Construct pub fn new_rc( tab_view: &TabView, - // Global actions + // Actions browser_action: Rc, window_action: Rc, tab_action: Rc, - // @TODO - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, // Options position: Option, is_pinned: bool, @@ -52,8 +46,6 @@ impl Item { browser_action, window_action, tab_action, - action_page_history_back.clone(), - action_page_history_forward.clone(), ); let widget = Widget::new_rc( @@ -133,8 +125,6 @@ impl Item { browser_action: Rc, window_action: Rc, tab_action: Rc, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, ) -> Result>, String> { let mut items = Vec::new(); @@ -148,8 +138,6 @@ impl Item { browser_action.clone(), window_action.clone(), tab_action.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), // Options None, record.is_pinned, diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index 090d83e6..d666606b 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -60,8 +60,6 @@ impl Page { browser_action: Rc, window_action: Rc, tab_action: Rc, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, ) -> Rc { // Init local actions let action_page_load = SimpleAction::new(&uuid_string_random(), None); @@ -74,8 +72,6 @@ impl Page { let navigation = Navigation::new_rc( browser_action.clone(), window_action.clone(), - action_page_history_back.clone(), - action_page_history_forward.clone(), action_page_open.clone(), ); diff --git a/src/app/browser/window/tab/item/page/navigation.rs b/src/app/browser/window/tab/item/page/navigation.rs index b6c097a9..03fc3f14 100644 --- a/src/app/browser/window/tab/item/page/navigation.rs +++ b/src/app/browser/window/tab/item/page/navigation.rs @@ -33,13 +33,11 @@ impl Navigation { pub fn new_rc( browser_action: Rc, window_action: Rc, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, action_page_open: SimpleAction, ) -> Rc { // Init components let home = Home::new_rc(window_action.clone()); - let history = History::new_rc(action_page_history_back, action_page_history_forward); + let history = History::new_rc(window_action.clone()); let reload = Reload::new_rc(window_action); let request = Request::new_rc(browser_action, action_page_open.clone()); let bookmark = Bookmark::new_rc(); diff --git a/src/app/browser/window/tab/item/page/navigation/history.rs b/src/app/browser/window/tab/item/page/navigation/history.rs index 692bb1cc..d0642d6c 100644 --- a/src/app/browser/window/tab/item/page/navigation/history.rs +++ b/src/app/browser/window/tab/item/page/navigation/history.rs @@ -6,7 +6,8 @@ use back::Back; use forward::Forward; use widget::Widget; -use gtk::{gio::SimpleAction, glib::GString, Box}; +use crate::app::browser::window::action::Action as WindowAction; +use gtk::{glib::GString, Box}; use std::{cell::RefCell, rc::Rc}; struct Memory { @@ -27,13 +28,10 @@ pub struct History { impl History { // Construct - pub fn new_rc( - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, - ) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { // init components - let back = Back::new_rc(action_page_history_back); - let forward = Forward::new_rc(action_page_history_forward); + let back = Back::new_rc(window_action.clone()); + let forward = Forward::new_rc(window_action); // Init widget let widget = Widget::new_rc(back.gobject(), forward.gobject()); diff --git a/src/app/browser/window/tab/item/page/navigation/history/back.rs b/src/app/browser/window/tab/item/page/navigation/history/back.rs index 39bf6e32..a6d567f0 100644 --- a/src/app/browser/window/tab/item/page/navigation/history/back.rs +++ b/src/app/browser/window/tab/item/page/navigation/history/back.rs @@ -2,28 +2,32 @@ mod widget; use widget::Widget; -use gtk::{gio::SimpleAction, Button}; +use crate::app::browser::window::action::Action as WindowAction; +use gtk::Button; use std::rc::Rc; pub struct Back { - action_page_history_back: SimpleAction, + window_action: Rc, widget: Rc, } impl Back { // Construct - pub fn new_rc(action_page_history_back: SimpleAction) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { // Return activated struct Rc::new(Self { - action_page_history_back: action_page_history_back.clone(), - widget: Widget::new_rc(action_page_history_back), + window_action: window_action.clone(), + widget: Widget::new_rc(window_action), }) } // Actions pub fn update(&self, status: bool) { // Update actions - self.action_page_history_back.set_enabled(status); + self.window_action + .history_back() + .gobject() + .set_enabled(status); // Update child components self.widget.update(status); diff --git a/src/app/browser/window/tab/item/page/navigation/history/back/widget.rs b/src/app/browser/window/tab/item/page/navigation/history/back/widget.rs index 9cd530b9..2fcbf0ce 100644 --- a/src/app/browser/window/tab/item/page/navigation/history/back/widget.rs +++ b/src/app/browser/window/tab/item/page/navigation/history/back/widget.rs @@ -1,6 +1,6 @@ +use crate::app::browser::window::action::Action as WindowAction; use gtk::{ - gio::SimpleAction, - prelude::{ActionExt, ButtonExt, WidgetExt}, + prelude::{ButtonExt, WidgetExt}, Button, }; use std::rc::Rc; @@ -11,7 +11,7 @@ pub struct Widget { impl Widget { // Construct - pub fn new_rc(action_page_history_back: SimpleAction) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { // Init gobject let gobject = Button::builder() .icon_name("go-previous-symbolic") @@ -21,9 +21,9 @@ impl Widget { // Init events gobject.connect_clicked({ - let action_page_history_back = action_page_history_back.clone(); + let window_action = window_action.clone(); move |_| { - action_page_history_back.activate(None); + window_action.history_back().activate(); } }); diff --git a/src/app/browser/window/tab/item/page/navigation/history/forward.rs b/src/app/browser/window/tab/item/page/navigation/history/forward.rs index 10b4550c..9dedf143 100644 --- a/src/app/browser/window/tab/item/page/navigation/history/forward.rs +++ b/src/app/browser/window/tab/item/page/navigation/history/forward.rs @@ -2,28 +2,32 @@ mod widget; use widget::Widget; -use gtk::{gio::SimpleAction, Button}; +use crate::app::browser::window::action::Action as WindowAction; +use gtk::Button; use std::rc::Rc; pub struct Forward { - action_page_history_forward: SimpleAction, + window_action: Rc, widget: Rc, } impl Forward { // Construct - pub fn new_rc(action_page_history_forward: SimpleAction) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { // Return activated struct Rc::new(Self { - action_page_history_forward: action_page_history_forward.clone(), - widget: Widget::new_rc(action_page_history_forward), + window_action: window_action.clone(), + widget: Widget::new_rc(window_action), }) } // Actions pub fn update(&self, status: bool) { // Update actions - self.action_page_history_forward.set_enabled(status); + self.window_action + .history_forward() + .gobject() + .set_enabled(status); // Update child components self.widget.update(status); diff --git a/src/app/browser/window/tab/item/page/navigation/history/forward/widget.rs b/src/app/browser/window/tab/item/page/navigation/history/forward/widget.rs index ad0bca89..1ea539e1 100644 --- a/src/app/browser/window/tab/item/page/navigation/history/forward/widget.rs +++ b/src/app/browser/window/tab/item/page/navigation/history/forward/widget.rs @@ -1,6 +1,6 @@ +use crate::app::browser::window::action::Action as WindowAction; use gtk::{ - gio::SimpleAction, - prelude::{ActionExt, ButtonExt, WidgetExt}, + prelude::{ButtonExt, WidgetExt}, Button, }; use std::rc::Rc; @@ -11,7 +11,7 @@ pub struct Widget { impl Widget { // Construct - pub fn new_rc(action_page_history_forward: SimpleAction) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { // Init gobject let gobject = Button::builder() .icon_name("go-next-symbolic") @@ -21,9 +21,9 @@ impl Widget { // Init events gobject.connect_clicked({ - let action_page_history_forward = action_page_history_forward.clone(); + let window_action = window_action.clone(); move |_| { - action_page_history_forward.activate(None); + window_action.history_forward().activate(); } }); diff --git a/src/app/browser/window/tab/menu.rs b/src/app/browser/window/tab/menu.rs index 7a8e8cc0..de6eb1c7 100644 --- a/src/app/browser/window/tab/menu.rs +++ b/src/app/browser/window/tab/menu.rs @@ -1,7 +1,5 @@ -use std::rc::Rc; - use crate::app::browser::window::action::Action as WindowAction; -use gtk::{gio::SimpleAction, prelude::ActionExt}; +use std::rc::Rc; /// Context menu wrapper /// @@ -14,13 +12,7 @@ impl Menu { // Constructors /// Create new `Self` - pub fn new( - window_action: Rc, - action_page_close_all: SimpleAction, - action_page_close: SimpleAction, - action_page_history_back: SimpleAction, - action_page_history_forward: SimpleAction, - ) -> Self { + pub fn new(window_action: Rc) -> Self { let main = gtk::gio::Menu::new(); main.append( @@ -58,12 +50,20 @@ impl Menu { history.append( Some("Back"), - Some(&detailed_action_name(action_page_history_back)), + Some(&format!( + "{}.{}", + window_action.id(), + window_action.history_back().id() + )), ); history.append( Some("Forward"), - Some(&detailed_action_name(action_page_history_forward)), + Some(&format!( + "{}.{}", + window_action.id(), + window_action.history_forward().id() + )), ); main.append_submenu(Some("History"), &history); @@ -72,12 +72,20 @@ impl Menu { close.append( Some("Current"), - Some(&detailed_action_name(action_page_close)), + Some(&format!( + "{}.{}", + window_action.id(), + window_action.close().id() + )), ); close.append( Some("All"), - Some(&detailed_action_name(action_page_close_all)), + Some(&format!( + "{}.{}", + window_action.id(), + window_action.close_all().id() + )), ); main.append_submenu(Some("Close"), &close); @@ -90,11 +98,3 @@ impl Menu { &self.gobject } } - -// Private helpers - -fn detailed_action_name(action: SimpleAction) -> String { - format!("win.{}", action.name()) // @TODO find the way to ident parent group - // without application-wide dependencies import - // see also src/app/action.rs -}