Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.7 kB · 158 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159pub mod button;pub mod slider;pub mod text_in;// pub mod text_in_scroll;pub mod toggle;pub mod toggle_button;
use winit::{ event::{KeyEvent, Modifiers}, keyboard::{Key, ModifiersState, NamedKey},};
use crate::{EventQueue, draw_buffer::DrawBuffer, pages::PageResponse};
pub(crate) trait Widget { fn draw(&self, draw_buffer: &mut DrawBuffer, selected: bool); /// true if the widget data was changed by the input fn process_input( &mut self, modifiers: &Modifiers, key_event: &KeyEvent, events: &mut EventQueue<'_>, ) -> WidgetResponse;
#[cfg(feature = "accesskit")] fn build_tree(&self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>);}
// #[derive(Debug)]// pub struct WidgetResponse<R> {// pub standard: StandardResponse,// pub extra: Option<R>,// }
// impl<R> Default for WidgetResponse<R> {// fn default() -> Self {// Self {// standard: StandardResponse::default(),// extra: None,// }// }// }
// impl<R> WidgetResponse<R> {// pub fn request_redraw() -> Self {// Self {// standard: StandardResponse::RequestRedraw,// extra: None,// }// }
// pub fn next_widget(value: u8) -> Self {// Self {// standard: StandardResponse::SwitchFocus(value),// extra: None,// }// }// }
// SwitchFocus also has to request a redraw#[derive(Debug, Default, PartialEq, Eq)]pub enum WidgetResponse { SwitchFocus(u8), /// true if the redraw is because the widget data was changed. /// This could be true even if the data didn't change. This makes the implementation of some widgets easier. /// It is still useful to keep other parts of the system in sync. /// /// A redraw request could otherwise be made because for example a internal cursor changed RequestRedraw(bool), // GlobalEvent(GlobalEvent), #[default] None,}
// impl<R> From<StandardResponse> for WidgetResponse<R> {// fn from(value: StandardResponse) -> Self {// Self {// standard: value,// extra: None,// }// }// }
impl WidgetResponse { pub fn to_page_resp(self, selected: &mut u8) -> PageResponse { match self { WidgetResponse::SwitchFocus(s) => { *selected = s; PageResponse::RequestRedraw } WidgetResponse::RequestRedraw(_) => PageResponse::RequestRedraw, WidgetResponse::None => PageResponse::None, } }
pub fn on_change(self, f: impl FnOnce()) -> Self { if self == WidgetResponse::RequestRedraw(true) { f(); } self }}
#[derive(Debug, Default)]pub struct NextWidget { pub left: Option<u8>, pub right: Option<u8>, pub up: Option<u8>, pub down: Option<u8>, pub tab: Option<u8>, pub shift_tab: Option<u8>,}
impl NextWidget { /// supposed to be called from Widgets, that own a NextWidget after catching their custom KeyEvents to pick a return pub fn process_key_event(&self, key_event: &KeyEvent, modifiers: &Modifiers) -> WidgetResponse { if !key_event.state.is_pressed() { return WidgetResponse::None; }
#[expect( non_local_definitions, reason = "this is only valid with these specific Option<u8> not in general" )] impl From<Option<u8>> for WidgetResponse { fn from(value: Option<u8>) -> Self { match value { Some(num) => WidgetResponse::SwitchFocus(num), None => WidgetResponse::None, } } }
if key_event.logical_key == Key::Named(NamedKey::ArrowUp) && modifiers.state().is_empty() { self.up.into() } else if key_event.logical_key == Key::Named(NamedKey::ArrowDown) && modifiers.state().is_empty() { self.down.into() } else if key_event.logical_key == Key::Named(NamedKey::ArrowRight) && modifiers.state().is_empty() { self.right.into() } else if key_event.logical_key == Key::Named(NamedKey::ArrowLeft) && modifiers.state().is_empty() { self.left.into() } else if key_event.logical_key == Key::Named(NamedKey::Tab) { if modifiers.state() == ModifiersState::SHIFT { self.shift_tab.into() } else { self.tab.into() } } else { WidgetResponse::None } }}