Widget focus
This commit is contained in:
parent
1ceca066d3
commit
c8e2ba3c5c
50
src/lib.rs
50
src/lib.rs
@ -8,13 +8,27 @@ use bevy_terminal_display::{
|
|||||||
crossterm::event::{Event, KeyCode, KeyEventKind},
|
crossterm::event::{Event, KeyCode, KeyEventKind},
|
||||||
input::events::TerminalInputEvent,
|
input::events::TerminalInputEvent,
|
||||||
ratatui::{
|
ratatui::{
|
||||||
layout::Rect, style::{Color, Modifier, Style}, widgets::{Block, Borders, Clear, HighlightSpacing, List, ListItem, ListState}
|
layout::Rect,
|
||||||
|
style::{Color, Modifier, Style},
|
||||||
|
widgets::{Block, Borders, Clear, HighlightSpacing, List, ListItem, ListState},
|
||||||
},
|
},
|
||||||
widgets::TerminalWidget,
|
widgets::TerminalWidget,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub enum MenuControlData<E: bevy::prelude::Event> {
|
||||||
|
Button {
|
||||||
|
label: String,
|
||||||
|
event: E,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MenuControl<E: bevy::prelude::Event> {
|
||||||
|
pub enabled: Arc<AtomicBool>,
|
||||||
|
pub data: MenuControlData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MenuWidget<E: bevy::prelude::Event> {
|
pub struct MenuWidget<E: bevy::prelude::Event> {
|
||||||
pub items: Vec<MenuOption<E>>,
|
pub items: Vec<MenuControl<E>>,
|
||||||
pub state: ListState,
|
pub state: ListState,
|
||||||
pub enabled_color: Color,
|
pub enabled_color: Color,
|
||||||
pub disabled_color: Color,
|
pub disabled_color: Color,
|
||||||
@ -37,12 +51,6 @@ impl<E: bevy::prelude::Event> Default for MenuWidget<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MenuOption<E: bevy::prelude::Event> {
|
|
||||||
pub enabled: Arc<AtomicBool>,
|
|
||||||
pub label: String,
|
|
||||||
pub event: E,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: bevy::prelude::Event + Clone> TerminalWidget for MenuWidget<E> {
|
impl<E: bevy::prelude::Event + Clone> TerminalWidget for MenuWidget<E> {
|
||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -67,7 +75,7 @@ impl<E: bevy::prelude::Event + Clone> TerminalWidget for MenuWidget<E> {
|
|||||||
let list = List::new(items)
|
let list = List::new(items)
|
||||||
.block(block)
|
.block(block)
|
||||||
.highlight_style(self.selected_style)
|
.highlight_style(self.selected_style)
|
||||||
.highlight_symbol(">")
|
.highlight_symbol("> ")
|
||||||
.highlight_spacing(HighlightSpacing::Always);
|
.highlight_spacing(HighlightSpacing::Always);
|
||||||
|
|
||||||
let area = if let Some(area) = &self.area_function {
|
let area = if let Some(area) = &self.area_function {
|
||||||
@ -91,11 +99,15 @@ impl<E: bevy::prelude::Event + Clone> TerminalWidget for MenuWidget<E> {
|
|||||||
if let Some(selected) = self.state.selected() {
|
if let Some(selected) = self.state.selected() {
|
||||||
if let Some(item) = self.items.get(selected) {
|
if let Some(item) = self.items.get(selected) {
|
||||||
if item.enabled.load(Ordering::Relaxed) {
|
if item.enabled.load(Ordering::Relaxed) {
|
||||||
commands.send_event(item.event.clone());
|
match &item.data {
|
||||||
|
MenuControlData::Button { event, .. } => {
|
||||||
|
commands.send_event(event.clone());
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
KeyCode::Up => self.state.select_previous(),
|
KeyCode::Up => self.state.select_previous(),
|
||||||
KeyCode::Down => self.state.select_next(),
|
KeyCode::Down => self.state.select_next(),
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -109,10 +121,12 @@ impl<E: bevy::prelude::Event> FromIterator<(&'static str, E)> for MenuWidget<E>
|
|||||||
fn from_iter<I: IntoIterator<Item = (&'static str, E)>>(iter: I) -> Self {
|
fn from_iter<I: IntoIterator<Item = (&'static str, E)>>(iter: I) -> Self {
|
||||||
let items = iter
|
let items = iter
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(label, event)| MenuOption {
|
.map(|(label, event)| MenuControl {
|
||||||
enabled: Arc::new(true.into()),
|
enabled: Arc::new(true.into()),
|
||||||
label: label.into(),
|
data: MenuControlData::Button {
|
||||||
event,
|
label: label.into(),
|
||||||
|
event,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Self {
|
Self {
|
||||||
@ -122,8 +136,10 @@ impl<E: bevy::prelude::Event> FromIterator<(&'static str, E)> for MenuWidget<E>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: bevy::prelude::Event> From<&MenuOption<E>> for ListItem<'_> {
|
impl<E: bevy::prelude::Event> From<&MenuControl<E>> for ListItem<'_> {
|
||||||
fn from(value: &MenuOption<E>) -> Self {
|
fn from(value: &MenuControl<E>) -> Self {
|
||||||
ListItem::new(value.label.clone())
|
match &value.data {
|
||||||
|
MenuControlData::Button { label, .. } => ListItem::new(label.clone()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user