add request state

This commit is contained in:
yggverse 2024-11-11 12:52:46 +02:00
parent 3a0deabc14
commit 7bc2d478d0
5 changed files with 72 additions and 23 deletions

View File

@ -38,8 +38,8 @@ impl Window {
// Init events // Init events
action.append().connect_activate({ action.append().connect_activate({
let tab = tab.clone(); let tab = tab.clone();
move |position, is_pinned, is_selected| { move |position, request, is_pinned, is_selected| {
tab.append(position, is_pinned, is_selected); tab.append(position, request, is_pinned, is_selected);
} }
}); });

View File

@ -4,8 +4,9 @@ use gtk::{
prelude::{ActionExt, ToVariant}, prelude::{ActionExt, ToVariant},
}; };
/// C-compatible variant type /// C-compatible variant type defaults
const DEFAULT_POSITION: i32 = -1; const DEFAULT_POSITION: i32 = -1;
const DEFAULT_REQUEST: String = String::new();
const DEFAULT_IS_PINNED: bool = false; const DEFAULT_IS_PINNED: bool = false;
const DEFAULT_IS_SELECTED: bool = true; const DEFAULT_IS_SELECTED: bool = true;
@ -23,7 +24,13 @@ impl Append {
gobject: SimpleAction::new_stateful( gobject: SimpleAction::new_stateful(
&uuid_string_random(), &uuid_string_random(),
None, None,
&(DEFAULT_POSITION, DEFAULT_IS_PINNED, DEFAULT_IS_SELECTED).to_variant(), &(
DEFAULT_POSITION,
DEFAULT_REQUEST,
DEFAULT_IS_PINNED,
DEFAULT_IS_SELECTED,
)
.to_variant(),
), ),
} }
} }
@ -34,11 +41,12 @@ impl Append {
/// * this action reset previous state for action after activation /// * this action reset previous state for action after activation
pub fn activate_default_once(&self) { pub fn activate_default_once(&self) {
// Save current state in memory // Save current state in memory
let (position, is_pinned, is_selected) = state(&self.gobject); let (position, request, is_pinned, is_selected) = state(&self.gobject);
// Set default state // Set default state
self.change_state( self.change_state(
Some(DEFAULT_POSITION), Some(DEFAULT_POSITION),
Some(DEFAULT_REQUEST),
DEFAULT_IS_PINNED, DEFAULT_IS_PINNED,
DEFAULT_IS_SELECTED, DEFAULT_IS_SELECTED,
); );
@ -47,7 +55,7 @@ impl Append {
self.gobject.activate(None); self.gobject.activate(None);
// Return previous state // Return previous state
self.change_state(position, is_pinned, is_selected); self.change_state(position, request, is_pinned, is_selected);
} }
/// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
@ -55,24 +63,31 @@ impl Append {
pub fn activate_stateful_once( pub fn activate_stateful_once(
&self, &self,
position: Option<i32>, position: Option<i32>,
request: Option<String>,
is_pinned: bool, is_pinned: bool,
is_selected: bool, is_selected: bool,
) { ) {
// Save current state in memory // Save current state in memory
let (_position, _is_pinned, _is_selected) = state(&self.gobject); let (_position, _request, _is_pinned, _is_selected) = state(&self.gobject);
// Apply requested state // Apply requested state
self.change_state(position, is_pinned, is_selected); self.change_state(position, request, is_pinned, is_selected);
// Activate action // Activate action
self.gobject.activate(None); self.gobject.activate(None);
// Return previous state // Return previous state
self.change_state(_position, _is_pinned, _is_selected); self.change_state(_position, _request, _is_pinned, _is_selected);
} }
/// Emit state change for action /// Emit state change for action
pub fn change_state(&self, position: Option<i32>, is_pinned: bool, is_selected: bool) { pub fn change_state(
&self,
position: Option<i32>,
request: Option<String>,
is_pinned: bool,
is_selected: bool,
) {
self.gobject.change_state( self.gobject.change_state(
&( &(
// Convert Option to C-based variant value // Convert Option to C-based variant value
@ -81,6 +96,11 @@ impl Append {
} else { } else {
DEFAULT_POSITION DEFAULT_POSITION
}, },
if let Some(request) = request {
request
} else {
DEFAULT_REQUEST
},
is_pinned, is_pinned,
is_selected, is_selected,
) )
@ -93,10 +113,13 @@ impl Append {
/// Define callback function for /// Define callback function for
/// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal /// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
/// * return `position`, `is_pinned`, `is_selected` state as tuple /// * return `position`, `is_pinned`, `is_selected` state as tuple
pub fn connect_activate(&self, callback: impl Fn(Option<i32>, bool, bool) + 'static) { pub fn connect_activate(
&self,
callback: impl Fn(Option<i32>, Option<String>, bool, bool) + 'static,
) {
self.gobject.connect_activate(move |this, _| { self.gobject.connect_activate(move |this, _| {
let (position, is_pinned, is_selected) = state(this); let (position, request, is_pinned, is_selected) = state(this);
callback(position, is_pinned, is_selected) callback(position, request, is_pinned, is_selected)
}); });
} }
@ -114,12 +137,12 @@ impl Append {
} }
/// Shared helper to get C-based action state in Optional format /// Shared helper to get C-based action state in Optional format
pub fn state(this: &SimpleAction) -> (Option<i32>, bool, bool) { pub fn state(this: &SimpleAction) -> (Option<i32>, Option<String>, bool, bool) {
let (position, is_pinned, is_selected) = this let (position, request, is_pinned, is_selected) = this
.state() .state()
.expect("Expected (`position`,`is_pinned`,`is_selected`) state") .expect("Expected (`position`,`request`,`is_pinned`,`is_selected`) state")
.get::<(i32, bool, bool)>() .get::<(i32, String, bool, bool)>()
.expect("Parameter type does not match (`i32`,`bool`,`bool`) tuple"); .expect("Parameter type does not match (`i32`,`String`,`bool`,`bool`) tuple");
( (
// Convert from C-based variant value to Option // Convert from C-based variant value to Option
if position == DEFAULT_POSITION { if position == DEFAULT_POSITION {
@ -127,6 +150,11 @@ pub fn state(this: &SimpleAction) -> (Option<i32>, bool, bool) {
} else { } else {
Some(position) Some(position)
}, },
if request.is_empty() {
None
} else {
Some(request)
},
is_pinned, is_pinned,
is_selected, is_selected,
) )

View File

@ -99,7 +99,13 @@ impl Tab {
} }
// Actions // Actions
pub fn append(&self, position: Option<i32>, is_pinned: bool, is_selected: bool) -> Rc<Item> { pub fn append(
&self,
position: Option<i32>,
request: Option<String>,
is_pinned: bool,
is_selected: bool,
) -> Rc<Item> {
// Init new tab item // Init new tab item
let item = Rc::new(Item::new( let item = Rc::new(Item::new(
self.widget.gobject(), self.widget.gobject(),
@ -107,6 +113,7 @@ impl Tab {
self.window_action.clone(), self.window_action.clone(),
// Options // Options
position, position,
request,
is_pinned, is_pinned,
is_selected, is_selected,
)); ));
@ -305,7 +312,7 @@ impl Tab {
pub fn init(&self) { pub fn init(&self) {
// Append just one blank page if no tabs available after last session restore // Append just one blank page if no tabs available after last session restore
if self.index.borrow().is_empty() { if self.index.borrow().is_empty() {
self.append(None, false, true); self.append(None, None, false, true);
} }
// @TODO other/child features.. // @TODO other/child features..

View File

@ -36,6 +36,7 @@ impl Item {
window_action: Rc<WindowAction>, window_action: Rc<WindowAction>,
// Options // Options
position: Option<i32>, position: Option<i32>,
request: Option<String>,
is_pinned: bool, is_pinned: bool,
is_selected: bool, is_selected: bool,
) -> Self { ) -> Self {
@ -65,6 +66,15 @@ impl Item {
// Init events // Init events
if let Some(text) = request {
page.navigation()
.request()
.widget()
.gobject()
.set_text(&text);
page.load(true);
} // @TODO load optionally
action.load().connect_activate({ action.load().connect_activate({
let page = page.clone(); let page = page.clone();
move |request| { move |request| {
@ -144,6 +154,7 @@ impl Item {
window_action.clone(), window_action.clone(),
// Options // Options
None, None,
None,
record.is_pinned, record.is_pinned,
record.is_selected, record.is_selected,
)); ));

View File

@ -288,9 +288,12 @@ impl Reader {
return match uri.scheme().as_str() { return match uri.scheme().as_str() {
"gemini" => { "gemini" => {
// Open new page in browser // Open new page in browser
window_action window_action.append().activate_stateful_once(
.append() None,
.activate_stateful_once(None, false, false); Some(uri.to_string()),
false,
false,
); // @TODO
} }
// Scheme not supported, delegate // Scheme not supported, delegate
_ => UriLauncher::new(&uri.to_str()).launch( _ => UriLauncher::new(&uri.to_str()).launch(