From ce29a06dda55a9636fd00626af2b6cd2ca1742cc Mon Sep 17 00:00:00 2001 From: yggverse Date: Thu, 10 Oct 2024 23:34:06 +0300 Subject: [PATCH] begin libadwaita headerbar tabs integration --- src/app/browser/window.rs | 37 ++++++------- src/app/browser/window/header.rs | 36 +++++------- .../browser/window/header/{tray.rs => bar.rs} | 55 ++++++++++--------- src/app/browser/window/header/bar/append.rs | 24 ++++++++ .../{tray/tab.rs => bar/append/widget.rs} | 21 ++++--- src/app/browser/window/header/bar/control.rs | 24 ++++++++ .../window/header/bar/control/widget.rs | 20 +++++++ .../window/header/{tray => bar}/menu.rs | 18 +++--- .../browser/window/header/bar/menu/widget.rs | 26 +++++++++ src/app/browser/window/header/bar/tab.rs | 24 ++++++++ .../browser/window/header/bar/tab/widget.rs | 20 +++++++ src/app/browser/window/header/bar/widget.rs | 34 ++++++++++++ src/app/browser/window/header/title.rs | 39 ------------- src/app/browser/window/header/widget.rs | 16 +++--- src/app/browser/window/tab.rs | 27 ++------- src/app/browser/window/widget.rs | 4 +- 16 files changed, 269 insertions(+), 156 deletions(-) rename src/app/browser/window/header/{tray.rs => bar.rs} (61%) create mode 100644 src/app/browser/window/header/bar/append.rs rename src/app/browser/window/header/{tray/tab.rs => bar/append/widget.rs} (53%) create mode 100644 src/app/browser/window/header/bar/control.rs create mode 100644 src/app/browser/window/header/bar/control/widget.rs rename src/app/browser/window/header/{tray => bar}/menu.rs (93%) create mode 100644 src/app/browser/window/header/bar/menu/widget.rs create mode 100644 src/app/browser/window/header/bar/tab.rs create mode 100644 src/app/browser/window/header/bar/tab/widget.rs create mode 100644 src/app/browser/window/header/bar/widget.rs delete mode 100644 src/app/browser/window/header/title.rs diff --git a/src/app/browser/window.rs b/src/app/browser/window.rs index a0a8e742..332b5418 100644 --- a/src/app/browser/window.rs +++ b/src/app/browser/window.rs @@ -14,7 +14,7 @@ use std::sync::Arc; use gtk::{gio::SimpleAction, glib::GString, Box}; pub struct Window { - header: Arc
, + //header: Arc
, tab: Arc, widget: Arc, } @@ -36,8 +36,18 @@ impl Window { action_tab_page_navigation_reload: Arc, action_tab_pin: Arc, ) -> Self { + // @TODO testing + let tab_view = adw::TabView::new(); + + let p1 = tab_view.append(>k::Label::new(Some("test 1"))); + let p2 = tab_view.append(>k::Label::new(Some("test 2"))); + + p1.set_title("title 1"); + p2.set_title("title 2"); + // Init components - let header = Arc::new(Header::new( + let header = Header::new_arc( + // Actions action_tool_debug.clone(), action_tool_profile_directory.clone(), action_quit.clone(), @@ -49,15 +59,17 @@ impl Window { action_tab_page_navigation_history_forward.clone(), action_tab_page_navigation_reload.clone(), action_tab_pin.clone(), - )); + // Widgets + &tab_view, + ); - let tab = Arc::new(Tab::new( + let tab = Tab::new_arc( action_tab_page_navigation_base, action_tab_page_navigation_history_back, action_tab_page_navigation_history_forward, action_tab_page_navigation_reload, action_update, - )); + ); tab.activate(tab.clone()); // GTK @@ -65,7 +77,7 @@ impl Window { // Init struct Self { - header, + //header, tab, widget, } @@ -105,19 +117,6 @@ impl Window { } pub fn update(&self) { - // Update header - let title = match self.tab.page_title() { - Some(value) => value, - None => GString::new(), // @TODO - }; - - let subtitle = match self.tab.page_description() { - Some(value) => value, - None => GString::new(), // @TODO - }; - - self.header.update(title.as_str(), subtitle.as_str()); - self.tab.update(); } diff --git a/src/app/browser/window/header.rs b/src/app/browser/window/header.rs index 6c543f2a..53bb061d 100644 --- a/src/app/browser/window/header.rs +++ b/src/app/browser/window/header.rs @@ -1,24 +1,21 @@ -mod title; -mod tray; +mod bar; mod widget; -use title::Title; -use tray::Tray; +use bar::Bar; use widget::Widget; -use adw::HeaderBar; +use adw::{TabView, ToolbarView}; use gtk::gio::SimpleAction; use std::sync::Arc; pub struct Header { - title: Arc, - // tray: Arc<Subject>, widget: Arc<Widget>, } impl Header { // Construct - pub fn new( + pub fn new_arc( + // Actions action_tool_debug: Arc<SimpleAction>, action_tool_profile_directory: Arc<SimpleAction>, action_quit: Arc<SimpleAction>, @@ -30,9 +27,11 @@ impl Header { action_tab_page_navigation_history_forward: Arc<SimpleAction>, action_tab_page_navigation_reload: Arc<SimpleAction>, action_tab_pin: Arc<SimpleAction>, - ) -> Self { + // Widgets + tab_view: &TabView, + ) -> Arc<Self> { // Init components - let tray = Tray::new( + let bar = Bar::new_arc( action_tool_debug, action_tool_profile_directory, action_quit, @@ -44,24 +43,17 @@ impl Header { action_tab_page_navigation_history_forward, action_tab_page_navigation_reload, action_tab_pin, + tab_view, ); - let title = Arc::new(Title::new()); - - // Init widget - let widget = Arc::new(Widget::new(tray.gobject(), Some(title.gobject()))); - // Return new struct - Self { title, widget } - } - - // Actions - pub fn update(&self, title: &str, description: &str) { - self.title.update(title, description); + Arc::new(Self { + widget: Widget::new_arc(bar.gobject()), + }) } // Getters - pub fn gobject(&self) -> &HeaderBar { + pub fn gobject(&self) -> &ToolbarView { &self.widget.gobject() } } diff --git a/src/app/browser/window/header/tray.rs b/src/app/browser/window/header/bar.rs similarity index 61% rename from src/app/browser/window/header/tray.rs rename to src/app/browser/window/header/bar.rs index aa541475..3408bcae 100644 --- a/src/app/browser/window/header/tray.rs +++ b/src/app/browser/window/header/bar.rs @@ -1,23 +1,26 @@ +mod append; +mod control; mod menu; mod tab; +mod widget; +use append::Append; +use control::Control; use menu::Menu; use tab::Tab; +use widget::Widget; -use gtk::{ - gio::SimpleAction, - prelude::BoxExt, - {Box, Orientation}, -}; - +use adw::TabView; +use gtk::{gio::SimpleAction, Box}; use std::sync::Arc; -pub struct Tray { - gobject: Box, +pub struct Bar { + widget: Arc<Widget>, } -impl Tray { - pub fn new( +impl Bar { + // Construct + pub fn new_arc( action_tool_debug: Arc<SimpleAction>, action_tool_profile_directory: Arc<SimpleAction>, action_quit: Arc<SimpleAction>, @@ -29,11 +32,13 @@ impl Tray { action_tab_page_navigation_history_forward: Arc<SimpleAction>, action_tab_page_navigation_reload: Arc<SimpleAction>, action_tab_pin: Arc<SimpleAction>, - ) -> Self { + view: &TabView, + ) -> Arc<Self> { // Init components - let tab = Tab::new(action_tab_append.clone()); - - let menu = Menu::new( + let control = Control::new_arc(); + let tab = Tab::new_arc(view); + let append = Append::new_arc(action_tab_append.clone()); + let menu = Menu::new_arc( action_tool_debug, action_tool_profile_directory, action_quit, @@ -47,21 +52,19 @@ impl Tray { action_tab_pin, ); - // Init widget - let gobject = Box::builder() - .orientation(Orientation::Horizontal) - .spacing(8) - .build(); - - gobject.append(menu.gobject()); - gobject.append(tab.gobject()); - - // Return new struct - Self { gobject } + // Build result + Arc::new(Self { + widget: Widget::new_arc( + control.gobject(), + append.gobject(), + menu.gobject(), + tab.gobject(), + ), + }) } // Getters pub fn gobject(&self) -> &Box { - &self.gobject + &self.widget.gobject() } } diff --git a/src/app/browser/window/header/bar/append.rs b/src/app/browser/window/header/bar/append.rs new file mode 100644 index 00000000..ebada7f9 --- /dev/null +++ b/src/app/browser/window/header/bar/append.rs @@ -0,0 +1,24 @@ +mod widget; + +use widget::Widget; + +use gtk::{gio::SimpleAction, Button}; +use std::sync::Arc; + +pub struct Append { + pub widget: Arc<Widget>, +} + +impl Append { + // Construct + pub fn new_arc(action_tab_append: Arc<SimpleAction>) -> Arc<Self> { + Arc::new(Self { + widget: Widget::new_arc(action_tab_append), + }) + } + + // Getters + pub fn gobject(&self) -> &Button { + &self.widget.gobject() + } +} diff --git a/src/app/browser/window/header/tray/tab.rs b/src/app/browser/window/header/bar/append/widget.rs similarity index 53% rename from src/app/browser/window/header/tray/tab.rs rename to src/app/browser/window/header/bar/append/widget.rs index 2dbeaaf4..aada2f4d 100644 --- a/src/app/browser/window/header/tray/tab.rs +++ b/src/app/browser/window/header/bar/append/widget.rs @@ -1,16 +1,22 @@ -use gtk::{gio::SimpleAction, prelude::ActionExt, prelude::ButtonExt, Button}; +use gtk::{ + gio::SimpleAction, + prelude::{ActionExt, ButtonExt}, + Align, Button, +}; use std::sync::Arc; -pub struct Tab { - pub gobject: Button, +pub struct Widget { + gobject: Button, } -impl Tab { +impl Widget { // Construct - pub fn new(action_tab_append: Arc<SimpleAction>) -> Self { - // Init widget + pub fn new_arc(action_tab_append: Arc<SimpleAction>) -> Arc<Self> { + // Init gobject let gobject = Button::builder() .icon_name("tab-new-symbolic") + .css_classes(["flat"]) + .valign(Align::Center) .tooltip_text("New tab") .build(); @@ -19,8 +25,7 @@ impl Tab { action_tab_append.activate(None); }); - // Return activated struct - Self { gobject } + Arc::new(Self { gobject }) } // Getters diff --git a/src/app/browser/window/header/bar/control.rs b/src/app/browser/window/header/bar/control.rs new file mode 100644 index 00000000..b4690818 --- /dev/null +++ b/src/app/browser/window/header/bar/control.rs @@ -0,0 +1,24 @@ +mod widget; + +use widget::Widget; + +use gtk::WindowControls; +use std::sync::Arc; + +pub struct Control { + widget: Arc<Widget>, +} + +impl Control { + // Construct + pub fn new_arc() -> Arc<Self> { + Arc::new(Self { + widget: Widget::new_arc(), + }) + } + + // Getters + pub fn gobject(&self) -> &WindowControls { + &self.widget.gobject() + } +} diff --git a/src/app/browser/window/header/bar/control/widget.rs b/src/app/browser/window/header/bar/control/widget.rs new file mode 100644 index 00000000..f447839d --- /dev/null +++ b/src/app/browser/window/header/bar/control/widget.rs @@ -0,0 +1,20 @@ +use gtk::{PackType, WindowControls}; +use std::sync::Arc; + +pub struct Widget { + gobject: WindowControls, +} + +impl Widget { + // Construct + pub fn new_arc() -> Arc<Self> { + Arc::new(Self { + gobject: WindowControls::new(PackType::End), + }) + } + + // Getters + pub fn gobject(&self) -> &WindowControls { + &self.gobject + } +} diff --git a/src/app/browser/window/header/tray/menu.rs b/src/app/browser/window/header/bar/menu.rs similarity index 93% rename from src/app/browser/window/header/tray/menu.rs rename to src/app/browser/window/header/bar/menu.rs index 331b87e3..bdd91699 100644 --- a/src/app/browser/window/header/tray/menu.rs +++ b/src/app/browser/window/header/bar/menu.rs @@ -1,3 +1,7 @@ +mod widget; + +use widget::Widget; + use gtk::{ gio::{self, SimpleAction}, glib::{gformat, GString}, @@ -8,11 +12,11 @@ use gtk::{ use std::sync::Arc; pub struct Menu { - gobject: MenuButton, + widget: Arc<Widget>, } #[rustfmt::skip] // @TODO template builder? impl Menu { - pub fn new( + pub fn new_arc( action_tool_debug: Arc<SimpleAction>, action_tool_profile_directory: Arc<SimpleAction>, action_quit: Arc<SimpleAction>, @@ -24,7 +28,7 @@ impl Menu { action_tab_page_navigation_history_forward: Arc<SimpleAction>, action_tab_page_navigation_reload: Arc<SimpleAction>, action_tab_pin: Arc<SimpleAction>, - ) -> Self { + ) -> Arc<Self> { // Init model let model = gio::Menu::new(); @@ -65,17 +69,13 @@ impl Menu { model.append(Some("Quit"), Some(&detailed_action_name(action_quit))); - // Init widget - let gobject = MenuButton::builder().tooltip_text("Menu").build(); - gobject.set_menu_model(Some(&model)); - // Result - Self { gobject } + Arc::new(Self { widget:Widget::new_arc(&model) }) } // Getters pub fn gobject(&self) -> &MenuButton { - &self.gobject + &self.widget.gobject() } } diff --git a/src/app/browser/window/header/bar/menu/widget.rs b/src/app/browser/window/header/bar/menu/widget.rs new file mode 100644 index 00000000..7056be03 --- /dev/null +++ b/src/app/browser/window/header/bar/menu/widget.rs @@ -0,0 +1,26 @@ +use gtk::{gio::Menu, Align, MenuButton}; +use std::sync::Arc; + +pub struct Widget { + gobject: MenuButton, +} + +impl Widget { + // Construct + pub fn new_arc(model: &Menu) -> Arc<Self> { + Arc::new(Self { + gobject: MenuButton::builder() + .css_classes(["flat"]) + .icon_name("open-menu-symbolic") + .menu_model(model) + .tooltip_text("Menu") + .valign(Align::Center) + .build(), + }) + } + + // Getters + pub fn gobject(&self) -> &MenuButton { + &self.gobject + } +} diff --git a/src/app/browser/window/header/bar/tab.rs b/src/app/browser/window/header/bar/tab.rs new file mode 100644 index 00000000..cd699a89 --- /dev/null +++ b/src/app/browser/window/header/bar/tab.rs @@ -0,0 +1,24 @@ +mod widget; + +use widget::Widget; + +use adw::{TabBar, TabView}; +use std::sync::Arc; + +pub struct Tab { + widget: Arc<Widget>, +} + +impl Tab { + // Construct + pub fn new_arc(view: &TabView) -> Arc<Self> { + Arc::new(Self { + widget: Widget::new_arc(view), + }) + } + + // Getters + pub fn gobject(&self) -> &TabBar { + &self.widget.gobject() + } +} diff --git a/src/app/browser/window/header/bar/tab/widget.rs b/src/app/browser/window/header/bar/tab/widget.rs new file mode 100644 index 00000000..cc024cbd --- /dev/null +++ b/src/app/browser/window/header/bar/tab/widget.rs @@ -0,0 +1,20 @@ +use adw::{TabBar, TabView}; +use std::sync::Arc; + +pub struct Widget { + gobject: TabBar, +} + +impl Widget { + // Construct + pub fn new_arc(view: &TabView) -> Arc<Self> { + Arc::new(Self { + gobject: TabBar::builder().view(&view).build(), + }) + } + + // Getters + pub fn gobject(&self) -> &TabBar { + &self.gobject + } +} diff --git a/src/app/browser/window/header/bar/widget.rs b/src/app/browser/window/header/bar/widget.rs new file mode 100644 index 00000000..e0f099ce --- /dev/null +++ b/src/app/browser/window/header/bar/widget.rs @@ -0,0 +1,34 @@ +use adw::TabBar; +use gtk::{prelude::BoxExt, Box, Button, MenuButton, Orientation, WindowControls}; +use std::sync::Arc; + +pub struct Widget { + gobject: Box, +} + +impl Widget { + // Construct + pub fn new_arc( + control: &WindowControls, + append: &Button, + menu: &MenuButton, + tab: &TabBar, + ) -> Arc<Self> { + let gobject = Box::builder() + .orientation(Orientation::Horizontal) + .spacing(8) + .build(); + + gobject.append(tab); + gobject.append(append); + gobject.append(menu); + gobject.append(control); + + Arc::new(Self { gobject }) + } + + // Getters + pub fn gobject(&self) -> &Box { + &self.gobject + } +} diff --git a/src/app/browser/window/header/title.rs b/src/app/browser/window/header/title.rs deleted file mode 100644 index 8de81da6..00000000 --- a/src/app/browser/window/header/title.rs +++ /dev/null @@ -1,39 +0,0 @@ -use adw::WindowTitle; - -const DEFAULT_TITLE: &str = "Yoda"; // @TODO -const DEFAULT_SUBTITLE: &str = ""; - -pub struct Title { - gobject: WindowTitle, -} - -impl Title { - // Construct - pub fn new() -> Self { - Self { - gobject: WindowTitle::new(DEFAULT_TITLE, DEFAULT_SUBTITLE), - } - } - - // Actions - pub fn update(&self, title: &str, subtitle: &str) { - // Update title - let mut parts = Vec::new(); - - if !title.is_empty() { - parts.push(title); - } - - parts.push(DEFAULT_TITLE); - - self.gobject.set_title(&parts.join(" - ")); - - // Update subtitle - self.gobject.set_subtitle(subtitle); - } - - // Getters - pub fn gobject(&self) -> &WindowTitle { - &self.gobject - } -} diff --git a/src/app/browser/window/header/widget.rs b/src/app/browser/window/header/widget.rs index 4e9d2af5..f9181314 100644 --- a/src/app/browser/window/header/widget.rs +++ b/src/app/browser/window/header/widget.rs @@ -1,23 +1,23 @@ -use adw::{HeaderBar, WindowTitle}; +use adw::ToolbarView; use gtk::Box; +use std::sync::Arc; pub struct Widget { - gobject: HeaderBar, + gobject: ToolbarView, } impl Widget { // Construct - pub fn new(pack_start: &Box, title_widget: Option<&WindowTitle>) -> Self { - let gobject = HeaderBar::builder().build(); + pub fn new_arc(top_bar: &Box) -> Arc<Self> { + let gobject = ToolbarView::builder().build(); - gobject.pack_start(pack_start); - gobject.set_title_widget(title_widget); + gobject.add_top_bar(top_bar); - Self { gobject } + Arc::new(Self { gobject }) } // Getters - pub fn gobject(&self) -> &HeaderBar { + pub fn gobject(&self) -> &ToolbarView { &self.gobject } } diff --git a/src/app/browser/window/tab.rs b/src/app/browser/window/tab.rs index f525a12c..5ba5c261 100644 --- a/src/app/browser/window/tab.rs +++ b/src/app/browser/window/tab.rs @@ -32,14 +32,14 @@ pub struct Tab { impl Tab { // Construct - pub fn new( + pub fn new_arc( // Actions action_tab_page_navigation_base: Arc<SimpleAction>, action_tab_page_navigation_history_back: Arc<SimpleAction>, action_tab_page_navigation_history_forward: Arc<SimpleAction>, action_tab_page_navigation_reload: Arc<SimpleAction>, action_update: Arc<SimpleAction>, - ) -> Self { + ) -> Arc<Self> { // Init empty HashMap index as no tabs appended yet let index = RefCell::new(HashMap::new()); @@ -47,7 +47,7 @@ impl Tab { let widget = Arc::new(Widget::new()); // Return non activated struct - Self { + Arc::new(Self { // Define action links action_tab_page_navigation_base, action_tab_page_navigation_history_back, @@ -58,7 +58,7 @@ impl Tab { index, // GTK widget, - } + }) } // Actions @@ -276,25 +276,6 @@ impl Tab { } // Getters - pub fn page_title(&self) -> Option<GString> { - if let Some(id) = self.widget.current_name() { - if let Some(item) = self.index.borrow().get(&id) { - return item.page_title(); - } - } - None - } - - pub fn page_description(&self) -> Option<GString> { - if let Some(id) = self.widget.current_name() { - // Get page by widget ID - if let Some(item) = self.index.borrow().get(&id) { - return item.page_description(); - } - } - None - } - pub fn gobject(&self) -> &Notebook { self.widget.gobject() } diff --git a/src/app/browser/window/widget.rs b/src/app/browser/window/widget.rs index f6e0bbdf..cf79feb3 100644 --- a/src/app/browser/window/widget.rs +++ b/src/app/browser/window/widget.rs @@ -1,4 +1,4 @@ -use adw::HeaderBar; +use adw::ToolbarView; use gtk::{prelude::BoxExt, Box, Notebook, Orientation}; pub struct Widget { @@ -7,7 +7,7 @@ pub struct Widget { impl Widget { // Construct - pub fn new(header: &HeaderBar, tab: &Notebook) -> Self { + pub fn new(header: &ToolbarView, tab: &Notebook) -> Self { let gobject = Box::builder().orientation(Orientation::Vertical).build(); gobject.append(header); gobject.append(tab);