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

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