Browse Source

begin actions encapsulation

master
yggverse 2 months ago
parent
commit
b56b6e3879
  1. 5
      README.md
  2. 73
      src/browser.rs
  3. 10
      src/browser/header.rs
  4. 8
      src/browser/header/tray.rs
  5. 19
      src/browser/header/tray/menu.rs
  6. 8
      src/browser/main.rs

5
README.md

@ -51,6 +51,11 @@ Guide and protocol draft
* unwrapped main `Self` structure * unwrapped main `Self` structure
* granted ownership for new object created * granted ownership for new object created
* public link getter for privately constructed widget * 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 ### Contribution

73
src/browser.rs

@ -6,8 +6,8 @@ use header::Header;
use main::Main; use main::Main;
use gtk::{ use gtk::{
gio::ActionEntry, gio::{ActionEntry, SimpleAction},
prelude::{ActionMapExtManual, GtkWindowExt}, prelude::{ActionMapExt, ActionMapExtManual, GtkWindowExt},
Application, ApplicationWindow, Application, ApplicationWindow,
}; };
use std::sync::Arc; use std::sync::Arc;
@ -17,8 +17,8 @@ pub struct Browser {
// db: db::Browser, // db: db::Browser,
widget: ApplicationWindow, widget: ApplicationWindow,
// Components // Components
header: Arc<Header>, // header: Arc<Header>,
main: Arc<Main>, // main: Arc<Main>,
} }
impl Browser { impl Browser {
@ -29,11 +29,18 @@ impl Browser {
default_width: i32, default_width: i32,
default_height: i32, default_height: i32,
) -> Browser { ) -> 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 // Init components
// let db = db::Browser::new(connection); // let db = db::Browser::new(connection);
let header = Arc::new(header::Header::new()); let header = Arc::new(Header::new(&action_debug, &action_quit));
let main = Arc::new(main::Main::new());
let main = Arc::new(Main::new(&action_debug, &action_quit, &action_update));
// Init widget
let widget = ApplicationWindow::builder() let widget = ApplicationWindow::builder()
.application(app) .application(app)
.default_width(default_width) .default_width(default_width)
@ -42,28 +49,36 @@ impl Browser {
.child(main.widget()) .child(main.widget())
.build(); .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([ 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") ActionEntry::builder("tab_append")
.activate({ .activate({
let main = main.clone(); let main = main.clone();
@ -110,8 +125,8 @@ impl Browser {
Self { Self {
// db, // db,
widget, widget,
header, // header,
main, // main,
} }
} }

10
src/browser/header.rs

@ -4,7 +4,7 @@ mod tray;
use subject::Subject; use subject::Subject;
use tray::Tray; use tray::Tray;
use gtk::{glib::GString, HeaderBar}; use gtk::{gio::SimpleAction, glib::GString, HeaderBar};
pub struct Header { pub struct Header {
widget: HeaderBar, widget: HeaderBar,
@ -13,14 +13,18 @@ pub struct Header {
impl Header { impl Header {
// Construct // Construct
pub fn new() -> Self { pub fn new(action_debug: &SimpleAction, action_quit: &SimpleAction) -> Self {
let tray = Tray::new(); // Init components
let tray = Tray::new(action_debug, action_quit);
let subject = Subject::new(); let subject = Subject::new();
// Init widget
let widget = HeaderBar::builder().build(); let widget = HeaderBar::builder().build();
widget.pack_start(tray.widget()); widget.pack_start(tray.widget());
widget.set_title_widget(Some(subject.widget())); widget.set_title_widget(Some(subject.widget()));
// Return new struct
Self { widget, subject } Self { widget, subject }
} }

8
src/browser/header/tray.rs

@ -1,6 +1,7 @@
mod menu; mod menu;
mod tab; mod tab;
use gtk::gio::SimpleAction;
use gtk::prelude::BoxExt; use gtk::prelude::BoxExt;
use gtk::{Box, Orientation}; use gtk::{Box, Orientation};
use menu::Menu; use menu::Menu;
@ -11,10 +12,12 @@ pub struct Tray {
} }
impl Tray { impl Tray {
pub fn new() -> Self { pub fn new(action_debug: &SimpleAction, action_quit: &SimpleAction) -> Self {
let menu = Menu::new(); // Init components
let menu = Menu::new(action_debug, action_quit);
let tab = Tab::new(); let tab = Tab::new();
// Init widget
let widget = Box::builder() let widget = Box::builder()
.orientation(Orientation::Horizontal) .orientation(Orientation::Horizontal)
.spacing(8) .spacing(8)
@ -23,6 +26,7 @@ impl Tray {
widget.append(menu.widget()); widget.append(menu.widget());
widget.append(tab.widget()); widget.append(tab.widget());
// Return new struct
Self { widget } Self { widget }
} }

19
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 { pub struct Menu {
widget: MenuButton, widget: MenuButton,
} }
impl Menu { impl Menu {
pub fn new() -> Self { pub fn new(action_debug: &SimpleAction, action_quit: &SimpleAction) -> Self {
// Init model // Init model
let model_tab = gio::Menu::new(); let model_tab = gio::Menu::new();
model_tab.append(Some("New"), Some("win.tab_append")); model_tab.append(Some("New"), Some("win.tab_append"));
@ -30,9 +35,10 @@ impl Menu {
model_tab.append_submenu(Some("Close"), &model_tab_close); model_tab.append_submenu(Some("Close"), &model_tab_close);
let model = gio::Menu::new(); let model = gio::Menu::new();
model.append_submenu(Some("Tab"), &model_tab); model.append_submenu(Some("Tab"), &model_tab);
model.append(Some("Debug"), Some("win.debug")); model.append(Some("Debug"), Some(&detailed_action_name(action_debug)));
model.append(Some("Quit"), Some("win.quit")); model.append(Some("Quit"), Some(&detailed_action_name(action_quit)));
// Init widget // Init widget
let widget = MenuButton::builder().tooltip_text("Menu").build(); let widget = MenuButton::builder().tooltip_text("Menu").build();
@ -47,3 +53,8 @@ impl Menu {
&self.widget &self.widget
} }
} }
// Private helpers
fn detailed_action_name(action: &SimpleAction) -> GString {
gformat!("win.{}", action.name()) // @TODO
}

8
src/browser/main.rs

@ -4,7 +4,7 @@ use std::sync::Arc;
use tab::Tab; use tab::Tab;
use gtk::{glib::GString, prelude::BoxExt, Box, Orientation}; use gtk::{gio::SimpleAction, glib::GString, prelude::BoxExt, Box, Orientation};
pub struct Main { pub struct Main {
tab: Arc<Tab>, tab: Arc<Tab>,
@ -13,7 +13,11 @@ pub struct Main {
impl Main { impl Main {
// Construct // Construct
pub fn new() -> Self { pub fn new(
action_debug: &SimpleAction,
action_quit: &SimpleAction,
action_update: &SimpleAction,
) -> Self {
// Init components // Init components
let tab = Arc::new(Tab::new()); let tab = Arc::new(Tab::new());

Loading…
Cancel
Save