mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-02-09 18:04:14 +00:00
add new tab item action group, delegate history handle to action implementation
This commit is contained in:
parent
5145a53bfa
commit
913030a955
@ -37,17 +37,22 @@ impl Browser {
|
|||||||
let widget = Rc::new(Widget::new(
|
let widget = Rc::new(Widget::new(
|
||||||
&window.widget.g_box,
|
&window.widget.g_box,
|
||||||
&[
|
&[
|
||||||
// Connect action groups (to apply accels)
|
// action groups
|
||||||
(
|
(
|
||||||
// Browser
|
// browser
|
||||||
&action.id,
|
&action.id,
|
||||||
action.simple_action_group.clone(),
|
action.simple_action_group.clone(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
// Window
|
// window
|
||||||
&window.action.id,
|
&window.action.id,
|
||||||
window.action.simple_action_group.clone(),
|
window.action.simple_action_group.clone(),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
// tab
|
||||||
|
&window.tab.action.id,
|
||||||
|
window.tab.action.simple_action_group.clone(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
mod action;
|
||||||
mod database;
|
mod database;
|
||||||
mod error;
|
mod error;
|
||||||
mod item;
|
mod item;
|
||||||
mod menu;
|
mod menu;
|
||||||
mod widget;
|
mod widget;
|
||||||
|
|
||||||
|
use action::Action;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
pub use item::Item;
|
pub use item::Item;
|
||||||
use menu::Menu;
|
use menu::Menu;
|
||||||
@ -27,6 +29,7 @@ pub struct Tab {
|
|||||||
window_action: Rc<WindowAction>,
|
window_action: Rc<WindowAction>,
|
||||||
profile: Rc<Profile>,
|
profile: Rc<Profile>,
|
||||||
index: Rc<RefCell<HashMap<Rc<GString>, Rc<Item>>>>,
|
index: Rc<RefCell<HashMap<Rc<GString>, Rc<Item>>>>,
|
||||||
|
pub action: Rc<Action>,
|
||||||
pub widget: Rc<Widget>,
|
pub widget: Rc<Widget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +41,8 @@ impl Tab {
|
|||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
|
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let action = Rc::new(Action::new());
|
||||||
|
|
||||||
// Init empty HashMap index
|
// Init empty HashMap index
|
||||||
let index: Rc<RefCell<HashMap<Rc<GString>, Rc<Item>>>> =
|
let index: Rc<RefCell<HashMap<Rc<GString>, Rc<Item>>>> =
|
||||||
Rc::new(RefCell::new(HashMap::new()));
|
Rc::new(RefCell::new(HashMap::new()));
|
||||||
@ -142,6 +147,7 @@ impl Tab {
|
|||||||
window_action: window_action.clone(),
|
window_action: window_action.clone(),
|
||||||
index,
|
index,
|
||||||
widget,
|
widget,
|
||||||
|
action,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +166,7 @@ impl Tab {
|
|||||||
&self.widget.tab_view,
|
&self.widget.tab_view,
|
||||||
&self.profile,
|
&self.profile,
|
||||||
// Actions
|
// Actions
|
||||||
(&self.browser_action, &self.window_action),
|
(&self.browser_action, &self.window_action, &self.action),
|
||||||
// Options
|
// Options
|
||||||
(
|
(
|
||||||
position,
|
position,
|
||||||
@ -260,19 +266,13 @@ impl Tab {
|
|||||||
|
|
||||||
pub fn page_history_back(&self, page_position: Option<i32>) {
|
pub fn page_history_back(&self, page_position: Option<i32>) {
|
||||||
if let Some(item) = self.item(page_position) {
|
if let Some(item) = self.item(page_position) {
|
||||||
if let Some(back) = item.page.navigation.history.back(true) {
|
item.action.history.back(true);
|
||||||
item.page.navigation.request.widget.entry.set_text(&back);
|
|
||||||
item.client.handle(&back, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_history_forward(&self, page_position: Option<i32>) {
|
pub fn page_history_forward(&self, page_position: Option<i32>) {
|
||||||
if let Some(item) = self.item(page_position) {
|
if let Some(item) = self.item(page_position) {
|
||||||
if let Some(forward) = item.page.navigation.history.forward(true) {
|
item.action.history.forward(true);
|
||||||
item.page.navigation.request.widget.entry.set_text(&forward);
|
|
||||||
item.client.handle(&forward, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ impl Tab {
|
|||||||
transaction,
|
transaction,
|
||||||
record.id,
|
record.id,
|
||||||
&self.profile,
|
&self.profile,
|
||||||
(&self.browser_action, &self.window_action),
|
(&self.browser_action, &self.window_action, &self.action),
|
||||||
) {
|
) {
|
||||||
Ok(items) => {
|
Ok(items) => {
|
||||||
for item in items {
|
for item in items {
|
||||||
|
25
src/app/browser/window/tab/action.rs
Normal file
25
src/app/browser/window/tab/action.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use gtk::{
|
||||||
|
gio::SimpleActionGroup,
|
||||||
|
glib::{uuid_string_random, GString},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) wrapper for `Tab` actions
|
||||||
|
pub struct Action {
|
||||||
|
pub id: GString,
|
||||||
|
pub simple_action_group: SimpleActionGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Action {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Action {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
id: uuid_string_random(),
|
||||||
|
simple_action_group: SimpleActionGroup::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ use adw::TabView;
|
|||||||
use client::Client;
|
use client::Client;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
glib::{uuid_string_random, GString},
|
glib::{uuid_string_random, GString},
|
||||||
prelude::{Cast, EditableExt},
|
prelude::{ActionExt, ActionMapExt, Cast, EditableExt},
|
||||||
};
|
};
|
||||||
use page::Page;
|
use page::Page;
|
||||||
use sqlite::Transaction;
|
use sqlite::Transaction;
|
||||||
@ -31,6 +31,7 @@ pub struct Item {
|
|||||||
// Components
|
// Components
|
||||||
pub page: Rc<Page>,
|
pub page: Rc<Page>,
|
||||||
pub widget: Rc<Widget>,
|
pub widget: Rc<Widget>,
|
||||||
|
pub action: Rc<Action>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
@ -40,7 +41,11 @@ impl Item {
|
|||||||
pub fn build(
|
pub fn build(
|
||||||
tab_view: &TabView,
|
tab_view: &TabView,
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
|
(browser_action, window_action, tab_action): (
|
||||||
|
&Rc<BrowserAction>,
|
||||||
|
&Rc<WindowAction>,
|
||||||
|
&Rc<super::Action>,
|
||||||
|
),
|
||||||
(position, request, is_pinned, is_selected, is_attention, is_load): (
|
(position, request, is_pinned, is_selected, is_attention, is_load): (
|
||||||
Position,
|
Position,
|
||||||
Option<String>,
|
Option<String>,
|
||||||
@ -57,10 +62,22 @@ impl Item {
|
|||||||
|
|
||||||
let action = Rc::new(Action::new());
|
let action = Rc::new(Action::new());
|
||||||
|
|
||||||
|
tab_action
|
||||||
|
.simple_action_group
|
||||||
|
.add_action(&action.history.back);
|
||||||
|
|
||||||
|
tab_action
|
||||||
|
.simple_action_group
|
||||||
|
.add_action(&action.history.forward);
|
||||||
|
|
||||||
let page = Rc::new(Page::build(
|
let page = Rc::new(Page::build(
|
||||||
&id,
|
&id,
|
||||||
profile,
|
profile,
|
||||||
(browser_action, window_action, &action),
|
(browser_action, window_action, &action),
|
||||||
|
(
|
||||||
|
&format!("{}.{}", &tab_action.id, action.history.back.name()),
|
||||||
|
&format!("{}.{}", &tab_action.id, action.history.forward.name()),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
let widget = Rc::new(Widget::build(
|
let widget = Rc::new(Widget::build(
|
||||||
@ -128,6 +145,7 @@ impl Item {
|
|||||||
client,
|
client,
|
||||||
page,
|
page,
|
||||||
widget,
|
widget,
|
||||||
|
action,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +187,11 @@ impl Item {
|
|||||||
app_browser_window_tab_id: i64,
|
app_browser_window_tab_id: i64,
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
// Actions
|
// Actions
|
||||||
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
|
(browser_action, window_action, item_action): (
|
||||||
|
&Rc<BrowserAction>,
|
||||||
|
&Rc<WindowAction>,
|
||||||
|
&Rc<super::Action>,
|
||||||
|
),
|
||||||
) -> Result<Vec<Rc<Item>>, String> {
|
) -> Result<Vec<Rc<Item>>, String> {
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
|
|
||||||
@ -181,7 +203,7 @@ impl Item {
|
|||||||
tab_view,
|
tab_view,
|
||||||
profile,
|
profile,
|
||||||
// Actions
|
// Actions
|
||||||
(browser_action, window_action),
|
(browser_action, window_action, item_action),
|
||||||
// Options tuple
|
// Options tuple
|
||||||
(
|
(
|
||||||
Position::End,
|
Position::End,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
mod history;
|
||||||
mod ident;
|
mod ident;
|
||||||
mod load;
|
mod load;
|
||||||
|
|
||||||
|
use history::History;
|
||||||
use ident::Ident;
|
use ident::Ident;
|
||||||
use load::Load;
|
use load::Load;
|
||||||
|
|
||||||
@ -8,6 +10,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
/// [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) wrapper for `Browser` actions
|
/// [SimpleActionGroup](https://docs.gtk.org/gio/class.SimpleActionGroup.html) wrapper for `Browser` actions
|
||||||
pub struct Action {
|
pub struct Action {
|
||||||
|
pub history: Rc<History>,
|
||||||
pub ident: Rc<Ident>,
|
pub ident: Rc<Ident>,
|
||||||
pub load: Rc<Load>,
|
pub load: Rc<Load>,
|
||||||
}
|
}
|
||||||
@ -23,9 +26,18 @@ impl Action {
|
|||||||
|
|
||||||
/// Create new `Self`
|
/// Create new `Self`
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
let ident = Rc::new(Ident::new());
|
||||||
|
let load = Rc::new(Load::new());
|
||||||
|
|
||||||
|
let history = Rc::new(History::build({
|
||||||
|
let load = load.clone();
|
||||||
|
move |request| load.activate(Some(&request), false)
|
||||||
|
}));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ident: Rc::new(Ident::new()),
|
history,
|
||||||
load: Rc::new(Load::new()),
|
ident,
|
||||||
|
load,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
79
src/app/browser/window/tab/item/action/history.rs
Normal file
79
src/app/browser/window/tab/item/action/history.rs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
mod back;
|
||||||
|
mod forward;
|
||||||
|
mod memory;
|
||||||
|
|
||||||
|
use back::Back;
|
||||||
|
use forward::Forward;
|
||||||
|
use gtk::{gio::SimpleAction, glib::GString};
|
||||||
|
use memory::Memory;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub struct History {
|
||||||
|
memory: Rc<Memory>,
|
||||||
|
pub back: SimpleAction,
|
||||||
|
pub forward: SimpleAction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl History {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
/// Build new activated `Self`
|
||||||
|
pub fn build(callback: impl Fn(GString) + 'static) -> Self {
|
||||||
|
// Init childs
|
||||||
|
let memory = Rc::new(Memory::new());
|
||||||
|
let back = SimpleAction::back();
|
||||||
|
let forward = SimpleAction::forward();
|
||||||
|
|
||||||
|
// Init events
|
||||||
|
let callback = Rc::new(callback);
|
||||||
|
|
||||||
|
back.connect_activate({
|
||||||
|
let callback = callback.clone();
|
||||||
|
let forward = forward.clone();
|
||||||
|
let memory = memory.clone();
|
||||||
|
move |this, _| {
|
||||||
|
if let Some(request) = memory.back(true) {
|
||||||
|
callback(request)
|
||||||
|
}
|
||||||
|
forward.set_enabled(memory.next(false).is_some());
|
||||||
|
this.set_enabled(memory.back(false).is_some());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
forward.connect_activate({
|
||||||
|
let back = back.clone();
|
||||||
|
let callback = callback.clone();
|
||||||
|
let memory = memory.clone();
|
||||||
|
move |this, _| {
|
||||||
|
if let Some(request) = memory.next(true) {
|
||||||
|
callback(request)
|
||||||
|
}
|
||||||
|
back.set_enabled(memory.back(false).is_some());
|
||||||
|
this.set_enabled(memory.next(false).is_some());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Done
|
||||||
|
Self {
|
||||||
|
memory,
|
||||||
|
back,
|
||||||
|
forward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
pub fn add(&self, request: GString, follow_to_index: bool) {
|
||||||
|
self.memory.add(request, follow_to_index);
|
||||||
|
self.back.set_enabled(self.back(false).is_some());
|
||||||
|
self.forward.set_enabled(self.forward(false).is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn back(&self, follow_to_index: bool) -> Option<GString> {
|
||||||
|
self.memory.back(follow_to_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn forward(&self, follow_to_index: bool) -> Option<GString> {
|
||||||
|
self.memory.next(follow_to_index)
|
||||||
|
}
|
||||||
|
}
|
13
src/app/browser/window/tab/item/action/history/back.rs
Normal file
13
src/app/browser/window/tab/item/action/history/back.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use gtk::{gio::SimpleAction, glib::uuid_string_random};
|
||||||
|
|
||||||
|
pub trait Back {
|
||||||
|
fn back() -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Back for SimpleAction {
|
||||||
|
fn back() -> Self {
|
||||||
|
let back = SimpleAction::new(&uuid_string_random(), None);
|
||||||
|
back.set_enabled(false);
|
||||||
|
back
|
||||||
|
}
|
||||||
|
}
|
13
src/app/browser/window/tab/item/action/history/forward.rs
Normal file
13
src/app/browser/window/tab/item/action/history/forward.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use gtk::{gio::SimpleAction, glib::uuid_string_random};
|
||||||
|
|
||||||
|
pub trait Forward {
|
||||||
|
fn forward() -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Forward for SimpleAction {
|
||||||
|
fn forward() -> Self {
|
||||||
|
let forward = SimpleAction::new(&uuid_string_random(), None);
|
||||||
|
forward.set_enabled(false);
|
||||||
|
forward
|
||||||
|
}
|
||||||
|
}
|
68
src/app/browser/window/tab/item/action/history/memory.rs
Normal file
68
src/app/browser/window/tab/item/action/history/memory.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
mod cursor;
|
||||||
|
|
||||||
|
use cursor::Cursor;
|
||||||
|
use gtk::glib::GString;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
pub struct Memory {
|
||||||
|
cursor: RefCell<Cursor>,
|
||||||
|
index: RefCell<Vec<GString>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Memory {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
cursor: RefCell::new(Cursor::new()),
|
||||||
|
index: RefCell::new(Vec::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
pub fn add(&self, value: GString, follow_to_index: bool) {
|
||||||
|
let mut index = self.index.borrow_mut();
|
||||||
|
|
||||||
|
match index.last() {
|
||||||
|
Some(last) => {
|
||||||
|
if *last != value {
|
||||||
|
index.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => index.push(value),
|
||||||
|
}
|
||||||
|
|
||||||
|
if follow_to_index {
|
||||||
|
self.cursor.borrow_mut().go_last(index.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn back(&self, follow_to_index: bool) -> Option<GString> {
|
||||||
|
let index = self.index.borrow();
|
||||||
|
let len = index.len();
|
||||||
|
|
||||||
|
match if follow_to_index {
|
||||||
|
self.cursor.borrow_mut().go_back(len)
|
||||||
|
} else {
|
||||||
|
self.cursor.borrow().back(len)
|
||||||
|
} {
|
||||||
|
Some(i) => index.get(i).cloned(),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(&self, follow_to_index: bool) -> Option<GString> {
|
||||||
|
let index = self.index.borrow();
|
||||||
|
let len = index.len();
|
||||||
|
|
||||||
|
match if follow_to_index {
|
||||||
|
self.cursor.borrow_mut().go_next(len)
|
||||||
|
} else {
|
||||||
|
self.cursor.borrow().next(len)
|
||||||
|
} {
|
||||||
|
Some(i) => index.get(i).cloned(),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
pub struct Cursor(Option<usize>);
|
||||||
|
|
||||||
|
impl Default for Cursor {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cursor {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
pub fn go_last(&mut self, len: usize) -> Option<usize> {
|
||||||
|
self.0 = len2i(len);
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn go_next(&mut self, len: usize) -> Option<usize> {
|
||||||
|
self.0 = self.next(len);
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn go_back(&mut self, len: usize) -> Option<usize> {
|
||||||
|
self.0 = self.back(len);
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
pub fn next(&self, len: usize) -> Option<usize> {
|
||||||
|
let i = len2i(len)?;
|
||||||
|
let n = self.0.unwrap_or_default();
|
||||||
|
|
||||||
|
if n < i {
|
||||||
|
Some(n + 1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn back(&self, len: usize) -> Option<usize> {
|
||||||
|
len2i(len)?;
|
||||||
|
let n = self.0.unwrap_or_default();
|
||||||
|
|
||||||
|
if n > 0 {
|
||||||
|
Some(n - 1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tools
|
||||||
|
|
||||||
|
fn len2i(len: usize) -> Option<usize> {
|
||||||
|
if len > 0 {
|
||||||
|
Some(len - 1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
@ -105,7 +105,7 @@ impl Client {
|
|||||||
// begin redirection to new address suggested
|
// begin redirection to new address suggested
|
||||||
Err(uri) => subject
|
Err(uri) => subject
|
||||||
.page
|
.page
|
||||||
.tab_action
|
.item_action
|
||||||
.load
|
.load
|
||||||
.activate(Some(&uri.to_string()), false),
|
.activate(Some(&uri.to_string()), false),
|
||||||
}
|
}
|
||||||
@ -215,10 +215,5 @@ fn snap_history(subject: &Rc<Subject>, uri: Option<&Uri>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add new record into the page navigation history
|
// Add new record into the page navigation history
|
||||||
if match subject.page.navigation.history.current() {
|
subject.page.item_action.history.add(request, true)
|
||||||
Some(current) => current != request, // apply additional filters
|
|
||||||
None => true,
|
|
||||||
} {
|
|
||||||
subject.page.navigation.history.add(request, true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -185,14 +185,14 @@ fn handle(
|
|||||||
};
|
};
|
||||||
if matches!(response.meta.status, Status::SensitiveInput) {
|
if matches!(response.meta.status, Status::SensitiveInput) {
|
||||||
subject.page.input.set_new_sensitive(
|
subject.page.input.set_new_sensitive(
|
||||||
subject.page.tab_action.clone(),
|
subject.page.item_action.clone(),
|
||||||
uri,
|
uri,
|
||||||
Some(&title),
|
Some(&title),
|
||||||
Some(1024),
|
Some(1024),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
subject.page.input.set_new_response(
|
subject.page.input.set_new_response(
|
||||||
subject.page.tab_action.clone(),
|
subject.page.item_action.clone(),
|
||||||
uri,
|
uri,
|
||||||
Some(&title),
|
Some(&title),
|
||||||
Some(1024),
|
Some(1024),
|
||||||
@ -369,7 +369,7 @@ fn handle(
|
|||||||
mime => {
|
mime => {
|
||||||
let status = subject.page
|
let status = subject.page
|
||||||
.content
|
.content
|
||||||
.to_status_mime(mime, Some((&subject.page.tab_action, &uri)));
|
.to_status_mime(mime, Some((&subject.page.item_action, &uri)));
|
||||||
status.set_description(Some(&format!("Content type `{mime}` yet not supported")));
|
status.set_description(Some(&format!("Content type `{mime}` yet not supported")));
|
||||||
subject.page.navigation.request.widget.entry.set_progress_fraction(0.0);
|
subject.page.navigation.request.widget.entry.set_progress_fraction(0.0);
|
||||||
subject.tab_page.set_loading(false);
|
subject.tab_page.set_loading(false);
|
||||||
@ -443,7 +443,7 @@ fn handle(
|
|||||||
.set_text(&uri.to_string());
|
.set_text(&uri.to_string());
|
||||||
}
|
}
|
||||||
redirects.replace(total);
|
redirects.replace(total);
|
||||||
subject.page.tab_action.load.activate(Some(&target.to_string()), false);
|
subject.page.item_action.load.activate(Some(&target.to_string()), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -13,7 +13,7 @@ use navigation::Navigation;
|
|||||||
use search::Search;
|
use search::Search;
|
||||||
use widget::Widget;
|
use widget::Widget;
|
||||||
|
|
||||||
use super::{Action as TabAction, BrowserAction, Profile, WindowAction};
|
use super::{Action as ItemAction, BrowserAction, Profile, WindowAction};
|
||||||
|
|
||||||
use gtk::{glib::GString, prelude::EditableExt};
|
use gtk::{glib::GString, prelude::EditableExt};
|
||||||
use sqlite::Transaction;
|
use sqlite::Transaction;
|
||||||
@ -24,7 +24,7 @@ pub struct Page {
|
|||||||
pub profile: Rc<Profile>,
|
pub profile: Rc<Profile>,
|
||||||
// Actions
|
// Actions
|
||||||
pub browser_action: Rc<BrowserAction>,
|
pub browser_action: Rc<BrowserAction>,
|
||||||
pub tab_action: Rc<TabAction>,
|
pub item_action: Rc<ItemAction>,
|
||||||
pub window_action: Rc<WindowAction>,
|
pub window_action: Rc<WindowAction>,
|
||||||
// Components
|
// Components
|
||||||
pub content: Rc<Content>,
|
pub content: Rc<Content>,
|
||||||
@ -40,20 +40,22 @@ impl Page {
|
|||||||
pub fn build(
|
pub fn build(
|
||||||
id: &Rc<GString>,
|
id: &Rc<GString>,
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
(browser_action, window_action, tab_action): (
|
(browser_action, window_action, item_action): (
|
||||||
&Rc<BrowserAction>,
|
&Rc<BrowserAction>,
|
||||||
&Rc<WindowAction>,
|
&Rc<WindowAction>,
|
||||||
&Rc<TabAction>,
|
&Rc<ItemAction>,
|
||||||
),
|
),
|
||||||
|
(back_action_name, forward_action_name): (&str, &str),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Init components
|
// Init components
|
||||||
let content = Rc::new(Content::build((window_action, tab_action)));
|
let content = Rc::new(Content::build((window_action, item_action)));
|
||||||
|
|
||||||
let search = Rc::new(Search::new());
|
let search = Rc::new(Search::new());
|
||||||
|
|
||||||
let navigation = Rc::new(Navigation::build(
|
let navigation = Rc::new(Navigation::build(
|
||||||
profile,
|
profile,
|
||||||
(browser_action, window_action, tab_action),
|
(browser_action, window_action, item_action),
|
||||||
|
(back_action_name, forward_action_name),
|
||||||
));
|
));
|
||||||
|
|
||||||
let input = Rc::new(Input::new());
|
let input = Rc::new(Input::new());
|
||||||
@ -72,7 +74,7 @@ impl Page {
|
|||||||
profile: profile.clone(),
|
profile: profile.clone(),
|
||||||
// Actions
|
// Actions
|
||||||
browser_action: browser_action.clone(),
|
browser_action: browser_action.clone(),
|
||||||
tab_action: tab_action.clone(),
|
item_action: item_action.clone(),
|
||||||
window_action: window_action.clone(),
|
window_action: window_action.clone(),
|
||||||
// Components
|
// Components
|
||||||
content,
|
content,
|
||||||
|
@ -5,7 +5,7 @@ mod text;
|
|||||||
use image::Image;
|
use image::Image;
|
||||||
use text::Text;
|
use text::Text;
|
||||||
|
|
||||||
use super::{TabAction, WindowAction};
|
use super::{ItemAction, WindowAction};
|
||||||
use adw::StatusPage;
|
use adw::StatusPage;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gdk::Paintable,
|
gdk::Paintable,
|
||||||
@ -18,7 +18,7 @@ use std::{rc::Rc, time::Duration};
|
|||||||
|
|
||||||
pub struct Content {
|
pub struct Content {
|
||||||
window_action: Rc<WindowAction>,
|
window_action: Rc<WindowAction>,
|
||||||
tab_action: Rc<TabAction>,
|
item_action: Rc<ItemAction>,
|
||||||
pub g_box: Box,
|
pub g_box: Box,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,11 +26,11 @@ impl Content {
|
|||||||
// Construct
|
// Construct
|
||||||
|
|
||||||
/// Create new container for different components
|
/// Create new container for different components
|
||||||
pub fn build((window_action, tab_action): (&Rc<WindowAction>, &Rc<TabAction>)) -> Self {
|
pub fn build((window_action, item_action): (&Rc<WindowAction>, &Rc<ItemAction>)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
g_box: Box::builder().orientation(Orientation::Vertical).build(),
|
g_box: Box::builder().orientation(Orientation::Vertical).build(),
|
||||||
window_action: window_action.clone(),
|
window_action: window_action.clone(),
|
||||||
tab_action: tab_action.clone(),
|
item_action: item_action.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ impl Content {
|
|||||||
pub fn to_status_mime(
|
pub fn to_status_mime(
|
||||||
&self,
|
&self,
|
||||||
mime: &str,
|
mime: &str,
|
||||||
download: Option<(&Rc<TabAction>, &Uri)>,
|
download: Option<(&Rc<ItemAction>, &Uri)>,
|
||||||
) -> StatusPage {
|
) -> StatusPage {
|
||||||
self.clean();
|
self.clean();
|
||||||
let status = status::mime::build(mime, download);
|
let status = status::mime::build(mime, download);
|
||||||
@ -90,7 +90,7 @@ impl Content {
|
|||||||
/// * action removes previous children component from `Self`
|
/// * action removes previous children component from `Self`
|
||||||
pub fn to_status_identity(&self) -> StatusPage {
|
pub fn to_status_identity(&self) -> StatusPage {
|
||||||
self.clean();
|
self.clean();
|
||||||
let status = status::identity::build(self.tab_action.clone());
|
let status = status::identity::build(self.item_action.clone());
|
||||||
self.g_box.append(&status);
|
self.g_box.append(&status);
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ impl Content {
|
|||||||
/// * could be useful to extract document title parsed from Gemtext
|
/// * could be useful to extract document title parsed from Gemtext
|
||||||
pub fn to_text_gemini(&self, base: &Uri, data: &str) -> Text {
|
pub fn to_text_gemini(&self, base: &Uri, data: &str) -> Text {
|
||||||
self.clean();
|
self.clean();
|
||||||
let text = Text::new_gemini(data, base, (&self.window_action, &self.tab_action));
|
let text = Text::new_gemini(data, base, (&self.window_action, &self.item_action));
|
||||||
self.g_box.append(&text.g_box);
|
self.g_box.append(&text.g_box);
|
||||||
text
|
text
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,4 @@ pub mod identity;
|
|||||||
pub mod loading;
|
pub mod loading;
|
||||||
pub mod mime;
|
pub mod mime;
|
||||||
|
|
||||||
use super::TabAction;
|
use super::ItemAction;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use super::TabAction;
|
use super::ItemAction;
|
||||||
use adw::StatusPage;
|
use adw::StatusPage;
|
||||||
use gtk::{glib::Uri, prelude::ButtonExt, Align, Button};
|
use gtk::{glib::Uri, prelude::ButtonExt, Align, Button};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
/// Create new default `GObject` preset for mime issue
|
/// Create new default `GObject` preset for mime issue
|
||||||
/// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html)
|
/// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html)
|
||||||
pub fn build(mime: &str, download: Option<(&Rc<TabAction>, &Uri)>) -> StatusPage {
|
pub fn build(mime: &str, download: Option<(&Rc<ItemAction>, &Uri)>) -> StatusPage {
|
||||||
let status_page = StatusPage::builder()
|
let status_page = StatusPage::builder()
|
||||||
.description(format!("Content type `{mime}` not supported!"))
|
.description(format!("Content type `{mime}` not supported!"))
|
||||||
.icon_name("dialog-question-symbolic")
|
.icon_name("dialog-question-symbolic")
|
||||||
|
@ -4,7 +4,7 @@ mod source;
|
|||||||
use gemini::Gemini;
|
use gemini::Gemini;
|
||||||
use source::Source;
|
use source::Source;
|
||||||
|
|
||||||
use super::{TabAction, WindowAction};
|
use super::{ItemAction, WindowAction};
|
||||||
use gtk::{
|
use gtk::{
|
||||||
glib::Uri,
|
glib::Uri,
|
||||||
prelude::{BoxExt, Cast},
|
prelude::{BoxExt, Cast},
|
||||||
@ -28,10 +28,10 @@ impl Text {
|
|||||||
pub fn new_gemini(
|
pub fn new_gemini(
|
||||||
gemtext: &str,
|
gemtext: &str,
|
||||||
base: &Uri,
|
base: &Uri,
|
||||||
(window_action, tab_action): (&Rc<WindowAction>, &Rc<TabAction>),
|
(window_action, item_action): (&Rc<WindowAction>, &Rc<ItemAction>),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Init components
|
// Init components
|
||||||
let gemini = Gemini::new(gemtext, base, (window_action, tab_action));
|
let gemini = Gemini::new(gemtext, base, (window_action, item_action));
|
||||||
|
|
||||||
// Init main widget
|
// Init main widget
|
||||||
let g_box = Box::builder().orientation(Orientation::Vertical).build();
|
let g_box = Box::builder().orientation(Orientation::Vertical).build();
|
||||||
|
@ -4,7 +4,7 @@ mod widget;
|
|||||||
use reader::Reader;
|
use reader::Reader;
|
||||||
use widget::Widget;
|
use widget::Widget;
|
||||||
|
|
||||||
use crate::app::browser::window::{tab::item::Action as TabAction, Action as WindowAction};
|
use crate::app::browser::window::{tab::item::Action as ItemAction, Action as WindowAction};
|
||||||
use gtk::glib::Uri;
|
use gtk::glib::Uri;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -18,11 +18,11 @@ impl Gemini {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
gemtext: &str,
|
gemtext: &str,
|
||||||
base: &Uri,
|
base: &Uri,
|
||||||
(window_action, tab_action): (&Rc<WindowAction>, &Rc<TabAction>),
|
(window_action, item_action): (&Rc<WindowAction>, &Rc<ItemAction>),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Init components
|
// Init components
|
||||||
let reader = Rc::new(
|
let reader = Rc::new(
|
||||||
Reader::new(gemtext, base, (window_action.clone(), tab_action.clone())).unwrap(),
|
Reader::new(gemtext, base, (window_action.clone(), item_action.clone())).unwrap(),
|
||||||
); // @TODO handle errors
|
); // @TODO handle errors
|
||||||
let widget = Rc::new(Widget::new(&reader.widget.text_view));
|
let widget = Rc::new(Widget::new(&reader.widget.text_view));
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use syntax::Syntax;
|
|||||||
use tag::Tag;
|
use tag::Tag;
|
||||||
use widget::Widget;
|
use widget::Widget;
|
||||||
|
|
||||||
use super::{TabAction, WindowAction};
|
use super::{ItemAction, WindowAction};
|
||||||
use crate::app::browser::window::action::Position;
|
use crate::app::browser::window::action::Position;
|
||||||
use ggemtext::line::{
|
use ggemtext::line::{
|
||||||
code::{Inline, Multiline},
|
code::{Inline, Multiline},
|
||||||
@ -43,7 +43,7 @@ impl Reader {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
gemtext: &str,
|
gemtext: &str,
|
||||||
base: &Uri,
|
base: &Uri,
|
||||||
(window_action, tab_action): (Rc<WindowAction>, Rc<TabAction>),
|
(window_action, item_action): (Rc<WindowAction>, Rc<ItemAction>),
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
// Init default values
|
// Init default values
|
||||||
let mut title = None;
|
let mut title = None;
|
||||||
@ -332,7 +332,7 @@ impl Reader {
|
|||||||
return match uri.scheme().as_str() {
|
return match uri.scheme().as_str() {
|
||||||
"gemini" | "titan" => {
|
"gemini" | "titan" => {
|
||||||
// Open new page in browser
|
// Open new page in browser
|
||||||
tab_action.load.activate(Some(&uri.to_str()), true);
|
item_action.load.activate(Some(&uri.to_str()), true);
|
||||||
}
|
}
|
||||||
// Scheme not supported, delegate
|
// Scheme not supported, delegate
|
||||||
_ => UriLauncher::new(&uri.to_str()).launch(
|
_ => UriLauncher::new(&uri.to_str()).launch(
|
||||||
|
@ -2,7 +2,7 @@ mod response;
|
|||||||
mod sensitive;
|
mod sensitive;
|
||||||
mod titan;
|
mod titan;
|
||||||
|
|
||||||
use super::TabAction;
|
use super::ItemAction;
|
||||||
use adw::Clamp;
|
use adw::Clamp;
|
||||||
use gtk::{glib::Uri, prelude::WidgetExt, Box, Label};
|
use gtk::{glib::Uri, prelude::WidgetExt, Box, Label};
|
||||||
use response::Response;
|
use response::Response;
|
||||||
@ -52,7 +52,7 @@ impl Input {
|
|||||||
// Setters
|
// Setters
|
||||||
pub fn set_new_response(
|
pub fn set_new_response(
|
||||||
&self,
|
&self,
|
||||||
action: Rc<TabAction>,
|
action: Rc<ItemAction>,
|
||||||
base: Uri,
|
base: Uri,
|
||||||
title: Option<&str>,
|
title: Option<&str>,
|
||||||
size_limit: Option<usize>,
|
size_limit: Option<usize>,
|
||||||
@ -64,7 +64,7 @@ impl Input {
|
|||||||
|
|
||||||
pub fn set_new_sensitive(
|
pub fn set_new_sensitive(
|
||||||
&self,
|
&self,
|
||||||
action: Rc<TabAction>,
|
action: Rc<ItemAction>,
|
||||||
base: Uri,
|
base: Uri,
|
||||||
title: Option<&str>,
|
title: Option<&str>,
|
||||||
max_length: Option<i32>,
|
max_length: Option<i32>,
|
||||||
|
@ -6,7 +6,7 @@ use control::Control;
|
|||||||
use form::Form;
|
use form::Form;
|
||||||
use title::Title;
|
use title::Title;
|
||||||
|
|
||||||
use super::TabAction;
|
use super::ItemAction;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::SimpleAction,
|
gio::SimpleAction,
|
||||||
glib::{uuid_string_random, Uri, UriHideFlags},
|
glib::{uuid_string_random, Uri, UriHideFlags},
|
||||||
@ -28,7 +28,7 @@ impl Response {
|
|||||||
|
|
||||||
/// Build new `Self`
|
/// Build new `Self`
|
||||||
pub fn build(
|
pub fn build(
|
||||||
tab_action: Rc<TabAction>,
|
item_action: Rc<ItemAction>,
|
||||||
base: Uri,
|
base: Uri,
|
||||||
title: Option<&str>,
|
title: Option<&str>,
|
||||||
size_limit: Option<usize>,
|
size_limit: Option<usize>,
|
||||||
@ -77,7 +77,7 @@ impl Response {
|
|||||||
action_send.connect_activate({
|
action_send.connect_activate({
|
||||||
let form = form.clone();
|
let form = form.clone();
|
||||||
move |_, _| {
|
move |_, _| {
|
||||||
tab_action.load.activate(
|
item_action.load.activate(
|
||||||
Some(&format!(
|
Some(&format!(
|
||||||
"{}?{}",
|
"{}?{}",
|
||||||
base.to_string_partial(UriHideFlags::QUERY),
|
base.to_string_partial(UriHideFlags::QUERY),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
mod form;
|
mod form;
|
||||||
|
|
||||||
use super::TabAction;
|
use super::ItemAction;
|
||||||
use form::Form;
|
use form::Form;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio::SimpleAction,
|
gio::SimpleAction,
|
||||||
@ -22,7 +22,7 @@ impl Sensitive {
|
|||||||
|
|
||||||
/// Build new `Self`
|
/// Build new `Self`
|
||||||
pub fn build(
|
pub fn build(
|
||||||
tab_action: Rc<TabAction>,
|
item_action: Rc<ItemAction>,
|
||||||
base: Uri,
|
base: Uri,
|
||||||
title: Option<&str>,
|
title: Option<&str>,
|
||||||
max_length: Option<i32>,
|
max_length: Option<i32>,
|
||||||
@ -54,7 +54,7 @@ impl Sensitive {
|
|||||||
action_send.connect_activate({
|
action_send.connect_activate({
|
||||||
let form = form.clone();
|
let form = form.clone();
|
||||||
move |_, _| {
|
move |_, _| {
|
||||||
tab_action.load.activate(
|
item_action.load.activate(
|
||||||
Some(&format!(
|
Some(&format!(
|
||||||
"{}?{}",
|
"{}?{}",
|
||||||
base.to_string_partial(UriHideFlags::QUERY),
|
base.to_string_partial(UriHideFlags::QUERY),
|
||||||
|
@ -6,20 +6,18 @@ mod reload;
|
|||||||
mod request;
|
mod request;
|
||||||
mod widget;
|
mod widget;
|
||||||
|
|
||||||
|
use super::{BrowserAction, ItemAction, Profile, WindowAction};
|
||||||
use bookmark::Bookmark;
|
use bookmark::Bookmark;
|
||||||
use gtk::Button;
|
use gtk::{Box, Button};
|
||||||
use history::History;
|
use history::History;
|
||||||
use home::Home;
|
use home::Home;
|
||||||
use reload::Reload;
|
use reload::Reload;
|
||||||
use request::Request;
|
use request::Request;
|
||||||
use widget::Widget;
|
|
||||||
|
|
||||||
use super::{BrowserAction, Profile, TabAction, WindowAction};
|
|
||||||
use sqlite::Transaction;
|
use sqlite::Transaction;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use widget::Widget;
|
||||||
|
|
||||||
pub struct Navigation {
|
pub struct Navigation {
|
||||||
pub history: Rc<History>,
|
|
||||||
pub profile: Rc<Profile>,
|
pub profile: Rc<Profile>,
|
||||||
pub request: Rc<Request>,
|
pub request: Rc<Request>,
|
||||||
pub widget: Rc<Widget>,
|
pub widget: Rc<Widget>,
|
||||||
@ -28,21 +26,21 @@ pub struct Navigation {
|
|||||||
impl Navigation {
|
impl Navigation {
|
||||||
pub fn build(
|
pub fn build(
|
||||||
profile: &Rc<Profile>,
|
profile: &Rc<Profile>,
|
||||||
(browser_action, window_action, tab_action): (
|
(browser_action, window_action, item_action): (
|
||||||
&Rc<BrowserAction>,
|
&Rc<BrowserAction>,
|
||||||
&Rc<WindowAction>,
|
&Rc<WindowAction>,
|
||||||
&Rc<TabAction>,
|
&Rc<ItemAction>,
|
||||||
),
|
),
|
||||||
|
(back_action_name, forward_action_name): (&str, &str),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// init children components
|
// init children components
|
||||||
|
|
||||||
let history = Rc::new(History::build(window_action));
|
let request = Rc::new(Request::build((browser_action, item_action)));
|
||||||
let request = Rc::new(Request::build((browser_action, tab_action)));
|
|
||||||
|
|
||||||
// init main widget
|
// init main widget
|
||||||
let widget = Rc::new(Widget::build(
|
let widget = Rc::new(Widget::build(
|
||||||
&Button::home(window_action),
|
&Button::home(window_action),
|
||||||
&history.widget.g_box, // @TODO
|
&Box::history(back_action_name, forward_action_name),
|
||||||
&Button::reload(window_action),
|
&Button::reload(window_action),
|
||||||
&request.widget.entry, // @TODO
|
&request.widget.entry, // @TODO
|
||||||
&Button::bookmark(window_action),
|
&Button::bookmark(window_action),
|
||||||
@ -50,7 +48,6 @@ impl Navigation {
|
|||||||
|
|
||||||
// done
|
// done
|
||||||
Self {
|
Self {
|
||||||
history,
|
|
||||||
profile: profile.clone(),
|
profile: profile.clone(),
|
||||||
request,
|
request,
|
||||||
widget,
|
widget,
|
||||||
|
@ -1,107 +1,26 @@
|
|||||||
mod back;
|
pub mod back;
|
||||||
mod forward;
|
pub mod forward;
|
||||||
mod widget;
|
|
||||||
|
|
||||||
use back::Back;
|
pub use back::Back;
|
||||||
use forward::Forward;
|
pub use forward::Forward;
|
||||||
use widget::Widget;
|
|
||||||
|
|
||||||
use super::WindowAction;
|
use gtk::{prelude::BoxExt, Box, Button, Orientation};
|
||||||
use gtk::{glib::GString, Button};
|
|
||||||
use std::{cell::RefCell, rc::Rc};
|
|
||||||
|
|
||||||
struct Memory {
|
pub trait History {
|
||||||
request: GString,
|
fn history(back_action_name: &str, forward_action_name: &str) -> Self;
|
||||||
// time: SystemTime,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct History {
|
impl History for Box {
|
||||||
// Extras
|
fn history(back_action_name: &str, forward_action_name: &str) -> Self {
|
||||||
memory: RefCell<Vec<Memory>>,
|
let g_box = Box::builder()
|
||||||
index: RefCell<Option<usize>>,
|
.orientation(Orientation::Horizontal)
|
||||||
// GTK
|
.css_classes([
|
||||||
pub widget: Rc<Widget>,
|
"linked", // merge childs
|
||||||
}
|
])
|
||||||
|
.build();
|
||||||
|
|
||||||
impl History {
|
g_box.append(&Button::back(back_action_name));
|
||||||
// Constructors
|
g_box.append(&Button::forward(forward_action_name));
|
||||||
|
g_box
|
||||||
/// 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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
use super::WindowAction;
|
use gtk::Button;
|
||||||
use gtk::{prelude::ActionExt, Button};
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub trait Back {
|
pub trait Back {
|
||||||
fn back(action: &Rc<WindowAction>) -> Self;
|
fn back(action_name: &str) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Back for Button {
|
impl Back for Button {
|
||||||
fn back(action: &Rc<WindowAction>) -> Self {
|
fn back(action_name: &str) -> Self {
|
||||||
Button::builder()
|
Button::builder()
|
||||||
.action_name(format!(
|
.action_name(action_name)
|
||||||
"{}.{}",
|
|
||||||
action.id,
|
|
||||||
action.history_back.simple_action.name()
|
|
||||||
)) // @TODO
|
|
||||||
.icon_name("go-previous-symbolic")
|
.icon_name("go-previous-symbolic")
|
||||||
.tooltip_text("Back")
|
.tooltip_text("Back")
|
||||||
.build()
|
.build()
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
use super::WindowAction;
|
use gtk::Button;
|
||||||
use gtk::{prelude::ActionExt, Button};
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub trait Forward {
|
pub trait Forward {
|
||||||
fn forward(action: &Rc<WindowAction>) -> Self;
|
fn forward(action_name: &str) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Forward for Button {
|
impl Forward for Button {
|
||||||
fn forward(action: &Rc<WindowAction>) -> Self {
|
fn forward(action_name: &str) -> Self {
|
||||||
Button::builder()
|
Button::builder()
|
||||||
.action_name(format!(
|
.action_name(action_name)
|
||||||
"{}.{}",
|
|
||||||
action.id,
|
|
||||||
action.history_back.simple_action.name()
|
|
||||||
)) // @TODO
|
|
||||||
.icon_name("go-next-symbolic")
|
.icon_name("go-next-symbolic")
|
||||||
.tooltip_text("Forward")
|
.tooltip_text("Forward")
|
||||||
.build()
|
.build()
|
||||||
|
@ -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 }
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,7 @@ mod widget;
|
|||||||
|
|
||||||
use widget::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::{
|
use gtk::{
|
||||||
glib::{gformat, GString, Uri, UriFlags},
|
glib::{gformat, GString, Uri, UriFlags},
|
||||||
prelude::EditableExt,
|
prelude::EditableExt,
|
||||||
@ -21,9 +21,9 @@ impl Request {
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
/// Build new `Self`
|
/// 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 {
|
Self {
|
||||||
widget: Rc::new(Widget::build((browser_action, tab_action))),
|
widget: Rc::new(Widget::build((browser_action, item_action))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ mod primary_icon;
|
|||||||
|
|
||||||
use primary_icon::PrimaryIcon;
|
use primary_icon::PrimaryIcon;
|
||||||
|
|
||||||
use super::{BrowserAction, TabAction};
|
use super::{BrowserAction, ItemAction};
|
||||||
use gtk::{
|
use gtk::{
|
||||||
glib::{timeout_add_local, ControlFlow, SourceId},
|
glib::{timeout_add_local, ControlFlow, SourceId},
|
||||||
prelude::{EditableExt, EntryExt, WidgetExt},
|
prelude::{EditableExt, EntryExt, WidgetExt},
|
||||||
@ -36,7 +36,7 @@ impl Widget {
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
/// Build new `Self`
|
/// 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
|
// Init animated progress bar state
|
||||||
let progress = Rc::new(Progress {
|
let progress = Rc::new(Progress {
|
||||||
fraction: RefCell::new(0.0),
|
fraction: RefCell::new(0.0),
|
||||||
@ -52,10 +52,10 @@ impl Widget {
|
|||||||
|
|
||||||
// Connect events
|
// Connect events
|
||||||
entry.connect_icon_release({
|
entry.connect_icon_release({
|
||||||
let tab_action = tab_action.clone();
|
let item_action = item_action.clone();
|
||||||
move |this, position| match position {
|
move |this, position| match position {
|
||||||
EntryIconPosition::Primary => tab_action.ident.activate(), // @TODO PrimaryIcon impl
|
EntryIconPosition::Primary => item_action.ident.activate(), // @TODO PrimaryIcon impl
|
||||||
EntryIconPosition::Secondary => tab_action.load.activate(Some(&this.text()), true),
|
EntryIconPosition::Secondary => item_action.load.activate(Some(&this.text()), true),
|
||||||
_ => todo!(), // unexpected
|
_ => todo!(), // unexpected
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -77,9 +77,9 @@ impl Widget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
entry.connect_activate({
|
entry.connect_activate({
|
||||||
let tab_action = tab_action.clone();
|
let item_action = item_action.clone();
|
||||||
move |entry| {
|
move |entry| {
|
||||||
tab_action.load.activate(Some(&entry.text()), true);
|
item_action.load.activate(Some(&entry.text()), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user