add new tab item action group, delegate history handle to action implementation

This commit is contained in:
yggverse 2025-01-25 17:28:05 +02:00
parent 5145a53bfa
commit 913030a955
29 changed files with 409 additions and 232 deletions

View file

@ -1,107 +1,26 @@
mod back;
mod forward;
mod widget;
pub mod back;
pub mod forward;
use back::Back;
use forward::Forward;
use widget::Widget;
pub use back::Back;
pub use forward::Forward;
use super::WindowAction;
use gtk::{glib::GString, Button};
use std::{cell::RefCell, rc::Rc};
use gtk::{prelude::BoxExt, Box, Button, Orientation};
struct Memory {
request: GString,
// time: SystemTime,
pub trait History {
fn history(back_action_name: &str, forward_action_name: &str) -> Self;
}
pub struct History {
// Extras
memory: RefCell<Vec<Memory>>,
index: RefCell<Option<usize>>,
// GTK
pub widget: Rc<Widget>,
}
impl History for Box {
fn history(back_action_name: &str, forward_action_name: &str) -> Self {
let g_box = Box::builder()
.orientation(Orientation::Horizontal)
.css_classes([
"linked", // merge childs
])
.build();
impl History {
// Constructors
/// Build new `Self`
pub fn build(action: &Rc<WindowAction>) -> Self {
// Init widget
let widget = Rc::new(Widget::build(
&Button::back(action),
&Button::forward(action),
));
// Init memory
let memory = RefCell::new(Vec::new());
// Init index
let index = RefCell::new(None);
Self {
memory,
index,
widget,
}
}
// Actions
pub fn add(&self, request: GString, follow_to_index: bool) {
// Append new Memory record
self.memory.borrow_mut().push(Memory {
request: request.clone(),
//time: SystemTime::now(),
});
if follow_to_index {
// Even push action make positive len value, make sure twice
if !self.memory.borrow().is_empty() {
// Navigate to the last record appended
self.index.replace(Some(self.memory.borrow().len() - 1));
} else {
self.index.replace(None);
}
}
}
pub fn back(&self, follow_to_index: bool) -> Option<GString> {
let index = *self.index.borrow();
if let Some(usize) = index {
// Make sure value positive to prevent panic
if usize > 0 {
if let Some(memory) = self.memory.borrow().get(usize - 1) {
if follow_to_index {
self.index.replace(Some(usize - 1));
}
return Some(memory.request.clone());
}
}
}
None
}
pub fn current(&self) -> Option<GString> {
let index = *self.index.borrow();
if let Some(usize) = index {
if let Some(memory) = self.memory.borrow().get(usize) {
return Some(memory.request.clone());
}
}
None
}
pub fn forward(&self, follow_to_index: bool) -> Option<GString> {
let index = *self.index.borrow();
if let Some(usize) = index {
if let Some(memory) = self.memory.borrow().get(usize + 1) {
if follow_to_index {
self.index.replace(Some(usize + 1));
}
return Some(memory.request.clone());
}
}
None
g_box.append(&Button::back(back_action_name));
g_box.append(&Button::forward(forward_action_name));
g_box
}
}

View file

@ -1,19 +1,13 @@
use super::WindowAction;
use gtk::{prelude::ActionExt, Button};
use std::rc::Rc;
use gtk::Button;
pub trait Back {
fn back(action: &Rc<WindowAction>) -> Self;
fn back(action_name: &str) -> Self;
}
impl Back for Button {
fn back(action: &Rc<WindowAction>) -> Self {
fn back(action_name: &str) -> Self {
Button::builder()
.action_name(format!(
"{}.{}",
action.id,
action.history_back.simple_action.name()
)) // @TODO
.action_name(action_name)
.icon_name("go-previous-symbolic")
.tooltip_text("Back")
.build()

View file

@ -1,19 +1,13 @@
use super::WindowAction;
use gtk::{prelude::ActionExt, Button};
use std::rc::Rc;
use gtk::Button;
pub trait Forward {
fn forward(action: &Rc<WindowAction>) -> Self;
fn forward(action_name: &str) -> Self;
}
impl Forward for Button {
fn forward(action: &Rc<WindowAction>) -> Self {
fn forward(action_name: &str) -> Self {
Button::builder()
.action_name(format!(
"{}.{}",
action.id,
action.history_back.simple_action.name()
)) // @TODO
.action_name(action_name)
.icon_name("go-next-symbolic")
.tooltip_text("Forward")
.build()

View file

@ -1,27 +0,0 @@
use gtk::{
prelude::{BoxExt, IsA},
Box, Orientation,
};
pub struct Widget {
pub g_box: Box,
}
impl Widget {
// Constructors
/// Build new `Self`
pub fn build(back: &impl IsA<gtk::Widget>, forward: &impl IsA<gtk::Widget>) -> Self {
let g_box = Box::builder()
.orientation(Orientation::Horizontal)
.css_classes([
"linked", // merge childs
])
.build();
g_box.append(back);
g_box.append(forward);
Self { g_box }
}
}

View file

@ -4,7 +4,7 @@ mod widget;
use widget::Widget;
use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction};
use crate::app::browser::{window::tab::item::Action as ItemAction, Action as BrowserAction};
use gtk::{
glib::{gformat, GString, Uri, UriFlags},
prelude::EditableExt,
@ -21,9 +21,9 @@ impl Request {
// Constructors
/// Build new `Self`
pub fn build((browser_action, tab_action): (&Rc<BrowserAction>, &Rc<TabAction>)) -> Self {
pub fn build((browser_action, item_action): (&Rc<BrowserAction>, &Rc<ItemAction>)) -> Self {
Self {
widget: Rc::new(Widget::build((browser_action, tab_action))),
widget: Rc::new(Widget::build((browser_action, item_action))),
}
}

View file

@ -3,7 +3,7 @@ mod primary_icon;
use primary_icon::PrimaryIcon;
use super::{BrowserAction, TabAction};
use super::{BrowserAction, ItemAction};
use gtk::{
glib::{timeout_add_local, ControlFlow, SourceId},
prelude::{EditableExt, EntryExt, WidgetExt},
@ -36,7 +36,7 @@ impl Widget {
// Constructors
/// Build new `Self`
pub fn build((browser_action, tab_action): (&Rc<BrowserAction>, &Rc<TabAction>)) -> Self {
pub fn build((browser_action, item_action): (&Rc<BrowserAction>, &Rc<ItemAction>)) -> Self {
// Init animated progress bar state
let progress = Rc::new(Progress {
fraction: RefCell::new(0.0),
@ -52,10 +52,10 @@ impl Widget {
// Connect events
entry.connect_icon_release({
let tab_action = tab_action.clone();
let item_action = item_action.clone();
move |this, position| match position {
EntryIconPosition::Primary => tab_action.ident.activate(), // @TODO PrimaryIcon impl
EntryIconPosition::Secondary => tab_action.load.activate(Some(&this.text()), true),
EntryIconPosition::Primary => item_action.ident.activate(), // @TODO PrimaryIcon impl
EntryIconPosition::Secondary => item_action.load.activate(Some(&this.text()), true),
_ => todo!(), // unexpected
}
});
@ -77,9 +77,9 @@ impl Widget {
});
entry.connect_activate({
let tab_action = tab_action.clone();
let item_action = item_action.clone();
move |entry| {
tab_action.load.activate(Some(&entry.text()), true);
item_action.load.activate(Some(&entry.text()), true);
}
});