diff --git a/src/app.rs b/src/app.rs index 49e343b2..70f8c872 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,7 +32,6 @@ impl App { // @TODO let default_state = (-1).to_variant(); - let action_page_new = SimpleAction::new(&uuid_string_random(), None); let action_page_close = SimpleAction::new_stateful(&uuid_string_random(), None, &default_state); let action_page_close_all = SimpleAction::new(&uuid_string_random(), None); @@ -55,7 +54,6 @@ impl App { // Init components let browser = Rc::new(Browser::new( profile.clone(), - action_page_new.clone(), action_page_close.clone(), action_page_close_all.clone(), action_page_home.clone(), @@ -201,8 +199,8 @@ impl App { ( gformat!( "{}.{}", - browser.window().tab().action().id(), - browser.window().tab().action().append().id() + browser.window().action().id(), + browser.window().action().append().id() ), &["t"], ), diff --git a/src/app/browser.rs b/src/app/browser.rs index 0185ae30..18834547 100644 --- a/src/app/browser.rs +++ b/src/app/browser.rs @@ -30,7 +30,6 @@ impl Browser { // Construct pub fn new( profile: Rc, - action_page_new: SimpleAction, action_page_close: SimpleAction, action_page_close_all: SimpleAction, action_page_home: SimpleAction, @@ -43,7 +42,6 @@ impl Browser { let action = Rc::new(Action::new()); let window = Rc::new(Window::new( action.clone(), - action_page_new.clone(), action_page_close.clone(), action_page_close_all.clone(), action_page_home.clone(), @@ -57,7 +55,6 @@ impl Browser { let widget = Rc::new(Widget::new( window.gobject(), &[ - action_page_new.clone(), action_page_close.clone(), action_page_close_all.clone(), action_page_home.clone(), @@ -68,11 +65,17 @@ impl Browser { ], )); - // Connect actions to browser window + // Connect browser actions to window widget .gobject() .insert_action_group(action.id(), Some(action.gobject())); + // Connect tab actions to window + widget.gobject().insert_action_group( + window.tab().action().id(), + Some(window.tab().action().gobject()), + ); // @TODO is really wanted to append it here? + // Connect events action.about().connect_activate({ let window = window.clone(); @@ -113,13 +116,6 @@ impl Browser { }); // @TODO - action_page_new.connect_activate({ - let window = window.clone(); - move |_, _| { - window.tab_append(None); - } - }); - action_page_close.connect_activate({ let window = window.clone(); move |this, _| { diff --git a/src/app/browser/window.rs b/src/app/browser/window.rs index 13dee8ea..36e8680e 100644 --- a/src/app/browser/window.rs +++ b/src/app/browser/window.rs @@ -1,8 +1,10 @@ +mod action; mod database; mod header; mod tab; mod widget; +use action::Action; use database::Database; use header::Header; use sqlite::Transaction; @@ -16,6 +18,7 @@ use std::rc::Rc; pub struct Window { //header: Rc
, tab: Rc, + action: Rc, widget: Rc, } @@ -24,7 +27,6 @@ impl Window { pub fn new( // Actions browser_action: Rc, - action_page_new: SimpleAction, action_page_close: SimpleAction, action_page_close_all: SimpleAction, action_page_home: SimpleAction, @@ -33,9 +35,13 @@ impl Window { action_page_reload: SimpleAction, action_page_pin: 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_home.clone(), @@ -48,7 +54,7 @@ impl Window { let header = Header::new_rc( // Actions browser_action, - action_page_new, + action.clone(), action_page_close, action_page_close_all, action_page_home, @@ -63,19 +69,24 @@ impl Window { // GTK let widget = Rc::new(Widget::new(header.gobject(), tab.gobject())); + // Init events + action.append().connect_activate({ + let tab = tab.clone(); + move || { + tab.append(None); + } + }); + // Init struct Self { //header, tab, + action, widget, } } // Actions - pub fn tab_append(&self, page_position: Option) { - self.tab.append(page_position); - } - pub fn tab_page_home(&self, page_position: Option) { self.tab.page_home(page_position); } @@ -166,6 +177,10 @@ impl Window { // Getters + pub fn action(&self) -> &Rc { + &self.action + } + pub fn tab(&self) -> &Rc { &self.tab } diff --git a/src/app/browser/window/action.rs b/src/app/browser/window/action.rs new file mode 100644 index 00000000..bc65c8dd --- /dev/null +++ b/src/app/browser/window/action.rs @@ -0,0 +1,65 @@ +mod append; + +use append::Append; + +use gtk::{ + gio::SimpleActionGroup, + glib::{uuid_string_random, GString}, + prelude::ActionMapExt, +}; +use std::rc::Rc; + +/// [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) wrapper for `Browser` actions +pub struct Action { + // Actions + append: Rc, + // Group + id: GString, + gobject: SimpleActionGroup, +} + +impl Action { + // Constructors + + /// Create new `Self` + pub fn new() -> Self { + // Init actions + let append = Rc::new(Append::new()); + + // Generate unique group ID + let id = uuid_string_random(); + + // Init group + let gobject = SimpleActionGroup::new(); + + // Add action to given group + gobject.add_action(append.gobject()); + + // Done + Self { + append, + id, + gobject, + } + } + + // Getters + + /// Get reference `Append` action + pub fn append(&self) -> &Rc { + &self.append + } + + /// Get auto-generated name for action group + /// * useful for manual relationship with GObjects or as the `detailed_name` + /// for [Accels](https://docs.gtk.org/gtk4/method.Application.set_accels_for_action.html) or + /// [Menu](https://docs.gtk.org/gio/class.Menu.html) builder + pub fn id(&self) -> &GString { + &self.id + } + + /// Get reference to [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) GObject + pub fn gobject(&self) -> &SimpleActionGroup { + &self.gobject + } +} diff --git a/src/app/browser/window/tab/action/append.rs b/src/app/browser/window/action/append.rs similarity index 85% rename from src/app/browser/window/tab/action/append.rs rename to src/app/browser/window/action/append.rs index d67e41d0..652069bf 100644 --- a/src/app/browser/window/tab/action/append.rs +++ b/src/app/browser/window/action/append.rs @@ -19,6 +19,13 @@ impl Append { } } + // Actions + + /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal + pub fn activate(&self) { + self.gobject.activate(None); + } + // Events /// Define callback function for diff --git a/src/app/browser/window/header.rs b/src/app/browser/window/header.rs index b8176afe..ca96ecd6 100644 --- a/src/app/browser/window/header.rs +++ b/src/app/browser/window/header.rs @@ -5,6 +5,7 @@ use bar::Bar; 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; @@ -18,7 +19,7 @@ impl Header { pub fn new_rc( // Actions browser_action: Rc, - action_page_new: SimpleAction, + window_action: Rc, action_page_close: SimpleAction, action_page_close_all: SimpleAction, action_page_home: SimpleAction, @@ -32,7 +33,7 @@ impl Header { // Init components let bar = Bar::new_rc( browser_action, - action_page_new, + window_action, action_page_close, action_page_close_all, action_page_home, diff --git a/src/app/browser/window/header/bar.rs b/src/app/browser/window/header/bar.rs index e3f43323..104569b7 100644 --- a/src/app/browser/window/header/bar.rs +++ b/src/app/browser/window/header/bar.rs @@ -9,6 +9,7 @@ use tab::Tab; 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 std::rc::Rc; @@ -21,7 +22,7 @@ impl Bar { // Construct pub fn new_rc( browser_action: Rc, - action_page_new: SimpleAction, + window_action: Rc, action_page_close: SimpleAction, action_page_close_all: SimpleAction, action_page_home: SimpleAction, @@ -33,10 +34,10 @@ impl Bar { ) -> Rc { // Init components let control = Control::new_rc(); - let tab = Tab::new_rc(action_page_new.clone(), view); + let tab = Tab::new_rc(window_action.clone(), view); let menu = Menu::new_rc( browser_action, - action_page_new, + window_action, action_page_close, action_page_close_all, action_page_home, diff --git a/src/app/browser/window/header/bar/menu.rs b/src/app/browser/window/header/bar/menu.rs index 33de8c43..ac84a327 100644 --- a/src/app/browser/window/header/bar/menu.rs +++ b/src/app/browser/window/header/bar/menu.rs @@ -3,6 +3,7 @@ mod widget; 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}, glib::{gformat, GString}, @@ -18,7 +19,7 @@ pub struct Menu { impl Menu { pub fn new_rc( browser_action: Rc, - action_page_new: SimpleAction, + window_action: Rc, action_page_close: SimpleAction, action_page_close_all: SimpleAction, action_page_home: SimpleAction, @@ -32,7 +33,12 @@ impl Menu { // Main > Page let main_page = gio::Menu::new(); - main_page.append(Some("New"), Some(&detailed_action_name(&action_page_new))); + main_page.append(Some("New"), Some(&gformat!( + "{}.{}", + window_action.id(), + window_action.append().id() + ))); + main_page.append(Some("Reload"), Some(&detailed_action_name(&action_page_reload))); main_page.append(Some("Pin"), Some(&detailed_action_name(&action_page_pin))); diff --git a/src/app/browser/window/header/bar/tab.rs b/src/app/browser/window/header/bar/tab.rs index 35689a7c..f976e4b4 100644 --- a/src/app/browser/window/header/bar/tab.rs +++ b/src/app/browser/window/header/bar/tab.rs @@ -4,8 +4,8 @@ mod widget; use append::Append; use widget::Widget; +use crate::app::browser::window::action::Action as WindowAction; use adw::{TabBar, TabView}; -use gtk::gio::SimpleAction; use std::rc::Rc; pub struct Tab { @@ -14,9 +14,9 @@ pub struct Tab { impl Tab { // Construct - pub fn new_rc(action_page_new: SimpleAction, view: &TabView) -> Rc { + pub fn new_rc(window_action: Rc, view: &TabView) -> Rc { Rc::new(Self { - widget: Widget::new_rc(view, Append::new_rc(action_page_new).gobject()), + widget: Widget::new_rc(view, Append::new_rc(window_action).gobject()), }) } diff --git a/src/app/browser/window/header/bar/tab/append.rs b/src/app/browser/window/header/bar/tab/append.rs index 793489b4..fa697c2f 100644 --- a/src/app/browser/window/header/bar/tab/append.rs +++ b/src/app/browser/window/header/bar/tab/append.rs @@ -2,7 +2,8 @@ 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 Append { @@ -11,9 +12,9 @@ pub struct Append { impl Append { // Construct - pub fn new_rc(action_page_new: SimpleAction) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { Rc::new(Self { - widget: Widget::new_rc(action_page_new), + widget: Widget::new_rc(window_action), }) } diff --git a/src/app/browser/window/header/bar/tab/append/widget.rs b/src/app/browser/window/header/bar/tab/append/widget.rs index 0af05d08..e4aeb74e 100644 --- a/src/app/browser/window/header/bar/tab/append/widget.rs +++ b/src/app/browser/window/header/bar/tab/append/widget.rs @@ -1,8 +1,5 @@ -use gtk::{ - gio::SimpleAction, - prelude::{ActionExt, ButtonExt}, - Align, Button, -}; +use crate::app::browser::window::action::Action as WindowAction; +use gtk::{prelude::ButtonExt, Align, Button}; use std::rc::Rc; pub struct Widget { @@ -11,7 +8,7 @@ pub struct Widget { impl Widget { // Construct - pub fn new_rc(action_page_new: SimpleAction) -> Rc { + pub fn new_rc(window_action: Rc) -> Rc { // Init gobject let gobject = Button::builder() .icon_name("tab-new-symbolic") @@ -21,9 +18,7 @@ impl Widget { .build(); // Init events - gobject.connect_clicked(move |_| { - action_page_new.activate(None); - }); + gobject.connect_clicked(move |_| window_action.append().activate()); Rc::new(Self { gobject }) } diff --git a/src/app/browser/window/tab.rs b/src/app/browser/window/tab.rs index 435cd8f2..3dd52898 100644 --- a/src/app/browser/window/tab.rs +++ b/src/app/browser/window/tab.rs @@ -11,6 +11,7 @@ use menu::Menu; 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, @@ -24,6 +25,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; pub struct Tab { // Global actions browser_action: Rc, + window_action: Rc, // Page actions action_page_home: SimpleAction, action_page_history_back: SimpleAction, @@ -39,6 +41,7 @@ impl Tab { // Construct pub fn new_rc( browser_action: Rc, + window_action: Rc, action_page_close: SimpleAction, action_page_close_all: SimpleAction, action_page_home: SimpleAction, @@ -74,6 +77,7 @@ impl Tab { let gobject = widget.gobject().clone(); // Actions let browser_action = browser_action.clone(); + let window_action = window_action.clone(); let action = action.clone(); let action_page_home = action_page_home.clone(); @@ -87,6 +91,7 @@ impl Tab { &gobject, // Global actions browser_action.clone(), + window_action.clone(), action.clone(), // Page actions action_page_home.clone(), @@ -174,6 +179,7 @@ impl Tab { // Return activated struct Rc::new(Self { browser_action, + window_action, // Global actions action_page_home, action_page_history_back, @@ -192,6 +198,7 @@ impl Tab { let item = Item::new_rc( self.gobject(), self.browser_action.clone(), + self.window_action.clone(), // Local actions self.action.clone(), // Global actions @@ -337,6 +344,7 @@ impl Tab { transaction, &record.id, self.browser_action.clone(), + self.window_action.clone(), self.action.clone(), self.action_page_home.clone(), self.action_page_history_back.clone(), diff --git a/src/app/browser/window/tab/action.rs b/src/app/browser/window/tab/action.rs index 42c52857..6cd4d8af 100644 --- a/src/app/browser/window/tab/action.rs +++ b/src/app/browser/window/tab/action.rs @@ -1,7 +1,5 @@ -mod append; mod open; -use append::Append; use open::Open; use gtk::{ @@ -14,7 +12,6 @@ use std::rc::Rc; /// [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) wrapper for `Browser` actions pub struct Action { // Actions - append: Rc, open: Rc, // Group id: GString, @@ -27,7 +24,6 @@ impl Action { /// Create new `Self` pub fn new() -> Self { // Init actions - let append = Rc::new(Append::new()); let open = Rc::new(Open::new()); // Generate unique group ID @@ -37,25 +33,14 @@ impl Action { let gobject = SimpleActionGroup::new(); // Add action to given group - gobject.add_action(append.gobject()); gobject.add_action(open.gobject()); // Done - Self { - append, - open, - id, - gobject, - } + Self { open, id, gobject } } // Getters - /// Get reference `Append` action - pub fn append(&self) -> &Rc { - &self.append - } - /// Get reference `Open` action pub fn open(&self) -> &Rc { &self.open diff --git a/src/app/browser/window/tab/item.rs b/src/app/browser/window/tab/item.rs index b3668486..762eb96c 100644 --- a/src/app/browser/window/tab/item.rs +++ b/src/app/browser/window/tab/item.rs @@ -7,6 +7,7 @@ use page::Page; use widget::Widget; 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::{ @@ -31,6 +32,7 @@ impl Item { tab_view: &TabView, // Global actions browser_action: Rc, + window_action: Rc, tab_action: Rc, // @TODO action_page_home: SimpleAction, @@ -132,6 +134,7 @@ impl Item { app_browser_window_tab_id: &i64, // Actions browser_action: Rc, + window_action: Rc, tab_action: Rc, action_page_home: SimpleAction, action_page_history_back: SimpleAction, @@ -148,6 +151,7 @@ impl Item { tab_view, // Actions browser_action.clone(), + window_action.clone(), tab_action.clone(), action_page_home.clone(), action_page_history_back.clone(), diff --git a/src/app/browser/window/tab/item/page/input.rs b/src/app/browser/window/tab/item/page/input.rs index 9eb84870..d7ceb214 100644 --- a/src/app/browser/window/tab/item/page/input.rs +++ b/src/app/browser/window/tab/item/page/input.rs @@ -33,25 +33,25 @@ impl Input { // Setters pub fn set_new_response( &self, - tab_action: Rc, + action: Rc, base: Uri, title: Option<&str>, size_limit: Option, ) { self.widget.update(Some( - Response::new_rc(tab_action, base, title, size_limit).gobject(), + Response::new_rc(action, base, title, size_limit).gobject(), )); } pub fn set_new_sensitive( &self, - tab_action: Rc, + action: Rc, base: Uri, title: Option<&str>, max_length: Option, ) { self.widget.update(Some( - Sensitive::new_rc(tab_action, base, title, max_length).gobject(), + Sensitive::new_rc(action, base, title, max_length).gobject(), )); }