Added a AlwaysFocused component #26

This commit is contained in:
2025-08-04 08:23:51 -05:00
parent 3a5286a54f
commit 896dfb0a36
2 changed files with 105 additions and 92 deletions
+1
View File
@@ -23,6 +23,7 @@ pub fn app(screen: Arc<Screen>) -> Rsx {
} }
} }
}}); }});
@AlwaysFocused;
Paginator { Paginator {
FlexRow { FlexRow {
Heading, smooth: false, { "OSUI" } Heading, smooth: false, { "OSUI" }
+104 -92
View File
@@ -1,8 +1,19 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::component;
use super::Extension; use super::Extension;
use crossterm::event::{Event as CrosstermEvent, KeyCode}; use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyModifiers};
component!(AlwaysFocused);
enum Direction {
Left,
Right,
Up,
Down,
}
pub struct RelativeFocusExtension { pub struct RelativeFocusExtension {
cursor: usize, cursor: usize,
@@ -13,94 +24,102 @@ impl Extension for RelativeFocusExtension {
fn event(&mut self, ctx: &super::Context, event: &dyn super::Event) { fn event(&mut self, ctx: &super::Context, event: &dyn super::Event) {
if let Some(e) = event.get::<CrosstermEvent>() { if let Some(e) = event.get::<CrosstermEvent>() {
match e { match e {
CrosstermEvent::Key(k) => match k.code { CrosstermEvent::Key(k) => {
KeyCode::Right => { if k.modifiers.contains(KeyModifiers::SHIFT) {
let rendered = self.rendered.lock().unwrap(); match k.code {
let (_, current_x, current_y) = rendered KeyCode::Right => {
.iter() let rendered = self.rendered.lock().unwrap();
.find(|r| r.0 == self.cursor) let (_, current_x, current_y) = rendered
.unwrap_or(&(0, 0, 0)); .iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction( if let Some(index) = find_closest_in_direction(
Direction::Right, Direction::Right,
*current_x, *current_x,
*current_y, *current_y,
&rendered, &rendered,
self.cursor, self.cursor,
) { ) {
self.cursor = index; self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() { for (i, w) in ctx.get_widgets().iter().enumerate() {
w.set_focused(i == self.cursor); w.set_focused(i == self.cursor);
}
}
} }
KeyCode::Left => {
let rendered = self.rendered.lock().unwrap();
let (_, current_x, current_y) = rendered
.iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction(
Direction::Left,
*current_x,
*current_y,
&rendered,
self.cursor,
) {
self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() {
w.set_focused(i == self.cursor);
}
}
}
KeyCode::Up => {
let rendered = self.rendered.lock().unwrap();
let (_, current_x, current_y) = rendered
.iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction(
Direction::Up,
*current_x,
*current_y,
&rendered,
self.cursor,
) {
self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() {
w.set_focused(i == self.cursor);
}
}
}
KeyCode::Down => {
let rendered = self.rendered.lock().unwrap();
let (_, current_x, current_y) = *rendered
.iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction(
Direction::Down,
current_x,
current_y,
&rendered,
self.cursor,
) {
self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() {
if let Some(AlwaysFocused) = w.get() {
w.set_focused(true);
} else {
w.set_focused(i == self.cursor);
}
}
}
}
_ => {}
} }
} }
}
KeyCode::Left => {
let rendered = self.rendered.lock().unwrap();
let (_, current_x, current_y) = rendered
.iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction(
Direction::Left,
*current_x,
*current_y,
&rendered,
self.cursor,
) {
self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() {
w.set_focused(i == self.cursor);
}
}
}
KeyCode::Up => {
let rendered = self.rendered.lock().unwrap();
let (_, current_x, current_y) = rendered
.iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction(
Direction::Up,
*current_x,
*current_y,
&rendered,
self.cursor,
) {
self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() {
w.set_focused(i == self.cursor);
}
}
}
KeyCode::Down => {
let rendered = self.rendered.lock().unwrap();
let (_, current_x, current_y) = *rendered
.iter()
.find(|r| r.0 == self.cursor)
.unwrap_or(&(0, 0, 0));
if let Some(index) = find_closest_in_direction(
Direction::Down,
current_x,
current_y,
&rendered,
self.cursor,
) {
self.cursor = index;
for (i, w) in ctx.get_widgets().iter().enumerate() {
w.set_focused(i == self.cursor);
}
}
}
_ => {}
},
_ => {} _ => {}
} }
} }
@@ -143,13 +162,6 @@ impl RelativeFocusExtension {
} }
} }
enum Direction {
Left,
Right,
Up,
Down,
}
fn find_closest_in_direction( fn find_closest_in_direction(
direction: Direction, direction: Direction,
current_x: u16, current_x: u16,