Simplify Event enum

Now properly unify Alt/Ctrl/Shift handling
This commit is contained in:
Alexandre Bury 2016-07-10 18:27:26 -07:00
parent 99bf28dfd6
commit 6e0819f723
8 changed files with 237 additions and 362 deletions

View File

@ -36,10 +36,7 @@ impl View for KeyCodeView {
} }
fn on_event(&mut self, event: Event) -> EventResult { fn on_event(&mut self, event: Event) -> EventResult {
let line = match event { let line = format!("{:?}", event);
Event::Char(c) => format!("Char: {}", c),
Event::Key(key) => format!("Key: {}", key),
};
self.history.push(line); self.history.push(line);
while self.history.len() > self.size { while self.history.len() > self.size {

View File

@ -1,5 +1,5 @@
use backend; use backend;
use event; use event::{Event, Key};
use theme; use theme;
use utf8; use utf8;
@ -80,16 +80,16 @@ impl backend::Backend for NcursesBackend {
ncurses::mvaddstr(y as i32, x as i32, text); ncurses::mvaddstr(y as i32, x as i32, text);
} }
fn poll_event() -> event::Event { fn poll_event() -> Event {
let ch: i32 = ncurses::getch(); let ch: i32 = ncurses::getch();
// Is it a UTF-8 starting point? // Is it a UTF-8 starting point?
if 32 <= ch && ch < 0x100 && ch != 127 { if 32 <= ch && ch < 0x100 && ch != 127 {
event::Event::Char(utf8::read_char(ch as u8, Event::Char(utf8::read_char(ch as u8,
|| ncurses::getch() as u8) || ncurses::getch() as u8)
.unwrap()) .unwrap())
} else { } else {
event::Event::Key(parse_ncurses_char(ch)) parse_ncurses_char(ch)
} }
} }
@ -103,125 +103,122 @@ impl backend::Backend for NcursesBackend {
} }
/// Returns the Key enum corresponding to the given ncurses event. /// Returns the Key enum corresponding to the given ncurses event.
fn parse_ncurses_char(ch: i32) -> event::Key { fn parse_ncurses_char(ch: i32) -> Event {
match ch { match ch {
// Values under 256 are chars and control values // Values under 256 are chars and control values
// //
// Tab is '\t' // Tab is '\t'
9 => event::Key::Tab, 9 => Event::Key(Key::Tab),
// Treat '\n' and the numpad Enter the same // Treat '\n' and the numpad Enter the same
10 | 10 |
ncurses::KEY_ENTER => event::Key::Enter, ncurses::KEY_ENTER => Event::Key(Key::Enter),
// This is the escape key when pressed by itself. // This is the escape key when pressed by itself.
// When used for control sequences, it should have been caught earlier. // When used for control sequences, it should have been caught earlier.
27 => event::Key::Esc, 27 => Event::Key(Key::Esc),
// `Backspace` sends 127, but Ctrl-H sends `Backspace` // `Backspace` sends 127, but Ctrl-H sends `Backspace`
127 | 127 |
ncurses::KEY_BACKSPACE => event::Key::Backspace, ncurses::KEY_BACKSPACE => Event::Key(Key::Backspace),
410 => event::Key::Resize, 410 => Event::WindowResize,
// Values 512 and above are probably extensions // Values 512 and above are probably extensions
// Those keys don't seem to be documented... // Those keys don't seem to be documented...
519 => event::Key::AltDel, 519 => Event::Alt(Key::Del),
520 => event::Key::AltShiftDel, 520 => Event::AltShift(Key::Del),
521 => event::Key::CtrlDel, 521 => Event::Ctrl(Key::Del),
522 => event::Key::CtrlShiftDel, 522 => Event::CtrlShift(Key::Del),
// 523: CtrlAltDel? // 523: CtrlAltDel?
// //
// 524? // 524?
525 => event::Key::AltDown, 525 => Event::Alt(Key::Down),
526 => event::Key::AltShiftDown, 526 => Event::AltShift(Key::Down),
527 => event::Key::CtrlDown, 527 => Event::Ctrl(Key::Down),
528 => event::Key::CtrlShiftDown, 528 => Event::CtrlShift(Key::Down),
529 => event::Key::CtrlAltDown, 529 => Event::CtrlAlt(Key::Down),
530 => event::Key::AltEnd, 530 => Event::Alt(Key::End),
531 => event::Key::AltShiftEnd, 531 => Event::AltShift(Key::End),
532 => event::Key::CtrlEnd, 532 => Event::Ctrl(Key::End),
533 => event::Key::CtrlShiftEnd, 533 => Event::CtrlShift(Key::End),
534 => event::Key::CtrlAltEnd, 534 => Event::CtrlAlt(Key::End),
535 => event::Key::AltHome, 535 => Event::Alt(Key::Home),
536 => event::Key::AltShiftHome, 536 => Event::AltShift(Key::Home),
537 => event::Key::CtrlHome, 537 => Event::Ctrl(Key::Home),
538 => event::Key::CtrlShiftHome, 538 => Event::CtrlShift(Key::Home),
539 => event::Key::CtrlAltHome, 539 => Event::CtrlAlt(Key::Home),
540 => event::Key::AltIns, 540 => Event::Alt(Key::Ins),
// 541: AltShiftIns? // 541: AltShiftIns?
542 => event::Key::CtrlIns, 542 => Event::Ctrl(Key::Ins),
// 543: CtrlShiftIns? // 543: CtrlShiftIns?
544 => event::Key::CtrlAltIns, 544 => Event::CtrlAlt(Key::Ins),
545 => event::Key::AltLeft, 545 => Event::Alt(Key::Left),
546 => event::Key::AltShiftLeft, 546 => Event::AltShift(Key::Left),
547 => event::Key::CtrlLeft, 547 => Event::Ctrl(Key::Left),
548 => event::Key::CtrlShiftLeft, 548 => Event::CtrlShift(Key::Left),
549 => event::Key::CtrlAltLeft, 549 => Event::CtrlAlt(Key::Left),
550 => event::Key::AltPageDown, 550 => Event::Alt(Key::PageDown),
551 => event::Key::AltShiftPageDown, 551 => Event::AltShift(Key::PageDown),
552 => event::Key::CtrlPageDown, 552 => Event::Ctrl(Key::PageDown),
553 => event::Key::CtrlShiftPageDown, 553 => Event::CtrlShift(Key::PageDown),
554 => event::Key::CtrlAltPageDown, 554 => Event::CtrlAlt(Key::PageDown),
555 => event::Key::AltPageUp, 555 => Event::Alt(Key::PageUp),
556 => event::Key::AltShiftPageUp, 556 => Event::AltShift(Key::PageUp),
557 => event::Key::CtrlPageUp, 557 => Event::Ctrl(Key::PageUp),
558 => event::Key::CtrlShiftPageUp, 558 => Event::CtrlShift(Key::PageUp),
559 => event::Key::CtrlAltPageUp, 559 => Event::CtrlAlt(Key::PageUp),
560 => event::Key::AltRight, 560 => Event::Alt(Key::Right),
561 => event::Key::AltShiftRight, 561 => Event::AltShift(Key::Right),
562 => event::Key::CtrlRight, 562 => Event::Ctrl(Key::Right),
563 => event::Key::CtrlShiftRight, 563 => Event::CtrlShift(Key::Right),
564 => event::Key::CtrlAltRight, 564 => Event::CtrlAlt(Key::Right),
// 565? // 565?
566 => event::Key::AltUp, 566 => Event::Alt(Key::Up),
567 => event::Key::AltShiftUp, 567 => Event::AltShift(Key::Up),
568 => event::Key::CtrlUp, 568 => Event::Ctrl(Key::Up),
569 => event::Key::CtrlShiftUp, 569 => Event::CtrlShift(Key::Up),
570 => event::Key::CtrlAltUp, 570 => Event::CtrlAlt(Key::Up),
ncurses::KEY_B2 => event::Key::NumpadCenter, ncurses::KEY_B2 => Event::Key(Key::NumpadCenter),
ncurses::KEY_DC => event::Key::Del, ncurses::KEY_DC => Event::Key(Key::Del),
ncurses::KEY_IC => event::Key::Ins, ncurses::KEY_IC => Event::Key(Key::Ins),
ncurses::KEY_BTAB => event::Key::ShiftTab, ncurses::KEY_BTAB => Event::Shift(Key::Tab),
ncurses::KEY_SLEFT => event::Key::ShiftLeft, ncurses::KEY_SLEFT => Event::Shift(Key::Left),
ncurses::KEY_SRIGHT => event::Key::ShiftRight, ncurses::KEY_SRIGHT => Event::Shift(Key::Right),
ncurses::KEY_LEFT => event::Key::Left, ncurses::KEY_LEFT => Event::Key(Key::Left),
ncurses::KEY_RIGHT => event::Key::Right, ncurses::KEY_RIGHT => Event::Key(Key::Right),
ncurses::KEY_UP => event::Key::Up, ncurses::KEY_UP => Event::Key(Key::Up),
ncurses::KEY_DOWN => event::Key::Down, ncurses::KEY_DOWN => Event::Key(Key::Down),
ncurses::KEY_SR => event::Key::ShiftUp, ncurses::KEY_SR => Event::Shift(Key::Up),
ncurses::KEY_SF => event::Key::ShiftDown, ncurses::KEY_SF => Event::Shift(Key::Down),
ncurses::KEY_PPAGE => event::Key::PageUp, ncurses::KEY_PPAGE => Event::Key(Key::PageUp),
ncurses::KEY_NPAGE => event::Key::PageDown, ncurses::KEY_NPAGE => Event::Key(Key::PageDown),
ncurses::KEY_HOME => event::Key::Home, ncurses::KEY_HOME => Event::Key(Key::Home),
ncurses::KEY_END => event::Key::End, ncurses::KEY_END => Event::Key(Key::End),
ncurses::KEY_SHOME => event::Key::ShiftHome, ncurses::KEY_SHOME => Event::Shift(Key::Home),
ncurses::KEY_SEND => event::Key::ShiftEnd, ncurses::KEY_SEND => Event::Shift(Key::End),
ncurses::KEY_SDC => event::Key::ShiftDel, ncurses::KEY_SDC => Event::Shift(Key::Del),
ncurses::KEY_SNEXT => event::Key::ShiftPageDown, ncurses::KEY_SNEXT => Event::Shift(Key::PageDown),
ncurses::KEY_SPREVIOUS => event::Key::ShiftPageUp, ncurses::KEY_SPREVIOUS => Event::Shift(Key::PageUp),
// All Fn keys use the same enum with associated number // All Fn keys use the same enum with associated number
f @ ncurses::KEY_F1...ncurses::KEY_F12 => { f @ ncurses::KEY_F1...ncurses::KEY_F12 => {
event::Key::F((f - ncurses::KEY_F0) as u8) Event::Key(Key::from_f((f - ncurses::KEY_F0) as u8))
} }
f @ 277...288 => event::Key::ShiftF((f - 277) as u8), f @ 277...288 => Event::Shift(Key::from_f((f - 276) as u8)),
f @ 289...300 => event::Key::CtrlF((f - 289) as u8), f @ 289...300 => Event::Ctrl(Key::from_f((f - 288) as u8)),
f @ 301...312 => event::Key::CtrlShiftF((f - 300) as u8), f @ 301...312 => Event::CtrlShift(Key::from_f((f - 300) as u8)),
f @ 313...324 => event::Key::AltF((f - 313) as u8), f @ 313...324 => Event::Alt(Key::from_f((f - 312) as u8)),
// Shift and Ctrl F{1-4} need escape sequences... // Values 8-10 (H,I,J) are used by other commands, so we won't receive them.
// c @ 1...25 => {
// TODO: shift and ctrl Fn keys Event::CtrlChar((b'a' + (c - 1) as u8) as char)
// Avoids 8-10 (H,I,J), they are used by other commands.
c @ 1...7 | c @ 11...25 => {
event::Key::CtrlChar((b'a' + (c - 1) as u8) as char)
} }
_ => event::Key::Unknown(ch), _ => Event::Unknown(ch),
} }
} }

View File

@ -1,6 +1,5 @@
//! User-input events and their effects. //! User-input events and their effects.
use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use Cursive; use Cursive;
@ -24,250 +23,137 @@ impl EventResult {
} }
} }
/// Represents a key, or a combination of keys. /// A non-character key on the keyboard
#[derive(PartialEq,Eq,Clone,Copy,Hash)] #[derive(PartialEq,Eq,Clone,Copy,Hash,Debug)]
pub enum Key { pub enum Key {
/// Both Enter and numpad Enter /// Both Enter (or Return) and numpad Enter
Enter, Enter,
/// Tabulation key /// Tabulation key
Tab, Tab,
ShiftTab, /// Backspace key
Backspace, Backspace,
/// Escape key
/// Indicates the window was resized
///
/// (Not really a key)
Resize,
/// Escape key.
Esc, Esc,
/// Left arrow
Left,
/// Right arrow
Right,
/// Up arrow
Up,
/// Down arrow
Down,
/// Insert key
Ins,
/// Delete key
Del,
/// Home key
Home,
/// End key
End,
/// Page Up key
PageUp,
/// Page Down key
PageDown,
/// The 5 in the center of the keypad, when numlock is disabled. /// The 5 in the center of the keypad, when numlock is disabled.
NumpadCenter, NumpadCenter,
Left, /// F1 key
/// Left arrow while shift is pressed. F1,
ShiftLeft, /// F2 key
AltLeft, F2,
AltShiftLeft, /// F3 key
CtrlLeft, F3,
CtrlShiftLeft, /// F4 key
CtrlAltLeft, F4,
/// F5 key
Right, F5,
/// Right arrow while shift is pressed. /// F6 key
ShiftRight, F6,
AltRight, /// F7 key
AltShiftRight, F7,
CtrlRight, /// F8 key
CtrlShiftRight, F8,
CtrlAltRight, /// F9 key
F9,
Up, /// F10 key
ShiftUp, F10,
AltUp, /// F11 key
AltShiftUp, F11,
CtrlUp, /// F12 key
CtrlShiftUp, F12,
CtrlAltUp,
Down,
ShiftDown,
AltDown,
AltShiftDown,
CtrlDown,
CtrlShiftDown,
CtrlAltDown,
PageUp,
ShiftPageUp,
AltPageUp,
AltShiftPageUp,
CtrlPageUp,
CtrlShiftPageUp,
CtrlAltPageUp,
PageDown,
ShiftPageDown,
AltPageDown,
AltShiftPageDown,
CtrlPageDown,
CtrlShiftPageDown,
CtrlAltPageDown,
Home,
ShiftHome,
AltHome,
AltShiftHome,
CtrlHome,
CtrlShiftHome,
CtrlAltHome,
End,
ShiftEnd,
AltEnd,
AltShiftEnd,
CtrlEnd,
CtrlShiftEnd,
CtrlAltEnd,
/// Delete key
Del,
ShiftDel,
AltDel,
AltShiftDel,
CtrlDel,
CtrlShiftDel,
/// Insert key.
Ins,
/// Insert key while ctrl is pressed.
CtrlIns,
AltIns,
CtrlAltIns,
F(u8),
ShiftF(u8),
AltF(u8),
CtrlF(u8),
CtrlShiftF(u8),
CtrlChar(char),
Unknown(i32),
} }
impl fmt::Display for Key { impl Key {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { /// Returns the function key corresponding to the given number
match *self { ///
Key::Unknown(ch) => write!(f, "Unknown: {}", ch), /// 1 -> F1, etc...
Key::CtrlChar(ch) => write!(f, "Ctrl-{}", ch), ///
Key::F(n) => write!(f, "F{}", n), /// # Panics
Key::ShiftF(n) => write!(f, "Shift-F{}", n), ///
Key::AltF(n) => write!(f, "Alt-F{}", n), /// If `n == 0 || n > 12`
Key::CtrlF(n) => write!(f, "Ctrl-F{}", n), pub fn from_f(n: u8) -> Key {
Key::CtrlShiftF(n) => write!(f, "Ctrl-Shift-F{}", n), match n {
key => { 1 => Key::F1,
write!(f, 2 => Key::F2,
"{}", 3 => Key::F3,
match key { 4 => Key::F4,
Key::Resize => "Screen resize", 5 => Key::F5,
Key::NumpadCenter => "Numpad center", 6 => Key::F6,
Key::Backspace => "Backspace", 7 => Key::F7,
Key::Enter => "Enter", 8 => Key::F8,
Key::Tab => "Tab", 9 => Key::F9,
Key::ShiftTab => "Shift-Tab", 10 => Key::F10,
11 => Key::F11,
Key::PageUp => "PageUp", 12 => Key::F12,
Key::ShiftPageUp => "Shift-PageUp", _ => panic!("unknown function key: F{}", n),
Key::AltPageUp => "Alt-PageUp",
Key::AltShiftPageUp => "Alt-Shift-PageUp",
Key::CtrlPageUp => "Ctrl-PageUp",
Key::CtrlShiftPageUp => "Ctrl-Shift-PageUp",
Key::CtrlAltPageUp => "Ctrl-Alt-PageUp",
Key::PageDown => "PageDown",
Key::ShiftPageDown => "Shift-PageDown",
Key::AltPageDown => "Alt-PageDown",
Key::AltShiftPageDown => "Alt-Shift-PageDown",
Key::CtrlPageDown => "Ctrl-PageDown",
Key::CtrlShiftPageDown => "Ctrl-Shift-PageDown",
Key::CtrlAltPageDown => "Ctrl-Alt-PageDown",
Key::Left => "Left",
Key::ShiftLeft => "Shift-Left",
Key::AltLeft => "Alt-Left",
Key::AltShiftLeft => "Alt-Shift-Left",
Key::CtrlLeft => "Ctrl-Left",
Key::CtrlShiftLeft => "Ctrl-Shift-Left",
Key::CtrlAltLeft => "Ctrl-Alt-Left",
Key::Right => "Right",
Key::ShiftRight => "Shift-Right",
Key::AltRight => "Alt-Right",
Key::AltShiftRight => "Alt-Shift-Right",
Key::CtrlRight => "Ctrl-Right",
Key::CtrlShiftRight => "Ctrl-Shift-Right",
Key::CtrlAltRight => "Ctrl-Alt-Right",
Key::Down => "Down",
Key::ShiftDown => "Shift-Down",
Key::AltDown => "Alt-Down",
Key::AltShiftDown => "Alt-Shift-Down",
Key::CtrlDown => "Ctrl-Down",
Key::CtrlShiftDown => "Ctrl-Shift-Down",
Key::CtrlAltDown => "Ctrl-Alt-Down",
Key::Up => "Up",
Key::ShiftUp => "Shift-Up",
Key::AltUp => "Alt-Up",
Key::AltShiftUp => "Alt-Shift-Up",
Key::CtrlUp => "Ctrl-Up",
Key::CtrlShiftUp => "Ctrl-Shift-Up",
Key::CtrlAltUp => "Ctrl-Alt-Up",
Key::Del => "Del",
Key::ShiftDel => "Shift-Del",
Key::AltDel => "Alt-Del",
Key::AltShiftDel => "Alt-Shift-Del",
Key::CtrlDel => "Ctrl-Del",
Key::CtrlShiftDel => "Ctrl-Shift-Del",
Key::Home => "Home",
Key::ShiftHome => "Shift-Home",
Key::AltHome => "Alt-Home",
Key::AltShiftHome => "Alt-Shift-Home",
Key::CtrlHome => "Ctrl-Home",
Key::CtrlShiftHome => "Ctrl-Shift-Home",
Key::CtrlAltHome => "Ctrl-Alt-Home",
Key::End => "End",
Key::ShiftEnd => "Shift-End",
Key::AltEnd => "Alt-End",
Key::AltShiftEnd => "Alt-Shift-End",
Key::CtrlEnd => "Ctrl-End",
Key::CtrlShiftEnd => "Ctrl-Shift-End",
Key::CtrlAltEnd => "Ctrl-Alt-End",
Key::Ins => "Ins",
Key::AltIns => "Alt-Ins",
Key::CtrlIns => "Ctrl-Ins",
Key::CtrlAltIns => "Ctrl-Alt-Ins",
Key::Esc => "Esc",
_ => "Missing key label",
})
}
} }
} }
} }
/// Represents an event as seen by the application. /// Represents an event as seen by the application.
/// #[derive(PartialEq,Eq,Clone,Copy,Hash,Debug)]
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
pub enum Event { pub enum Event {
/// A text character was entered. /// Event fired when the window is resized
WindowResize,
/// A character was entered (includes numbers, punctuation, ...)
Char(char), Char(char),
/// A key was pressed. /// A character was entered with the Ctrl key pressed
CtrlChar(char),
/// A character was entered with the Alt key pressed
AltChar(char),
/// A non-character key was pressed
Key(Key), Key(Key),
/// A non-character key was pressed with the Shift key pressed
Shift(Key),
/// A non-character key was pressed with the Alt key pressed
Alt(Key),
/// A non-character key was pressed with the Shift and Alt keys pressed
AltShift(Key),
/// A non-character key was pressed with the Ctrl key pressed
Ctrl(Key),
/// A non-character key was pressed with the Ctrl and Shift keys pressed
CtrlShift(Key),
/// A non-character key was pressed with the Ctrl and Alt keys pressed
CtrlAlt(Key),
/// An unknown event was received.
Unknown(i32),
} }
/// Generic trait to convert a value to an event. impl From<char> for Event {
pub trait ToEvent { fn from(c: char) -> Event {
fn to_event(self) -> Event; Event::Char(c)
}
impl ToEvent for char {
fn to_event(self) -> Event {
Event::Char(self)
} }
} }
impl ToEvent for Key { impl From<Key> for Event {
fn to_event(self) -> Event { fn from(k: Key) -> Event {
Event::Key(self) Event::Key(k)
}
}
impl ToEvent for Event {
fn to_event(self) -> Event {
self
} }
} }

