Implement focus_previous operation
This commit is contained in:
parent
54ad92ce91
commit
6eb3dd7e5e
3 changed files with 60 additions and 12 deletions
|
|
@ -51,7 +51,7 @@ enum Message {
|
|||
CreateTask,
|
||||
FilterChanged(Filter),
|
||||
TaskMessage(usize, TaskMessage),
|
||||
TabPressed,
|
||||
TabPressed { shift: bool },
|
||||
}
|
||||
|
||||
impl Application for Todos {
|
||||
|
|
@ -147,7 +147,13 @@ impl Application for Todos {
|
|||
|
||||
Command::none()
|
||||
}
|
||||
Message::TabPressed => widget::focus_next(),
|
||||
Message::TabPressed { shift } => {
|
||||
if shift {
|
||||
widget::focus_previous()
|
||||
} else {
|
||||
widget::focus_next()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
};
|
||||
|
||||
|
|
@ -251,10 +257,13 @@ impl Application for Todos {
|
|||
(
|
||||
Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: keyboard::KeyCode::Tab,
|
||||
modifiers,
|
||||
..
|
||||
}),
|
||||
event::Status::Ignored,
|
||||
) => Some(Message::TabPressed),
|
||||
) => Some(Message::TabPressed {
|
||||
shift: modifiers.shift(),
|
||||
}),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,46 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn focus_previous<T>() -> impl Operation<T> {
|
||||
struct FocusPrevious {
|
||||
count: FocusCount,
|
||||
current: usize,
|
||||
}
|
||||
|
||||
impl<T> Operation<T> for FocusPrevious {
|
||||
fn focusable(
|
||||
&mut self,
|
||||
state: &mut dyn state::Focusable,
|
||||
_id: Option<&Id>,
|
||||
) {
|
||||
if self.count.total == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.count.focused {
|
||||
None if self.current == self.count.total - 1 => state.focus(),
|
||||
Some(0) if self.current == 0 => state.unfocus(),
|
||||
Some(0) => {}
|
||||
Some(focused) if focused == self.current => state.unfocus(),
|
||||
Some(focused) if focused - 1 == self.current => state.focus(),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.current += 1;
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self)
|
||||
}
|
||||
}
|
||||
|
||||
count_focusable(|count| FocusPrevious { count, current: 0 })
|
||||
}
|
||||
|
||||
pub fn focus_next<T>() -> impl Operation<T> {
|
||||
struct FocusNext {
|
||||
count: FocusCount,
|
||||
|
|
@ -121,19 +161,10 @@ pub fn focus_next<T>() -> impl Operation<T> {
|
|||
state: &mut dyn state::Focusable,
|
||||
_id: Option<&Id>,
|
||||
) {
|
||||
if self.count.total == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.count.focused {
|
||||
None if self.current == 0 => state.focus(),
|
||||
Some(focused) if focused == self.current => state.unfocus(),
|
||||
Some(focused) if focused + 1 == self.current => state.focus(),
|
||||
Some(focused)
|
||||
if focused == self.count.total - 1 && self.current == 0 =>
|
||||
{
|
||||
state.focus()
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,6 +215,14 @@ pub use svg::Svg;
|
|||
use crate::Command;
|
||||
use iced_native::widget::operation;
|
||||
|
||||
/// Focuses the previous focusable widget.
|
||||
pub fn focus_previous<Message>() -> Command<Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
Command::widget(operation::focus_previous())
|
||||
}
|
||||
|
||||
/// Focuses the next focusable widget.
|
||||
pub fn focus_next<Message>() -> Command<Message>
|
||||
where
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue