diff --git a/src/browser.rs b/src/browser.rs index f939768b..7b22d862 100644 --- a/src/browser.rs +++ b/src/browser.rs @@ -30,29 +30,32 @@ impl Browser { default_height: i32, ) -> Browser { // Init window actions - let action_debug = SimpleAction::new("debug", None); - let action_quit = SimpleAction::new("quit", None); - let action_update = SimpleAction::new("update", None); + let action_debug = Arc::new(SimpleAction::new("debug", None)); + let action_quit = Arc::new(SimpleAction::new("quit", None)); + let action_update = Arc::new(SimpleAction::new("update", None)); - let action_tab_append = SimpleAction::new("tab_append", None); - let action_tab_close = SimpleAction::new("tab_close", None); - let action_tab_close_all = SimpleAction::new("tab_close_all", None); - let action_tab_page_reload = SimpleAction::new("tab_page_reload", None); - let action_tab_pin = SimpleAction::new("tab_pin", None); + let action_tab_append = Arc::new(SimpleAction::new("tab_append", None)); + let action_tab_close = Arc::new(SimpleAction::new("tab_close", None)); + let action_tab_close_all = Arc::new(SimpleAction::new("tab_close_all", None)); + let action_tab_page_reload = Arc::new(SimpleAction::new("tab_page_reload", None)); + let action_tab_pin = Arc::new(SimpleAction::new("tab_pin", None)); // Init components // let db = db::Browser::new(connection); let header = Arc::new(Header::new( - &action_debug, - &action_quit, - &action_tab_append, - &action_tab_close, - &action_tab_close_all, - &action_tab_page_reload, - &action_tab_pin, + action_debug.clone(), + action_quit.clone(), + action_tab_append.clone(), + action_tab_close.clone(), + action_tab_close_all.clone(), + action_tab_page_reload.clone(), + action_tab_pin.clone(), )); - let main = Arc::new(Main::new(&action_tab_page_reload, &action_update)); + let main = Arc::new(Main::new( + action_tab_page_reload.clone(), + action_update.clone(), + )); // Init widget let widget = ApplicationWindow::builder() @@ -63,15 +66,15 @@ impl Browser { .child(main.widget()) .build(); - widget.add_action(&action_debug); - widget.add_action(&action_quit); - widget.add_action(&action_update); + widget.add_action(action_debug.as_ref()); + widget.add_action(action_quit.as_ref()); + widget.add_action(action_update.as_ref()); - widget.add_action(&action_tab_append); - widget.add_action(&action_tab_close); - widget.add_action(&action_tab_close_all); - widget.add_action(&action_tab_page_reload); - widget.add_action(&action_tab_pin); + widget.add_action(action_tab_append.as_ref()); + widget.add_action(action_tab_close.as_ref()); + widget.add_action(action_tab_close_all.as_ref()); + widget.add_action(action_tab_page_reload.as_ref()); + widget.add_action(action_tab_pin.as_ref()); // Init events action_debug.connect_activate({ diff --git a/src/browser/header.rs b/src/browser/header.rs index 25c62404..7f0b7db7 100644 --- a/src/browser/header.rs +++ b/src/browser/header.rs @@ -6,6 +6,8 @@ use tray::Tray; use gtk::{gio::SimpleAction, glib::GString, HeaderBar}; +use std::sync::Arc; + pub struct Header { widget: HeaderBar, subject: Subject, @@ -14,13 +16,13 @@ pub struct Header { impl Header { // Construct pub fn new( - action_debug: &SimpleAction, - action_quit: &SimpleAction, - action_tab_append: &SimpleAction, - action_tab_close: &SimpleAction, - action_tab_close_all: &SimpleAction, - action_tab_page_reload: &SimpleAction, - action_tab_pin: &SimpleAction, + action_debug: Arc, + action_quit: Arc, + action_tab_append: Arc, + action_tab_close: Arc, + action_tab_close_all: Arc, + action_tab_page_reload: Arc, + action_tab_pin: Arc, ) -> Self { // Init components let tray = Tray::new( diff --git a/src/browser/header/tray.rs b/src/browser/header/tray.rs index e2f1e7b0..d1537b2c 100644 --- a/src/browser/header/tray.rs +++ b/src/browser/header/tray.rs @@ -1,27 +1,34 @@ mod menu; mod tab; -use gtk::gio::SimpleAction; -use gtk::prelude::BoxExt; -use gtk::{Box, Orientation}; use menu::Menu; use tab::Tab; +use gtk::{ + gio::SimpleAction, + prelude::BoxExt, + {Box, Orientation}, +}; + +use std::sync::Arc; + pub struct Tray { widget: Box, } impl Tray { pub fn new( - action_debug: &SimpleAction, - action_quit: &SimpleAction, - action_tab_append: &SimpleAction, - action_tab_close: &SimpleAction, - action_tab_close_all: &SimpleAction, - action_tab_page_reload: &SimpleAction, - action_tab_pin: &SimpleAction, + action_debug: Arc, + action_quit: Arc, + action_tab_append: Arc, + action_tab_close: Arc, + action_tab_close_all: Arc, + action_tab_page_reload: Arc, + action_tab_pin: Arc, ) -> Self { // Init components + let tab = Tab::new(action_tab_append.clone()); + let menu = Menu::new( action_debug, action_quit, @@ -32,8 +39,6 @@ impl Tray { action_tab_pin, ); - let tab = Tab::new(action_tab_append); - // Init widget let widget = Box::builder() .orientation(Orientation::Horizontal) diff --git a/src/browser/header/tray/menu.rs b/src/browser/header/tray/menu.rs index 9f14b667..dbc453a1 100644 --- a/src/browser/header/tray/menu.rs +++ b/src/browser/header/tray/menu.rs @@ -5,19 +5,21 @@ use gtk::{ MenuButton, }; +use std::sync::Arc; + pub struct Menu { widget: MenuButton, } impl Menu { pub fn new( - action_debug: &SimpleAction, - action_quit: &SimpleAction, - action_tab_append: &SimpleAction, - action_tab_close: &SimpleAction, - action_tab_close_all: &SimpleAction, - action_tab_page_reload: &SimpleAction, - action_tab_pin: &SimpleAction, + action_debug: Arc, + action_quit: Arc, + action_tab_append: Arc, + action_tab_close: Arc, + action_tab_close_all: Arc, + action_tab_page_reload: Arc, + action_tab_pin: Arc, ) -> Self { // Init model let model_tab = gio::Menu::new(); @@ -72,7 +74,7 @@ impl Menu { } // Private helpers -fn detailed_action_name(action: &SimpleAction) -> GString { +fn detailed_action_name(action: Arc) -> GString { gformat!("win.{}", action.name()) // @TODO find the way to ident parent group // without application-wide dependencies import } diff --git a/src/browser/header/tray/tab.rs b/src/browser/header/tray/tab.rs index 22f07221..352297f4 100644 --- a/src/browser/header/tray/tab.rs +++ b/src/browser/header/tray/tab.rs @@ -1,4 +1,5 @@ use gtk::{gio::SimpleAction, prelude::ActionExt, prelude::ButtonExt, Button}; +use std::sync::Arc; pub struct Tab { pub widget: Button, @@ -6,7 +7,7 @@ pub struct Tab { impl Tab { // Construct - pub fn new(action_tab_append: &SimpleAction) -> Self { + pub fn new(action_tab_append: Arc) -> Self { // Init widget let widget = Button::builder() .icon_name("tab-new-symbolic") @@ -14,11 +15,8 @@ impl Tab { .build(); // Init events - widget.connect_clicked({ - let action_tab_append = action_tab_append.clone(); - move |_| { - action_tab_append.activate(None); - } + widget.connect_clicked(move |_| { + action_tab_append.activate(None); }); // Return activated struct diff --git a/src/browser/main.rs b/src/browser/main.rs index 654b73d2..45d07fd7 100644 --- a/src/browser/main.rs +++ b/src/browser/main.rs @@ -13,9 +13,12 @@ pub struct Main { impl Main { // Construct - pub fn new(action_tab_page_reload: &SimpleAction, action_update: &SimpleAction) -> Self { + pub fn new( + action_tab_page_reload: Arc, + action_update: Arc, + ) -> Self { // Init components - let tab = Arc::new(Tab::new()); + let tab = Arc::new(Tab::new(action_tab_page_reload, action_update)); tab.activate(tab.clone()); tab.append(Some(GString::from("gemini://geminiprotocol.net/")), true); // demo tab @TODO replace with session restore feature diff --git a/src/browser/main/tab.rs b/src/browser/main/tab.rs index 4af58ac2..0730bfbb 100644 --- a/src/browser/main/tab.rs +++ b/src/browser/main/tab.rs @@ -5,6 +5,7 @@ use label::Label; use page::Page; use gtk::{ + gio::SimpleAction, glib::{uuid_string_random, GString}, prelude::WidgetExt, GestureClick, Notebook, @@ -15,6 +16,9 @@ use std::{cell::RefCell, collections::HashMap, sync::Arc}; pub struct Tab { // GTK widget: Notebook, + // Keep action links in memory to not require them on every tab append + action_tab_page_reload: Arc, + action_update: Arc, // Dynamically allocated reference index labels: RefCell>>, pages: RefCell>>, @@ -22,9 +26,20 @@ pub struct Tab { impl Tab { // Construct - pub fn new() -> Self { + pub fn new( + action_tab_page_reload: Arc, + action_update: Arc, + ) -> Self { + // Init widget + let widget = Notebook::builder().scrollable(true).build(); + + // Return non activated struct Self { - widget: Notebook::builder().scrollable(true).build(), + // GTK + widget, + // Define action links + action_tab_page_reload, + action_update, // Init empty HashMap index as no tabs appended yet labels: RefCell::new(HashMap::new()), pages: RefCell::new(HashMap::new()), @@ -53,7 +68,12 @@ impl Tab { // Init new tab components let label = Arc::new(Label::new(id.clone(), false)); - let page = Arc::new(Page::new(id.clone(), page_navigation_request_text)); + let page = Arc::new(Page::new( + id.clone(), + page_navigation_request_text, + self.action_tab_page_reload.clone(), + self.action_update.clone(), + )); // Register dynamically created tab components in the HashMap index self.labels.borrow_mut().insert(id.clone(), label.clone()); diff --git a/src/browser/main/tab/page.rs b/src/browser/main/tab/page.rs index e1defe39..e5be6483 100644 --- a/src/browser/main/tab/page.rs +++ b/src/browser/main/tab/page.rs @@ -8,7 +8,7 @@ use navigation::Navigation; use gtk::{ gio::{ - ActionEntry, Cancellable, SimpleActionGroup, SocketClient, SocketProtocol, + ActionEntry, Cancellable, SimpleAction, SimpleActionGroup, SocketClient, SocketProtocol, TlsCertificateFlags, }, glib::{gformat, GString, Priority, Regex, RegexCompileFlags, RegexMatchFlags, Uri, UriFlags}, @@ -32,10 +32,19 @@ pub struct Page { impl Page { // Construct - pub fn new(name: GString, navigation_request_text: Option) -> Page { + pub fn new( + name: GString, + navigation_request_text: Option, + action_tab_page_reload: Arc, + action_update: Arc, + ) -> Page { // Init components let content = Arc::new(Content::new()); - let navigation = Arc::new(Navigation::new(navigation_request_text)); + let navigation = Arc::new(Navigation::new( + navigation_request_text, + action_tab_page_reload, + action_update, + )); // Init widget let widget = Box::builder() diff --git a/src/browser/main/tab/page/navigation.rs b/src/browser/main/tab/page/navigation.rs index e96ad717..029c81fd 100644 --- a/src/browser/main/tab/page/navigation.rs +++ b/src/browser/main/tab/page/navigation.rs @@ -11,11 +11,14 @@ use reload::Reload; use request::Request; use gtk::{ + gio::SimpleAction, glib::GString, prelude::{BoxExt, WidgetExt}, Box, DirectionType, Orientation, }; +use std::sync::Arc; + pub struct Navigation { // GTK widget: Box, @@ -28,11 +31,15 @@ pub struct Navigation { } impl Navigation { - pub fn new(request_text: Option) -> Self { + pub fn new( + request_text: Option, + action_tab_page_reload: Arc, + action_update: Arc, + ) -> Self { // Init components let base = Base::new(); let history = History::new(); - let reload = Reload::new(); + let reload = Reload::new(action_tab_page_reload); let request = Request::new(request_text); let bookmark = Bookmark::new(); diff --git a/src/browser/main/tab/page/navigation/reload.rs b/src/browser/main/tab/page/navigation/reload.rs index 392e9055..a2de0e03 100644 --- a/src/browser/main/tab/page/navigation/reload.rs +++ b/src/browser/main/tab/page/navigation/reload.rs @@ -1,4 +1,9 @@ -use gtk::{prelude::WidgetExt, Button}; +use gtk::{ + gio::SimpleAction, + prelude::{ActionExt, ButtonExt, WidgetExt}, + Button, +}; +use std::sync::Arc; pub struct Reload { widget: Button, @@ -6,20 +11,27 @@ pub struct Reload { impl Reload { // Construct - pub fn new() -> Self { - Self { - widget: Button::builder() - .action_name("win.tab_page_reload") - .icon_name("view-refresh-symbolic") - .tooltip_text("Reload") - .sensitive(false) - .build(), - } + pub fn new(action_tab_page_reload: Arc) -> Self { + // Init widget + let widget = Button::builder() + .icon_name("view-refresh-symbolic") + .tooltip_text("Reload") + .sensitive(false) + .build(); + + // Init events + widget.connect_clicked(move |_| { + action_tab_page_reload.activate(None); + }); + + // Return activated struct + Self { widget } } // Actions pub fn update(&self, is_enabled: bool) { self.widget.set_sensitive(is_enabled); + // @TODO deactivate action } // Getters