define actions in arc container

This commit is contained in:
yggverse 2024-09-28 03:10:07 +03:00
parent 7c78396328
commit 9a3ad366af
10 changed files with 138 additions and 77 deletions

View File

@ -30,29 +30,32 @@ impl Browser {
default_height: i32, default_height: i32,
) -> Browser { ) -> Browser {
// Init window actions // Init window actions
let action_debug = SimpleAction::new("debug", None); let action_debug = Arc::new(SimpleAction::new("debug", None));
let action_quit = SimpleAction::new("quit", None); let action_quit = Arc::new(SimpleAction::new("quit", None));
let action_update = SimpleAction::new("update", None); let action_update = Arc::new(SimpleAction::new("update", None));
let action_tab_append = SimpleAction::new("tab_append", None); let action_tab_append = Arc::new(SimpleAction::new("tab_append", None));
let action_tab_close = SimpleAction::new("tab_close", None); let action_tab_close = Arc::new(SimpleAction::new("tab_close", None));
let action_tab_close_all = SimpleAction::new("tab_close_all", None); let action_tab_close_all = Arc::new(SimpleAction::new("tab_close_all", None));
let action_tab_page_reload = SimpleAction::new("tab_page_reload", None); let action_tab_page_reload = Arc::new(SimpleAction::new("tab_page_reload", None));
let action_tab_pin = SimpleAction::new("tab_pin", None); let action_tab_pin = Arc::new(SimpleAction::new("tab_pin", None));
// Init components // Init components
// let db = db::Browser::new(connection); // let db = db::Browser::new(connection);
let header = Arc::new(Header::new( let header = Arc::new(Header::new(
&action_debug, action_debug.clone(),
&action_quit, action_quit.clone(),
&action_tab_append, action_tab_append.clone(),
&action_tab_close, action_tab_close.clone(),
&action_tab_close_all, action_tab_close_all.clone(),
&action_tab_page_reload, action_tab_page_reload.clone(),
&action_tab_pin, 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 // Init widget
let widget = ApplicationWindow::builder() let widget = ApplicationWindow::builder()
@ -63,15 +66,15 @@ impl Browser {
.child(main.widget()) .child(main.widget())
.build(); .build();
widget.add_action(&action_debug); widget.add_action(action_debug.as_ref());
widget.add_action(&action_quit); widget.add_action(action_quit.as_ref());
widget.add_action(&action_update); widget.add_action(action_update.as_ref());
widget.add_action(&action_tab_append); widget.add_action(action_tab_append.as_ref());
widget.add_action(&action_tab_close); widget.add_action(action_tab_close.as_ref());
widget.add_action(&action_tab_close_all); widget.add_action(action_tab_close_all.as_ref());
widget.add_action(&action_tab_page_reload); widget.add_action(action_tab_page_reload.as_ref());
widget.add_action(&action_tab_pin); widget.add_action(action_tab_pin.as_ref());
// Init events // Init events
action_debug.connect_activate({ action_debug.connect_activate({

View File

@ -6,6 +6,8 @@ use tray::Tray;
use gtk::{gio::SimpleAction, glib::GString, HeaderBar}; use gtk::{gio::SimpleAction, glib::GString, HeaderBar};
use std::sync::Arc;
pub struct Header { pub struct Header {
widget: HeaderBar, widget: HeaderBar,
subject: Subject, subject: Subject,
@ -14,13 +16,13 @@ pub struct Header {
impl Header { impl Header {
// Construct // Construct
pub fn new( pub fn new(
action_debug: &SimpleAction, action_debug: Arc<SimpleAction>,
action_quit: &SimpleAction, action_quit: Arc<SimpleAction>,
action_tab_append: &SimpleAction, action_tab_append: Arc<SimpleAction>,
action_tab_close: &SimpleAction, action_tab_close: Arc<SimpleAction>,
action_tab_close_all: &SimpleAction, action_tab_close_all: Arc<SimpleAction>,
action_tab_page_reload: &SimpleAction, action_tab_page_reload: Arc<SimpleAction>,
action_tab_pin: &SimpleAction, action_tab_pin: Arc<SimpleAction>,
) -> Self { ) -> Self {
// Init components // Init components
let tray = Tray::new( let tray = Tray::new(

View File

@ -1,27 +1,34 @@
mod menu; mod menu;
mod tab; mod tab;
use gtk::gio::SimpleAction;
use gtk::prelude::BoxExt;
use gtk::{Box, Orientation};
use menu::Menu; use menu::Menu;
use tab::Tab; use tab::Tab;
use gtk::{
gio::SimpleAction,
prelude::BoxExt,
{Box, Orientation},
};
use std::sync::Arc;
pub struct Tray { pub struct Tray {
widget: Box, widget: Box,
} }
impl Tray { impl Tray {
pub fn new( pub fn new(
action_debug: &SimpleAction, action_debug: Arc<SimpleAction>,
action_quit: &SimpleAction, action_quit: Arc<SimpleAction>,
action_tab_append: &SimpleAction, action_tab_append: Arc<SimpleAction>,
action_tab_close: &SimpleAction, action_tab_close: Arc<SimpleAction>,
action_tab_close_all: &SimpleAction, action_tab_close_all: Arc<SimpleAction>,
action_tab_page_reload: &SimpleAction, action_tab_page_reload: Arc<SimpleAction>,
action_tab_pin: &SimpleAction, action_tab_pin: Arc<SimpleAction>,
) -> Self { ) -> Self {
// Init components // Init components
let tab = Tab::new(action_tab_append.clone());
let menu = Menu::new( let menu = Menu::new(
action_debug, action_debug,
action_quit, action_quit,
@ -32,8 +39,6 @@ impl Tray {
action_tab_pin, action_tab_pin,
); );
let tab = Tab::new(action_tab_append);
// Init widget // Init widget
let widget = Box::builder() let widget = Box::builder()
.orientation(Orientation::Horizontal) .orientation(Orientation::Horizontal)

View File

@ -5,19 +5,21 @@ use gtk::{
MenuButton, MenuButton,
}; };
use std::sync::Arc;
pub struct Menu { pub struct Menu {
widget: MenuButton, widget: MenuButton,
} }
impl Menu { impl Menu {
pub fn new( pub fn new(
action_debug: &SimpleAction, action_debug: Arc<SimpleAction>,
action_quit: &SimpleAction, action_quit: Arc<SimpleAction>,
action_tab_append: &SimpleAction, action_tab_append: Arc<SimpleAction>,
action_tab_close: &SimpleAction, action_tab_close: Arc<SimpleAction>,
action_tab_close_all: &SimpleAction, action_tab_close_all: Arc<SimpleAction>,
action_tab_page_reload: &SimpleAction, action_tab_page_reload: Arc<SimpleAction>,
action_tab_pin: &SimpleAction, action_tab_pin: Arc<SimpleAction>,
) -> Self { ) -> Self {
// Init model // Init model
let model_tab = gio::Menu::new(); let model_tab = gio::Menu::new();
@ -72,7 +74,7 @@ impl Menu {
} }
// Private helpers // Private helpers
fn detailed_action_name(action: &SimpleAction) -> GString { fn detailed_action_name(action: Arc<SimpleAction>) -> GString {
gformat!("win.{}", action.name()) // @TODO find the way to ident parent group gformat!("win.{}", action.name()) // @TODO find the way to ident parent group
// without application-wide dependencies import // without application-wide dependencies import
} }

View File

@ -1,4 +1,5 @@
use gtk::{gio::SimpleAction, prelude::ActionExt, prelude::ButtonExt, Button}; use gtk::{gio::SimpleAction, prelude::ActionExt, prelude::ButtonExt, Button};
use std::sync::Arc;
pub struct Tab { pub struct Tab {
pub widget: Button, pub widget: Button,
@ -6,7 +7,7 @@ pub struct Tab {
impl Tab { impl Tab {
// Construct // Construct
pub fn new(action_tab_append: &SimpleAction) -> Self { pub fn new(action_tab_append: Arc<SimpleAction>) -> Self {
// Init widget // Init widget
let widget = Button::builder() let widget = Button::builder()
.icon_name("tab-new-symbolic") .icon_name("tab-new-symbolic")
@ -14,11 +15,8 @@ impl Tab {
.build(); .build();
// Init events // Init events
widget.connect_clicked({ widget.connect_clicked(move |_| {
let action_tab_append = action_tab_append.clone(); action_tab_append.activate(None);
move |_| {
action_tab_append.activate(None);
}
}); });
// Return activated struct // Return activated struct

View File

@ -13,9 +13,12 @@ pub struct Main {
impl Main { impl Main {
// Construct // Construct
pub fn new(action_tab_page_reload: &SimpleAction, action_update: &SimpleAction) -> Self { pub fn new(
action_tab_page_reload: Arc<SimpleAction>,
action_update: Arc<SimpleAction>,
) -> Self {
// Init components // 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.activate(tab.clone());
tab.append(Some(GString::from("gemini://geminiprotocol.net/")), true); // demo tab @TODO replace with session restore feature tab.append(Some(GString::from("gemini://geminiprotocol.net/")), true); // demo tab @TODO replace with session restore feature

View File

@ -5,6 +5,7 @@ use label::Label;
use page::Page; use page::Page;
use gtk::{ use gtk::{
gio::SimpleAction,
glib::{uuid_string_random, GString}, glib::{uuid_string_random, GString},
prelude::WidgetExt, prelude::WidgetExt,
GestureClick, Notebook, GestureClick, Notebook,
@ -15,6 +16,9 @@ use std::{cell::RefCell, collections::HashMap, sync::Arc};
pub struct Tab { pub struct Tab {
// GTK // GTK
widget: Notebook, widget: Notebook,
// Keep action links in memory to not require them on every tab append
action_tab_page_reload: Arc<SimpleAction>,
action_update: Arc<SimpleAction>,
// Dynamically allocated reference index // Dynamically allocated reference index
labels: RefCell<HashMap<GString, Arc<Label>>>, labels: RefCell<HashMap<GString, Arc<Label>>>,
pages: RefCell<HashMap<GString, Arc<Page>>>, pages: RefCell<HashMap<GString, Arc<Page>>>,
@ -22,9 +26,20 @@ pub struct Tab {
impl Tab { impl Tab {
// Construct // Construct
pub fn new() -> Self { pub fn new(
action_tab_page_reload: Arc<SimpleAction>,
action_update: Arc<SimpleAction>,
) -> Self {
// Init widget
let widget = Notebook::builder().scrollable(true).build();
// Return non activated struct
Self { 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 // Init empty HashMap index as no tabs appended yet
labels: RefCell::new(HashMap::new()), labels: RefCell::new(HashMap::new()),
pages: RefCell::new(HashMap::new()), pages: RefCell::new(HashMap::new()),
@ -53,7 +68,12 @@ impl Tab {
// Init new tab components // Init new tab components
let label = Arc::new(Label::new(id.clone(), false)); 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 // Register dynamically created tab components in the HashMap index
self.labels.borrow_mut().insert(id.clone(), label.clone()); self.labels.borrow_mut().insert(id.clone(), label.clone());

View File

@ -8,7 +8,7 @@ use navigation::Navigation;
use gtk::{ use gtk::{
gio::{ gio::{
ActionEntry, Cancellable, SimpleActionGroup, SocketClient, SocketProtocol, ActionEntry, Cancellable, SimpleAction, SimpleActionGroup, SocketClient, SocketProtocol,
TlsCertificateFlags, TlsCertificateFlags,
}, },
glib::{gformat, GString, Priority, Regex, RegexCompileFlags, RegexMatchFlags, Uri, UriFlags}, glib::{gformat, GString, Priority, Regex, RegexCompileFlags, RegexMatchFlags, Uri, UriFlags},
@ -32,10 +32,19 @@ pub struct Page {
impl Page { impl Page {
// Construct // Construct
pub fn new(name: GString, navigation_request_text: Option<GString>) -> Page { pub fn new(
name: GString,
navigation_request_text: Option<GString>,
action_tab_page_reload: Arc<SimpleAction>,
action_update: Arc<SimpleAction>,
) -> Page {
// Init components // Init components
let content = Arc::new(Content::new()); 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 // Init widget
let widget = Box::builder() let widget = Box::builder()

View File

@ -11,11 +11,14 @@ use reload::Reload;
use request::Request; use request::Request;
use gtk::{ use gtk::{
gio::SimpleAction,
glib::GString, glib::GString,
prelude::{BoxExt, WidgetExt}, prelude::{BoxExt, WidgetExt},
Box, DirectionType, Orientation, Box, DirectionType, Orientation,
}; };
use std::sync::Arc;
pub struct Navigation { pub struct Navigation {
// GTK // GTK
widget: Box, widget: Box,
@ -28,11 +31,15 @@ pub struct Navigation {
} }
impl Navigation { impl Navigation {
pub fn new(request_text: Option<GString>) -> Self { pub fn new(
request_text: Option<GString>,
action_tab_page_reload: Arc<SimpleAction>,
action_update: Arc<SimpleAction>,
) -> Self {
// Init components // Init components
let base = Base::new(); let base = Base::new();
let history = History::new(); let history = History::new();
let reload = Reload::new(); let reload = Reload::new(action_tab_page_reload);
let request = Request::new(request_text); let request = Request::new(request_text);
let bookmark = Bookmark::new(); let bookmark = Bookmark::new();

View File

@ -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 { pub struct Reload {
widget: Button, widget: Button,
@ -6,20 +11,27 @@ pub struct Reload {
impl Reload { impl Reload {
// Construct // Construct
pub fn new() -> Self { pub fn new(action_tab_page_reload: Arc<SimpleAction>) -> Self {
Self { // Init widget
widget: Button::builder() let widget = Button::builder()
.action_name("win.tab_page_reload") .icon_name("view-refresh-symbolic")
.icon_name("view-refresh-symbolic") .tooltip_text("Reload")
.tooltip_text("Reload") .sensitive(false)
.sensitive(false) .build();
.build(),
} // Init events
widget.connect_clicked(move |_| {
action_tab_page_reload.activate(None);
});
// Return activated struct
Self { widget }
} }
// Actions // Actions
pub fn update(&self, is_enabled: bool) { pub fn update(&self, is_enabled: bool) {
self.widget.set_sensitive(is_enabled); self.widget.set_sensitive(is_enabled);
// @TODO deactivate action
} }
// Getters // Getters