From b56b6e3879e1b4ff2f5173056c2db7e184791357 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 28 Sep 2024 01:29:05 +0300 Subject: [PATCH] begin actions encapsulation --- README.md | 5 +++ src/browser.rs | 73 ++++++++++++++++++++------------- src/browser/header.rs | 10 +++-- src/browser/header/tray.rs | 8 +++- src/browser/header/tray/menu.rs | 19 +++++++-- src/browser/main.rs | 8 +++- 6 files changed, 83 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 41ae0ff8..08d4945d 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,11 @@ Guide and protocol draft * unwrapped main `Self` structure * granted ownership for new object created * public link getter for privately constructed widget +* Public API oriented to simple (`integer`, `boolean`), standard (`std::*`) or system-wide (`gio`, `glib`, etc) data types usage to reduce internal dependencies from app implementation + +#### GTK + +* Operate with [action objects](https://docs.gtk.org/gio/class.SimpleAction.html) instead of names like `win.action`. This allows to follow encapsulation, because by the goal, module must know nothing about parent presets - for example, define some action in parent, then delegate object created as argument ### Contribution diff --git a/src/browser.rs b/src/browser.rs index 2a69e7d5..d5fd8b5c 100644 --- a/src/browser.rs +++ b/src/browser.rs @@ -6,8 +6,8 @@ use header::Header; use main::Main; use gtk::{ - gio::ActionEntry, - prelude::{ActionMapExtManual, GtkWindowExt}, + gio::{ActionEntry, SimpleAction}, + prelude::{ActionMapExt, ActionMapExtManual, GtkWindowExt}, Application, ApplicationWindow, }; use std::sync::Arc; @@ -17,8 +17,8 @@ pub struct Browser { // db: db::Browser, widget: ApplicationWindow, // Components - header: Arc
, - main: Arc
, + // header: Arc
, + // main: Arc
, } impl Browser { @@ -29,11 +29,18 @@ impl Browser { default_width: i32, 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); + // Init components // let db = db::Browser::new(connection); - let header = Arc::new(header::Header::new()); - let main = Arc::new(main::Main::new()); + let header = Arc::new(Header::new(&action_debug, &action_quit)); + let main = Arc::new(Main::new(&action_debug, &action_quit, &action_update)); + + // Init widget let widget = ApplicationWindow::builder() .application(app) .default_width(default_width) @@ -42,28 +49,36 @@ impl Browser { .child(main.widget()) .build(); - // Init actions + widget.add_action(&action_debug); + widget.add_action(&action_quit); + widget.add_action(&action_update); + + // Init events + action_debug.connect_activate({ + let target = widget.clone(); + move |_, _| { + target.emit_enable_debugging(true); + } + }); + + action_quit.connect_activate({ + let target = widget.clone(); + move |_, _| { + target.close(); + } + }); + + action_update.connect_activate({ + let header = header.clone(); + let main = main.clone(); + move |_, _| { + main.update(); + header.update(main.tab_page_title(), main.tab_page_description()); + } + }); + + // Init actions @TODO widget.add_action_entries([ - ActionEntry::builder("update") - .activate({ - let header = header.clone(); - let main = main.clone(); - move |_, _, _| { - main.update(); - header.update(main.tab_page_title(), main.tab_page_description()); - } - }) - .build(), - ActionEntry::builder("debug") - .activate(|this: &ApplicationWindow, _, _| { - this.emit_enable_debugging(true); - }) - .build(), - ActionEntry::builder("quit") - .activate(|this: &ApplicationWindow, _, _| { - this.close(); - }) - .build(), ActionEntry::builder("tab_append") .activate({ let main = main.clone(); @@ -110,8 +125,8 @@ impl Browser { Self { // db, widget, - header, - main, + // header, + // main, } } diff --git a/src/browser/header.rs b/src/browser/header.rs index c5365fe6..7a227ef2 100644 --- a/src/browser/header.rs +++ b/src/browser/header.rs @@ -4,7 +4,7 @@ mod tray; use subject::Subject; use tray::Tray; -use gtk::{glib::GString, HeaderBar}; +use gtk::{gio::SimpleAction, glib::GString, HeaderBar}; pub struct Header { widget: HeaderBar, @@ -13,14 +13,18 @@ pub struct Header { impl Header { // Construct - pub fn new() -> Self { - let tray = Tray::new(); + pub fn new(action_debug: &SimpleAction, action_quit: &SimpleAction) -> Self { + // Init components + let tray = Tray::new(action_debug, action_quit); + let subject = Subject::new(); + // Init widget let widget = HeaderBar::builder().build(); widget.pack_start(tray.widget()); widget.set_title_widget(Some(subject.widget())); + // Return new struct Self { widget, subject } } diff --git a/src/browser/header/tray.rs b/src/browser/header/tray.rs index 3907786e..8fc391a5 100644 --- a/src/browser/header/tray.rs +++ b/src/browser/header/tray.rs @@ -1,6 +1,7 @@ mod menu; mod tab; +use gtk::gio::SimpleAction; use gtk::prelude::BoxExt; use gtk::{Box, Orientation}; use menu::Menu; @@ -11,10 +12,12 @@ pub struct Tray { } impl Tray { - pub fn new() -> Self { - let menu = Menu::new(); + pub fn new(action_debug: &SimpleAction, action_quit: &SimpleAction) -> Self { + // Init components + let menu = Menu::new(action_debug, action_quit); let tab = Tab::new(); + // Init widget let widget = Box::builder() .orientation(Orientation::Horizontal) .spacing(8) @@ -23,6 +26,7 @@ impl Tray { widget.append(menu.widget()); widget.append(tab.widget()); + // Return new struct Self { widget } } diff --git a/src/browser/header/tray/menu.rs b/src/browser/header/tray/menu.rs index c5bae60e..04c74553 100644 --- a/src/browser/header/tray/menu.rs +++ b/src/browser/header/tray/menu.rs @@ -1,11 +1,16 @@ -use gtk::{gio, MenuButton}; +use gtk::{ + gio::{self, MenuItem, SimpleAction}, + glib::{gformat, GString}, + prelude::ActionExt, + MenuButton, +}; pub struct Menu { widget: MenuButton, } impl Menu { - pub fn new() -> Self { + pub fn new(action_debug: &SimpleAction, action_quit: &SimpleAction) -> Self { // Init model let model_tab = gio::Menu::new(); model_tab.append(Some("New"), Some("win.tab_append")); @@ -30,9 +35,10 @@ impl Menu { model_tab.append_submenu(Some("Close"), &model_tab_close); let model = gio::Menu::new(); + model.append_submenu(Some("Tab"), &model_tab); - model.append(Some("Debug"), Some("win.debug")); - model.append(Some("Quit"), Some("win.quit")); + model.append(Some("Debug"), Some(&detailed_action_name(action_debug))); + model.append(Some("Quit"), Some(&detailed_action_name(action_quit))); // Init widget let widget = MenuButton::builder().tooltip_text("Menu").build(); @@ -47,3 +53,8 @@ impl Menu { &self.widget } } + +// Private helpers +fn detailed_action_name(action: &SimpleAction) -> GString { + gformat!("win.{}", action.name()) // @TODO +} diff --git a/src/browser/main.rs b/src/browser/main.rs index 41300599..f0726192 100644 --- a/src/browser/main.rs +++ b/src/browser/main.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use tab::Tab; -use gtk::{glib::GString, prelude::BoxExt, Box, Orientation}; +use gtk::{gio::SimpleAction, glib::GString, prelude::BoxExt, Box, Orientation}; pub struct Main { tab: Arc, @@ -13,7 +13,11 @@ pub struct Main { impl Main { // Construct - pub fn new() -> Self { + pub fn new( + action_debug: &SimpleAction, + action_quit: &SimpleAction, + action_update: &SimpleAction, + ) -> Self { // Init components let tab = Arc::new(Tab::new());