mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-24 18:14:14 +00:00
init context menu for page tabs
This commit is contained in:
parent
51f543143d
commit
b443d1c58e
@ -52,7 +52,7 @@ impl App {
|
|||||||
let action_page_home = Action::new("win", false, None);
|
let action_page_home = Action::new("win", false, None);
|
||||||
let action_page_history_back = Action::new("win", false, None);
|
let action_page_history_back = Action::new("win", false, None);
|
||||||
let action_page_history_forward = Action::new("win", false, None);
|
let action_page_history_forward = Action::new("win", false, None);
|
||||||
let action_page_reload = Action::new("win", true, None);
|
let action_page_reload = Action::new_stateful("win", true, None, &0.to_variant()); // @TODO
|
||||||
let action_page_pin = Action::new("win", true, None);
|
let action_page_pin = Action::new("win", true, None);
|
||||||
|
|
||||||
// Init GTK
|
// Init GTK
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::SimpleAction,
|
gio::SimpleAction,
|
||||||
glib::{gformat, uuid_string_random, GString, VariantTy},
|
glib::{gformat, uuid_string_random, GString, Variant, VariantTy},
|
||||||
prelude::ActionExt,
|
prelude::ActionExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,6 +27,23 @@ impl Action {
|
|||||||
Self { group, simple }
|
Self { group, simple }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_stateful(
|
||||||
|
group: &str,
|
||||||
|
is_enabled: bool,
|
||||||
|
parameter_type: Option<&VariantTy>,
|
||||||
|
state: &Variant,
|
||||||
|
) -> Self {
|
||||||
|
// Create random action name as no static values should be in use
|
||||||
|
let simple = SimpleAction::new_stateful(&uuid_string_random(), parameter_type, state);
|
||||||
|
simple.set_enabled(is_enabled);
|
||||||
|
|
||||||
|
// Assign action to the group
|
||||||
|
let group = GString::from(group);
|
||||||
|
|
||||||
|
// Return new Action
|
||||||
|
Self { group, simple }
|
||||||
|
}
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
pub fn detailed_name(&self) -> GString {
|
pub fn detailed_name(&self) -> GString {
|
||||||
gformat!("{}.{}", self.group, self.simple.name()) // @TODO find the way to ident parent group
|
gformat!("{}.{}", self.group, self.simple.name()) // @TODO find the way to ident parent group
|
||||||
|
@ -11,7 +11,7 @@ use window::Window;
|
|||||||
use adw::ApplicationWindow;
|
use adw::ApplicationWindow;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::{Cancellable, File, SimpleAction},
|
gio::{Cancellable, File, SimpleAction},
|
||||||
prelude::GtkWindowExt,
|
prelude::{ActionExt, GtkWindowExt},
|
||||||
FileLauncher,
|
FileLauncher,
|
||||||
};
|
};
|
||||||
use sqlite::Transaction;
|
use sqlite::Transaction;
|
||||||
@ -174,8 +174,14 @@ impl Browser {
|
|||||||
|
|
||||||
action_page_reload.connect_activate({
|
action_page_reload.connect_activate({
|
||||||
let window = window.clone();
|
let window = window.clone();
|
||||||
move |_, _| {
|
move |this, _| {
|
||||||
window.tab_page_navigation_reload();
|
let page_position = this
|
||||||
|
.state()
|
||||||
|
.expect("Page position required for reload action")
|
||||||
|
.get::<i32>()
|
||||||
|
.expect("Parameter does not match `i32`");
|
||||||
|
|
||||||
|
window.tab_page_navigation_reload(page_position);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ impl Window {
|
|||||||
self.tab.page_navigation_history_forward();
|
self.tab.page_navigation_history_forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tab_page_navigation_reload(&self) {
|
pub fn tab_page_navigation_reload(&self, page_position: i32) {
|
||||||
self.tab.page_navigation_reload();
|
self.tab.page_navigation_reload(page_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tab_close(&self) {
|
pub fn tab_close(&self) {
|
||||||
|
@ -8,9 +8,9 @@ use widget::Widget;
|
|||||||
|
|
||||||
use adw::TabView;
|
use adw::TabView;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::SimpleAction,
|
gio::{Menu, SimpleAction},
|
||||||
glib::{uuid_string_random, GString, Propagation},
|
glib::{gformat, uuid_string_random, GString, Propagation},
|
||||||
prelude::StaticVariantType,
|
prelude::{ActionExt, StaticVariantType, ToVariant},
|
||||||
};
|
};
|
||||||
use sqlite::Transaction;
|
use sqlite::Transaction;
|
||||||
use std::{cell::RefCell, collections::HashMap, sync::Arc};
|
use std::{cell::RefCell, collections::HashMap, sync::Arc};
|
||||||
@ -48,10 +48,51 @@ impl Tab {
|
|||||||
// Init empty HashMap index as no tabs appended yet
|
// Init empty HashMap index as no tabs appended yet
|
||||||
let index = Arc::new(RefCell::new(HashMap::new()));
|
let index = Arc::new(RefCell::new(HashMap::new()));
|
||||||
|
|
||||||
|
// @TODO move to mod
|
||||||
|
let menu = Menu::new();
|
||||||
|
|
||||||
|
menu.append(
|
||||||
|
Some("Reload"),
|
||||||
|
Some(&gformat!("win.{}", action_page_reload.name())),
|
||||||
|
); // @TODO resolve namespace outside
|
||||||
|
|
||||||
// Init widget
|
// Init widget
|
||||||
let widget = Arc::new(Widget::new(action_tab_open.clone()));
|
let widget = Arc::new(Widget::new(&menu));
|
||||||
|
|
||||||
// Init events
|
// Init events
|
||||||
|
|
||||||
|
// Setup actions for context menu
|
||||||
|
widget.gobject().connect_setup_menu({
|
||||||
|
let action_page_reload = action_page_reload.clone();
|
||||||
|
move |tab_view, tab_page| {
|
||||||
|
// Enable actions by default
|
||||||
|
action_page_reload.set_enabled(true);
|
||||||
|
|
||||||
|
match tab_page {
|
||||||
|
// Menu opened:
|
||||||
|
// setup actions to operate with page selected only
|
||||||
|
Some(this) => {
|
||||||
|
let position = tab_view.page_position(this).to_variant();
|
||||||
|
|
||||||
|
action_page_reload.change_state(&position);
|
||||||
|
}
|
||||||
|
// Menu closed:
|
||||||
|
// return actions to default values
|
||||||
|
None => match tab_view.selected_page() {
|
||||||
|
Some(selected) => {
|
||||||
|
// Get position of page selected
|
||||||
|
let position = tab_view.page_position(&selected).to_variant();
|
||||||
|
|
||||||
|
// Update related actions
|
||||||
|
action_page_reload.change_state(&position);
|
||||||
|
}
|
||||||
|
// No selected page found, disable related actions
|
||||||
|
None => action_page_reload.set_enabled(false),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
widget.gobject().connect_close_page({
|
widget.gobject().connect_close_page({
|
||||||
let index = index.clone();
|
let index = index.clone();
|
||||||
move |_, item| {
|
move |_, item| {
|
||||||
@ -201,8 +242,8 @@ impl Tab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_navigation_reload(&self) {
|
pub fn page_navigation_reload(&self, page_position: i32) {
|
||||||
if let Some(id) = self.widget.current_page_keyword() {
|
if let Some(id) = self.widget.gobject().nth_page(page_position).keyword() {
|
||||||
if let Some(item) = self.index.borrow().get(&id) {
|
if let Some(item) = self.index.borrow().get(&id) {
|
||||||
item.page_navigation_reload();
|
item.page_navigation_reload();
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,37 @@
|
|||||||
use adw::TabView;
|
use adw::TabView;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::{Icon, SimpleAction, SimpleActionGroup},
|
gio::{Icon, MenuModel},
|
||||||
glib::{uuid_string_random, GString},
|
glib::GString,
|
||||||
prelude::{ActionMapExt, WidgetExt},
|
prelude::IsA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Currently used as the indicator for pinned tabs
|
||||||
|
const DEFAULT_TAB_ICON: &str = "view-pin-symbolic";
|
||||||
|
|
||||||
|
/// Wrapper for [TabView](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.TabView.html) GObject
|
||||||
pub struct Widget {
|
pub struct Widget {
|
||||||
gobject: TabView,
|
gobject: TabView,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget {
|
impl Widget {
|
||||||
// Construct
|
// Construct
|
||||||
pub fn new(action_page_new: SimpleAction) -> Self {
|
pub fn new(menu_model: &impl IsA<MenuModel>) -> Self {
|
||||||
// Init additional action group
|
|
||||||
let action_group = SimpleActionGroup::new();
|
|
||||||
action_group.add_action(&action_page_new);
|
|
||||||
|
|
||||||
// Init gobject
|
// Init gobject
|
||||||
let gobject = TabView::new();
|
let gobject = TabView::builder().menu_model(menu_model).build();
|
||||||
|
|
||||||
// Change default icon visible for tabs pinned
|
// Change default icon (if available in the system icon set)
|
||||||
if let Ok(default_icon) = Icon::for_string("view-pin-symbolic") {
|
// * visible for pinned tabs only
|
||||||
|
// * @TODO not default GTK behavior, make this feature optional
|
||||||
|
if let Ok(default_icon) = Icon::for_string(DEFAULT_TAB_ICON) {
|
||||||
gobject.set_default_icon(&default_icon);
|
gobject.set_default_icon(&default_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new group for actions
|
// Done
|
||||||
gobject.insert_action_group(&uuid_string_random(), Some(&action_group));
|
|
||||||
|
|
||||||
Self { gobject }
|
Self { gobject }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
if let Some(selected_page) = self.gobject.selected_page() {
|
if let Some(selected_page) = self.gobject.selected_page() {
|
||||||
self.gobject.close_page(&selected_page);
|
self.gobject.close_page(&selected_page);
|
||||||
@ -46,6 +47,7 @@ impl Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
|
||||||
pub fn current_page_keyword(&self) -> Option<GString> {
|
pub fn current_page_keyword(&self) -> Option<GString> {
|
||||||
let page = self.gobject.selected_page()?;
|
let page = self.gobject.selected_page()?;
|
||||||
let id = page.keyword()?;
|
let id = page.keyword()?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user