View File

@ -65,7 +65,7 @@ use printer::Printer;
use view::View; use view::View;
use view::{Selector, StackView}; use view::{Selector, StackView};
use event::{Callback, Event, EventResult, ToEvent}; use event::{Callback, Event, EventResult};
/// Identifies a screen in the cursive ROOT. /// Identifies a screen in the cursive ROOT.
pub type ScreenId = usize; pub type ScreenId = usize;
@ -218,10 +218,10 @@ impl Cursive {
/// Adds a global callback. /// Adds a global callback.
/// ///
/// Will be triggered on the given key press when no view catches it. /// Will be triggered on the given key press when no view catches it.
pub fn add_global_callback<F, E: ToEvent>(&mut self, event: E, cb: F) pub fn add_global_callback<F, E: Into<Event>>(&mut self, event: E, cb: F)
where F: Fn(&mut Cursive) + 'static where F: Fn(&mut Cursive) + 'static
{ {
self.global_callbacks.insert(event.to_event(), Rc::new(cb)); self.global_callbacks.insert(event.into(), Rc::new(cb));
} }
/// Convenient method to add a layer to the current screen. /// Convenient method to add a layer to the current screen.
@ -310,9 +310,8 @@ impl Cursive {
// Wait for next event. // Wait for next event.
// (If set_fps was called, this returns -1 now and then) // (If set_fps was called, this returns -1 now and then)
let event = B::poll_event(); let event = B::poll_event();
if event == Event::Key(event::Key::Resize) { if event == Event::WindowResize {
B::clear(); B::clear();
continue;
} }
// Event dispatch order: // Event dispatch order:

View File

@ -226,7 +226,7 @@ impl View for Dialog {
match event { match event {
Event::Key(Key::Down) | Event::Key(Key::Down) |
Event::Key(Key::Tab) | Event::Key(Key::Tab) |
Event::Key(Key::ShiftTab) => { Event::Shift(Key::Tab) => {
// Default to leftmost button when going down. // Default to leftmost button when going down.
self.focus = Focus::Button(0); self.focus = Focus::Button(0);
EventResult::Consumed(None) EventResult::Consumed(None)
@ -245,7 +245,7 @@ impl View for Dialog {
// Up goes back to the content // Up goes back to the content
Event::Key(Key::Up) | Event::Key(Key::Up) |
Event::Key(Key::Tab) | Event::Key(Key::Tab) |
Event::Key(Key::ShiftTab) => { Event::Shift(Key::Tab) => {
if self.content.take_focus() { if self.content.take_focus() {
self.focus = Focus::Content; self.focus = Focus::Content;
EventResult::Consumed(None) EventResult::Consumed(None)

View File

@ -155,44 +155,40 @@ impl View for EditView {
// Find the byte index of the char at self.cursor // Find the byte index of the char at self.cursor
self.content.insert(self.cursor, ch); self.content.insert(self.cursor, ch);
// TODO: handle wide (CJK) chars
self.cursor += ch.len_utf8(); self.cursor += ch.len_utf8();
} }
Event::Key(key) => { // TODO: handle ctrl-key?
match key { Event::Key(Key::Home) => self.cursor = 0,
Key::Home => self.cursor = 0, Event::Key(Key::End) => self.cursor = self.content.len(),
Key::End => self.cursor = self.content.len(), Event::Key(Key::Left) if self.cursor > 0 => {
Key::Left if self.cursor > 0 => { let len = self.content[..self.cursor]
let len = self.content[..self.cursor] .graphemes(true)
.graphemes(true) .last()
.last() .unwrap()
.unwrap() .len();
.len(); self.cursor -= len;
self.cursor -= len;
}
Key::Right if self.cursor < self.content.len() => {
let len = self.content[self.cursor..]
.graphemes(true)
.next()
.unwrap()
.len();
self.cursor += len;
}
Key::Backspace if self.cursor > 0 => {
let len = self.content[..self.cursor]
.graphemes(true)
.last()
.unwrap()
.len();
self.cursor -= len;
self.content.remove(self.cursor);
}
Key::Del if self.cursor < self.content.len() => {
self.content.remove(self.cursor);
}
_ => return EventResult::Ignored,
}
} }
Event::Key(Key::Right) if self.cursor < self.content.len() => {
let len = self.content[self.cursor..]
.graphemes(true)
.next()
.unwrap()
.len();
self.cursor += len;
}
Event::Key(Key::Backspace) if self.cursor > 0 => {
let len = self.content[..self.cursor]
.graphemes(true)
.last()
.unwrap()
.len();
self.cursor -= len;
self.content.remove(self.cursor);
}
Event::Key(Key::Del) if self.cursor < self.content.len() => {
self.content.remove(self.cursor);
}
_ => return EventResult::Ignored,
} }
// Keep cursor in [offset, offset+last_length] by changing offset // Keep cursor in [offset, offset+last_length] by changing offset

View File

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use Cursive; use Cursive;
use event::{Callback, Event, EventResult, ToEvent}; use event::{Callback, Event, EventResult};
use super::{View, ViewWrapper}; use super::{View, ViewWrapper};
/// A simple wrapper view that catches some ignored event from its child. /// A simple wrapper view that catches some ignored event from its child.
@ -23,10 +23,10 @@ impl KeyEventView {
} }
/// Registers a callback when the given key is ignored by the child. /// Registers a callback when the given key is ignored by the child.
pub fn register<F, E: ToEvent>(mut self, event: E, cb: F) -> Self pub fn register<F, E: Into<Event>>(mut self, event: E, cb: F) -> Self
where F: Fn(&mut Cursive) + 'static where F: Fn(&mut Cursive) + 'static
{ {
self.callbacks.insert(event.to_event(), Rc::new(cb)); self.callbacks.insert(event.into(), Rc::new(cb));
self self
} }

View File

@ -207,7 +207,7 @@ impl View for LinearLayout {
self.focus -= 1; self.focus -= 1;
EventResult::Consumed(None) EventResult::Consumed(None)
} }
Event::Key(Key::ShiftTab) if self.focus + 1 < Event::Shift(Key::Tab) if self.focus + 1 <
self.children.len() => { self.children.len() => {
self.focus += 1; self.focus += 1;
EventResult::Consumed(None) EventResult::Consumed(None)