diff --git a/src/browser.rs b/src/browser.rs index dd84e86f..074ad4e4 100644 --- a/src/browser.rs +++ b/src/browser.rs @@ -60,6 +60,7 @@ impl Browser { )); let main = Arc::new(Main::new( + action_tab_page_navigation_base.clone(), action_tab_page_navigation_reload.clone(), action_update.clone(), )); @@ -134,19 +135,19 @@ impl Browser { action_tab_page_navigation_base.connect_activate({ let main = main.clone(); move |_, _| { - // @TODO + main.tab_page_navigation_base(); } }); action_tab_page_navigation_history_back.connect_activate({ - let main = main.clone(); + // let main = main.clone(); move |_, _| { // @TODO } }); action_tab_page_navigation_history_forward.connect_activate({ - let main = main.clone(); + // let main = main.clone(); move |_, _| { // @TODO } @@ -155,7 +156,7 @@ impl Browser { action_tab_page_navigation_reload.connect_activate({ let main = main.clone(); move |_, _| { - main.tab_page_reload(); + main.tab_page_navigation_reload(); } }); diff --git a/src/browser/main.rs b/src/browser/main.rs index 628f5c7d..a5e0d991 100644 --- a/src/browser/main.rs +++ b/src/browser/main.rs @@ -14,11 +14,16 @@ pub struct Main { impl Main { // Construct pub fn new( + action_tab_page_navigation_base: Arc, action_tab_page_navigation_reload: Arc, action_update: Arc, ) -> Self { // Init components - let tab = Arc::new(Tab::new(action_tab_page_navigation_reload, action_update)); + let tab = Arc::new(Tab::new( + action_tab_page_navigation_base, + action_tab_page_navigation_reload, + action_update, + )); tab.activate(tab.clone()); tab.append(Some(GString::from("gemini://geminiprotocol.net/")), true); // demo tab @TODO replace with session restore feature @@ -36,8 +41,12 @@ impl Main { self.tab.append(tab_page_navigation_request_text, true); } - pub fn tab_page_reload(&self) { - self.tab.page_reload(); + pub fn tab_page_navigation_base(&self) { + self.tab.page_navigation_base(); + } + + pub fn tab_page_navigation_reload(&self) { + self.tab.page_navigation_reload(); } pub fn tab_close(&self) { diff --git a/src/browser/main/tab.rs b/src/browser/main/tab.rs index 900fce30..c6021e32 100644 --- a/src/browser/main/tab.rs +++ b/src/browser/main/tab.rs @@ -17,6 +17,7 @@ pub struct Tab { // GTK widget: Notebook, // Keep action links in memory to not require them on every tab append + action_tab_page_navigation_base: Arc, action_tab_page_navigation_reload: Arc, action_update: Arc, // Dynamically allocated reference index @@ -27,6 +28,7 @@ pub struct Tab { impl Tab { // Construct pub fn new( + action_tab_page_navigation_base: Arc, action_tab_page_navigation_reload: Arc, action_update: Arc, ) -> Self { @@ -38,6 +40,7 @@ impl Tab { // GTK widget, // Define action links + action_tab_page_navigation_base, action_tab_page_navigation_reload, action_update, // Init empty HashMap index as no tabs appended yet @@ -76,6 +79,7 @@ impl Tab { let page = Arc::new(Page::new( id.clone(), page_navigation_request_text.clone(), + self.action_tab_page_navigation_base.clone(), self.action_tab_page_navigation_reload.clone(), self.action_update.clone(), )); @@ -144,14 +148,27 @@ impl Tab { } } - pub fn page_reload(&self) { + pub fn page_navigation_base(&self) { // Get current page if let Some(page_number) = self.widget.current_page() { // Get default widget to extract it name as the ID for childs if let Some(widget) = self.widget.nth_page(Some(page_number)) { // Get page by widget ID if let Some(page) = self.pages.borrow().get(&widget.widget_name()) { - page.reload(); + page.navigation_base(); + } + } + } + } + + pub fn page_navigation_reload(&self) { + // Get current page + if let Some(page_number) = self.widget.current_page() { + // Get default widget to extract it name as the ID for childs + if let Some(widget) = self.widget.nth_page(Some(page_number)) { + // Get page by widget ID + if let Some(page) = self.pages.borrow().get(&widget.widget_name()) { + page.navigation_reload(); } } } diff --git a/src/browser/main/tab/page.rs b/src/browser/main/tab/page.rs index c66b2efc..bb60cf5b 100644 --- a/src/browser/main/tab/page.rs +++ b/src/browser/main/tab/page.rs @@ -14,7 +14,7 @@ use gtk::{ glib::{gformat, GString, Priority, Regex, RegexCompileFlags, RegexMatchFlags, Uri, UriFlags}, prelude::{ ActionExt, ActionMapExt, BoxExt, IOStreamExt, InputStreamExtManual, OutputStreamExtManual, - SocketClientExt, StaticVariantType, WidgetExt, + SocketClientExt, StaticVariantType, ToVariant, WidgetExt, }, Box, Orientation, }; @@ -24,6 +24,7 @@ pub struct Page { // GTK widget: Box, // Actions + action_page_open: Arc, // action_tab_page_navigation_reload: Arc, action_update: Arc, // Components @@ -38,6 +39,7 @@ impl Page { pub fn new( name: GString, navigation_request_text: Option, + action_tab_page_navigation_base: Arc, action_tab_page_navigation_reload: Arc, action_update: Arc, ) -> Page { @@ -55,6 +57,7 @@ impl Page { let content = Arc::new(Content::new(action_page_open.clone())); let navigation = Arc::new(Navigation::new( navigation_request_text, + action_tab_page_navigation_base.clone(), action_tab_page_navigation_reload.clone(), action_update.clone(), )); @@ -94,6 +97,7 @@ impl Page { // GTK widget, // Actions + action_page_open, // action_tab_page_navigation_reload, action_update, // Components @@ -109,7 +113,13 @@ impl Page { self.navigation.grab_request_focus(); } - pub fn reload(&self) { + pub fn navigation_base(&self) { + if let Some(address) = self.navigation.base_address() { + self.action_page_open.activate(Some(&address.to_variant())); + } + } + + pub fn navigation_reload(&self) { // Init globals let request_text = self.navigation.request_text(); diff --git a/src/browser/main/tab/page/navigation.rs b/src/browser/main/tab/page/navigation.rs index bfe7ff26..fe1c7d79 100644 --- a/src/browser/main/tab/page/navigation.rs +++ b/src/browser/main/tab/page/navigation.rs @@ -33,11 +33,12 @@ pub struct Navigation { impl Navigation { pub fn new( request_text: Option, + action_tab_page_navigation_base: Arc, action_tab_page_navigation_reload: Arc, action_update: Arc, ) -> Self { // Init components - let base = Base::new(); + let base = Base::new(action_tab_page_navigation_base); let history = History::new(); let reload = Reload::new(action_tab_page_navigation_reload.clone()); let request = Request::new( @@ -102,6 +103,10 @@ impl Navigation { &self.widget } + pub fn base_address(&self) -> Option { + self.base.address() + } + pub fn request_text(&self) -> GString { self.request.text() } diff --git a/src/browser/main/tab/page/navigation/base.rs b/src/browser/main/tab/page/navigation/base.rs index eb5b3271..0058202f 100644 --- a/src/browser/main/tab/page/navigation/base.rs +++ b/src/browser/main/tab/page/navigation/base.rs @@ -1,35 +1,75 @@ -use gtk::{glib::Uri, prelude::WidgetExt, Button}; +use gtk::{ + gio::SimpleAction, + glib::{gformat, GString, Uri}, + prelude::{ActionExt, ButtonExt, WidgetExt}, + Button, +}; +use std::{cell::RefCell, sync::Arc}; pub struct Base { + action_tab_page_navigation_base: Arc, + uri: RefCell>, widget: Button, } impl Base { // Construct - pub fn new() -> Self { + pub fn new(action_tab_page_navigation_base: Arc) -> Self { + // Init widget let widget = Button::builder() - .action_name("win.tab_page_base") .icon_name("go-home-symbolic") .tooltip_text("Base") .sensitive(false) .build(); - Self { widget } + // Init events + widget.connect_clicked({ + let action_tab_page_navigation_base = action_tab_page_navigation_base.clone(); + move |_| { + action_tab_page_navigation_base.activate(None); + } + }); + + // Return activated struct + Self { + action_tab_page_navigation_base, + uri: RefCell::new(None), + widget, + } } // Actions pub fn update(&self, uri: Option) { - let status = match uri { + // Update sensitivity + let status = match &uri { Some(uri) => "/" != uri.path(), None => false, }; - self.widget.action_set_enabled("win.tab_page_base", status); + self.action_tab_page_navigation_base.set_enabled(status); self.widget.set_sensitive(status); + + // Update parsed cache + self.uri.replace(uri); } // Getters pub fn widget(&self) -> &Button { &self.widget } + + pub fn address(&self) -> Option { + if let Some(uri) = self.uri.take() { + let scheme = uri.scheme(); + let port = uri.port(); + if let Some(host) = uri.host() { + if port.is_positive() { + return Some(gformat!("{scheme}://{host}:{port}/")); + } else { + return Some(gformat!("{scheme}://{host}/")); + } + } + } + None + } }