appcui/ui/keyselector/
keyselector.rs1use crate::prelude::*;
2use crate::ui::keyselector::{events::EventData, Flags};
3
4#[CustomControl(overwrite=OnPaint+OnKeyPressed+OnMouseEvent, internal=true)]
5pub struct KeySelector {
6 flags: Flags,
7 key: Key,
8}
9impl KeySelector {
10
11 pub fn new(key: Key, layout: Layout, flags: Flags) -> Self {
28 let mut obj = Self {
29 base: ControlBase::with_status_flags(layout, StatusFlags::Visible | StatusFlags::Enabled | StatusFlags::AcceptInput),
30 flags,
31 key,
32 };
33 obj.set_size_bounds(5, 1, u16::MAX, 1);
34 obj
35 }
36
37 #[inline(always)]
39 pub fn key(&self) -> Key {
40 self.key
41 }
42
43 #[inline(always)]
45 pub fn set_key(&mut self, key: Key) {
46 self.key = key;
47 }
48}
49impl OnPaint for KeySelector {
50 fn on_paint(&self, surface: &mut Surface, theme: &Theme) {
51 let attr = match () {
52 _ if !self.is_enabled() => theme.editor.inactive,
53 _ if self.has_focus() => theme.editor.focused,
54 _ if self.is_mouse_over() => theme.editor.hovered,
55 _ => theme.editor.normal,
56 };
57 let right = self.size().width as i32;
58 surface.fill_horizontal_line(0, 0, right, Character::with_attributes(' ', attr));
59 surface.reduce_clip_by(1, 0, 1, 0);
60 let m = self.key.modifier.name();
61 let k = self.key.code.name();
62 if !m.is_empty() {
63 surface.write_string(1, 0, m, attr, false);
64 surface.write_string(1 + m.len() as i32, 0, k, attr, false);
65 } else if self.key == Key::None {
66 if self.has_focus() {
67 surface.write_string(1, 0, "None", attr, false);
68 } else {
69 surface.write_string(1, 0, "None", theme.editor.inactive, false);
70 }
71 } else {
72 surface.write_string(1, 0, k, attr, false);
73 }
74 if self.has_focus() {
75 surface.set_cursor(1, 0);
76 }
77 }
78}
79impl OnKeyPressed for KeySelector {
80 fn on_key_pressed(&mut self, key: Key, _: char) -> EventProcessStatus {
81 match key.code {
82 KeyCode::Enter => {
83 if (!self.flags.contains(Flags::AcceptEnter)) || (self.flags.contains(Flags::ReadOnly)) {
84 return EventProcessStatus::Ignored;
85 }
86 }
87 KeyCode::Escape => {
88 if (!self.flags.contains(Flags::AcceptEscape)) || (self.flags.contains(Flags::ReadOnly)) {
89 return EventProcessStatus::Ignored;
90 }
91 }
92 KeyCode::Tab => {
93 if (!self.flags.contains(Flags::AcceptTab)) || (self.flags.contains(Flags::ReadOnly)) {
94 return EventProcessStatus::Ignored;
95 }
96 }
97 _ => {}
98 }
99 if !self.flags.contains(Flags::ReadOnly) && self.key != key {
100 let old = self.key;
101 self.key = key;
102 self.raise_event(ControlEvent {
103 emitter: self.handle,
104 receiver: self.event_processor,
105 data: ControlEventData::KeySelector(EventData { new_key: key, old_key: old }),
106 });
107 }
108 EventProcessStatus::Processed
109 }
110}
111impl OnMouseEvent for KeySelector {
112 fn on_mouse_event(&mut self, event: &MouseEvent) -> EventProcessStatus {
113 match event {
114 MouseEvent::Enter | MouseEvent::Leave => EventProcessStatus::Processed,
115 _ => EventProcessStatus::Ignored,
116 }
117 }
118}