2018-04-03 01:08:12 +00:00
|
|
|
//! Backend using BearLibTerminal
|
|
|
|
//!
|
|
|
|
//! Requires the `blt-backend` feature.
|
|
|
|
#![cfg(feature = "bear-lib-terminal")]
|
|
|
|
|
2019-02-28 23:55:02 +00:00
|
|
|
use bear_lib_terminal;
|
2016-10-11 23:23:08 +00:00
|
|
|
|
2018-07-08 19:48:37 +00:00
|
|
|
use std::collections::HashSet;
|
|
|
|
|
2016-10-12 07:47:20 +00:00
|
|
|
use self::bear_lib_terminal::geometry::Size;
|
2018-06-11 06:29:10 +00:00
|
|
|
use self::bear_lib_terminal::terminal::{
|
|
|
|
self, state, Event as BltEvent, KeyCode,
|
|
|
|
};
|
|
|
|
use self::bear_lib_terminal::Color as BltColor;
|
2018-07-08 19:48:37 +00:00
|
|
|
|
2019-02-28 23:54:12 +00:00
|
|
|
use crate::backend;
|
|
|
|
use crate::event::{Event, Key, MouseButton, MouseEvent};
|
|
|
|
use crate::theme::{BaseColor, Color, ColorPair, Effect};
|
|
|
|
use crate::vec::Vec2;
|
2016-10-11 23:23:08 +00:00
|
|
|
|
2017-07-16 13:05:04 +00:00
|
|
|
enum ColorRole {
|
|
|
|
Foreground,
|
|
|
|
Background,
|
|
|
|
}
|
|
|
|
|
2018-11-09 18:40:06 +00:00
|
|
|
/// Backend using BearLibTerminal
|
2018-04-01 23:39:03 +00:00
|
|
|
pub struct Backend {
|
2018-05-20 16:59:35 +00:00
|
|
|
buttons_pressed: HashSet<MouseButton>,
|
|
|
|
mouse_position: Vec2,
|
|
|
|
}
|
2018-04-01 23:39:03 +00:00
|
|
|
|
2018-05-20 17:42:52 +00:00
|
|
|
impl Backend {
|
2018-11-09 18:40:06 +00:00
|
|
|
/// Creates a new BearLibTerminal-based backend.
|
2019-02-28 23:55:02 +00:00
|
|
|
pub fn init() -> Box<dyn backend::Backend> {
|
2019-03-04 03:24:39 +00:00
|
|
|
// TODO: Add some error handling?
|
2018-05-20 17:42:52 +00:00
|
|
|
terminal::open("Cursive", 80, 24);
|
|
|
|
terminal::set(terminal::config::Window::empty().resizeable(true));
|
|
|
|
terminal::set(vec![
|
|
|
|
terminal::config::InputFilter::Group {
|
|
|
|
group: terminal::config::InputFilterGroup::Keyboard,
|
|
|
|
both: false,
|
|
|
|
},
|
|
|
|
terminal::config::InputFilter::Group {
|
|
|
|
group: terminal::config::InputFilterGroup::Mouse,
|
|
|
|
both: true,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
let c = Backend {
|
2018-04-01 23:39:03 +00:00
|
|
|
buttons_pressed: HashSet::new(),
|
2018-05-20 16:59:35 +00:00
|
|
|
mouse_position: Vec2::zero(),
|
2018-05-20 17:42:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Box::new(c)
|
2018-05-20 16:59:35 +00:00
|
|
|
}
|
2018-04-01 23:39:03 +00:00
|
|
|
|
2018-05-20 17:42:52 +00:00
|
|
|
fn parse_next(&mut self) -> Option<Event> {
|
2018-05-20 16:59:35 +00:00
|
|
|
// TODO: we could add backend-specific controls here.
|
|
|
|
// Ex: ctrl+mouse wheel cause window cellsize to change
|
2018-05-20 17:42:52 +00:00
|
|
|
terminal::read_event().map(|ev| {
|
2018-05-20 16:59:35 +00:00
|
|
|
match ev {
|
|
|
|
BltEvent::Close => Event::Exit,
|
|
|
|
BltEvent::Resize { .. } => Event::WindowResize,
|
|
|
|
// TODO: mouse support
|
|
|
|
BltEvent::MouseMove { x, y } => {
|
|
|
|
self.mouse_position = Vec2::new(x as usize, y as usize);
|
|
|
|
// TODO: find out if a button is pressed?
|
|
|
|
match self.buttons_pressed.iter().next() {
|
|
|
|
None => Event::Refresh,
|
|
|
|
Some(btn) => Event::Mouse {
|
|
|
|
event: MouseEvent::Hold(*btn),
|
|
|
|
position: self.mouse_position,
|
|
|
|
offset: Vec2::zero(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BltEvent::MouseScroll { delta } => Event::Mouse {
|
|
|
|
event: if delta < 0 {
|
|
|
|
MouseEvent::WheelUp
|
|
|
|
} else {
|
|
|
|
MouseEvent::WheelDown
|
|
|
|
},
|
|
|
|
position: self.mouse_position,
|
|
|
|
offset: Vec2::zero(),
|
|
|
|
},
|
|
|
|
BltEvent::KeyPressed { key, ctrl, shift } => {
|
|
|
|
self.blt_keycode_to_ev(key, shift, ctrl)
|
|
|
|
}
|
|
|
|
// TODO: there's no Key::Shift/Ctrl for w/e reason
|
|
|
|
BltEvent::ShiftPressed => Event::Refresh,
|
|
|
|
BltEvent::ControlPressed => Event::Refresh,
|
|
|
|
// TODO: what should we do here?
|
|
|
|
BltEvent::KeyReleased { key, .. } => {
|
|
|
|
// It's probably a mouse key.
|
|
|
|
blt_keycode_to_mouse_button(key)
|
|
|
|
.map(|btn| {
|
|
|
|
self.buttons_pressed.remove(&btn);
|
|
|
|
Event::Mouse {
|
|
|
|
event: MouseEvent::Release(btn),
|
|
|
|
position: self.mouse_position,
|
|
|
|
offset: Vec2::zero(),
|
|
|
|
}
|
2018-11-05 19:03:52 +00:00
|
|
|
})
|
|
|
|
.unwrap_or(Event::Unknown(vec![]))
|
2018-05-20 16:59:35 +00:00
|
|
|
}
|
|
|
|
BltEvent::ShiftReleased | BltEvent::ControlReleased => {
|
|
|
|
Event::Refresh
|
|
|
|
}
|
2018-11-05 19:03:52 +00:00
|
|
|
_ => Event::Unknown(vec![]),
|
2018-05-20 16:59:35 +00:00
|
|
|
}
|
2018-05-20 17:42:52 +00:00
|
|
|
})
|
2018-04-01 23:39:03 +00:00
|
|
|
}
|
|
|
|
|
2017-10-13 07:20:27 +00:00
|
|
|
fn blt_keycode_to_ev(
|
2018-06-11 06:29:10 +00:00
|
|
|
&mut self, kc: KeyCode, shift: bool, ctrl: bool,
|
2017-10-13 07:20:27 +00:00
|
|
|
) -> Event {
|
|
|
|
match kc {
|
2017-12-30 22:03:42 +00:00
|
|
|
KeyCode::F1
|
|
|
|
| KeyCode::F2
|
|
|
|
| KeyCode::F3
|
|
|
|
| KeyCode::F4
|
|
|
|
| KeyCode::F5
|
|
|
|
| KeyCode::F6
|
|
|
|
| KeyCode::F7
|
|
|
|
| KeyCode::F8
|
|
|
|
| KeyCode::F9
|
|
|
|
| KeyCode::F10
|
|
|
|
| KeyCode::F11
|
|
|
|
| KeyCode::F12
|
|
|
|
| KeyCode::NumEnter
|
|
|
|
| KeyCode::Enter
|
|
|
|
| KeyCode::Escape
|
|
|
|
| KeyCode::Backspace
|
|
|
|
| KeyCode::Tab
|
|
|
|
| KeyCode::Pause
|
|
|
|
| KeyCode::Insert
|
|
|
|
| KeyCode::Home
|
|
|
|
| KeyCode::PageUp
|
|
|
|
| KeyCode::Delete
|
|
|
|
| KeyCode::End
|
|
|
|
| KeyCode::PageDown
|
|
|
|
| KeyCode::Right
|
|
|
|
| KeyCode::Left
|
|
|
|
| KeyCode::Down
|
|
|
|
| KeyCode::Up => match (shift, ctrl) {
|
2017-10-13 07:20:27 +00:00
|
|
|
(true, true) => Event::CtrlShift(blt_keycode_to_key(kc)),
|
|
|
|
(true, false) => Event::Shift(blt_keycode_to_key(kc)),
|
|
|
|
(false, true) => Event::Ctrl(blt_keycode_to_key(kc)),
|
|
|
|
(false, false) => Event::Key(blt_keycode_to_key(kc)),
|
|
|
|
},
|
|
|
|
// TODO: mouse support
|
2017-12-30 22:03:42 +00:00
|
|
|
KeyCode::MouseLeft
|
|
|
|
| KeyCode::MouseRight
|
|
|
|
| KeyCode::MouseMiddle
|
|
|
|
| KeyCode::MouseFourth
|
|
|
|
| KeyCode::MouseFifth => blt_keycode_to_mouse_button(kc)
|
2017-10-13 07:20:27 +00:00
|
|
|
.map(|btn| {
|
|
|
|
self.buttons_pressed.insert(btn);
|
|
|
|
Event::Mouse {
|
|
|
|
event: MouseEvent::Press(btn),
|
|
|
|
position: self.mouse_position,
|
|
|
|
offset: Vec2::zero(),
|
|
|
|
}
|
2018-11-05 19:03:52 +00:00
|
|
|
})
|
|
|
|
.unwrap_or(Event::Unknown(vec![])),
|
2017-12-30 22:03:42 +00:00
|
|
|
KeyCode::A
|
|
|
|
| KeyCode::B
|
|
|
|
| KeyCode::C
|
|
|
|
| KeyCode::D
|
|
|
|
| KeyCode::E
|
|
|
|
| KeyCode::F
|
|
|
|
| KeyCode::G
|
|
|
|
| KeyCode::H
|
|
|
|
| KeyCode::I
|
|
|
|
| KeyCode::J
|
|
|
|
| KeyCode::K
|
|
|
|
| KeyCode::L
|
|
|
|
| KeyCode::M
|
|
|
|
| KeyCode::N
|
|
|
|
| KeyCode::O
|
|
|
|
| KeyCode::P
|
|
|
|
| KeyCode::Q
|
|
|
|
| KeyCode::R
|
|
|
|
| KeyCode::S
|
|
|
|
| KeyCode::T
|
|
|
|
| KeyCode::U
|
|
|
|
| KeyCode::V
|
|
|
|
| KeyCode::W
|
|
|
|
| KeyCode::X
|
|
|
|
| KeyCode::Y
|
|
|
|
| KeyCode::Z
|
|
|
|
| KeyCode::Row1
|
|
|
|
| KeyCode::Row2
|
|
|
|
| KeyCode::Row3
|
|
|
|
| KeyCode::Row4
|
|
|
|
| KeyCode::Row5
|
|
|
|
| KeyCode::Row6
|
|
|
|
| KeyCode::Row7
|
|
|
|
| KeyCode::Row8
|
|
|
|
| KeyCode::Row9
|
|
|
|
| KeyCode::Row0
|
|
|
|
| KeyCode::Grave
|
|
|
|
| KeyCode::Minus
|
|
|
|
| KeyCode::Equals
|
|
|
|
| KeyCode::LeftBracket
|
|
|
|
| KeyCode::RightBracket
|
|
|
|
| KeyCode::Backslash
|
|
|
|
| KeyCode::Semicolon
|
|
|
|
| KeyCode::Apostrophe
|
|
|
|
| KeyCode::Comma
|
|
|
|
| KeyCode::Period
|
|
|
|
| KeyCode::Slash
|
|
|
|
| KeyCode::Space
|
|
|
|
| KeyCode::NumDivide
|
|
|
|
| KeyCode::NumMultiply
|
|
|
|
| KeyCode::NumMinus
|
|
|
|
| KeyCode::NumPlus
|
|
|
|
| KeyCode::NumPeriod
|
|
|
|
| KeyCode::Num1
|
|
|
|
| KeyCode::Num2
|
|
|
|
| KeyCode::Num3
|
|
|
|
| KeyCode::Num4
|
|
|
|
| KeyCode::Num5
|
|
|
|
| KeyCode::Num6
|
|
|
|
| KeyCode::Num7
|
|
|
|
| KeyCode::Num8
|
|
|
|
| KeyCode::Num9
|
2018-11-05 19:03:52 +00:00
|
|
|
| KeyCode::Num0 => {
|
|
|
|
if ctrl {
|
|
|
|
Event::CtrlChar(blt_keycode_to_char(kc, shift))
|
|
|
|
} else {
|
|
|
|
Event::Char(blt_keycode_to_char(kc, shift))
|
|
|
|
}
|
|
|
|
}
|
2017-10-13 07:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-11 23:23:08 +00:00
|
|
|
|
2018-04-01 23:39:03 +00:00
|
|
|
impl backend::Backend for Backend {
|
2016-10-11 23:23:08 +00:00
|
|
|
fn finish(&mut self) {
|
|
|
|
terminal::close();
|
|
|
|
}
|
|
|
|
|
2018-04-01 22:35:37 +00:00
|
|
|
fn set_color(&self, color: ColorPair) -> ColorPair {
|
|
|
|
let current = ColorPair {
|
|
|
|
front: blt_colour_to_colour(state::foreground()),
|
2018-06-11 06:29:10 +00:00
|
|
|
back: blt_colour_to_colour(state::background()),
|
2018-04-01 22:35:37 +00:00
|
|
|
};
|
2018-06-11 06:29:10 +00:00
|
|
|
|
2017-07-16 13:05:04 +00:00
|
|
|
let fg = colour_to_blt_colour(color.front, ColorRole::Foreground);
|
|
|
|
let bg = colour_to_blt_colour(color.back, ColorRole::Background);
|
2018-06-11 06:29:10 +00:00
|
|
|
|
2018-04-01 22:35:37 +00:00
|
|
|
terminal::set_colors(fg, bg);
|
|
|
|
|
|
|
|
current
|
2016-10-11 23:23:08 +00:00
|
|
|
}
|
|
|
|
|
2018-04-01 22:35:37 +00:00
|
|
|
fn set_effect(&self, effect: Effect) {
|
2016-10-11 23:23:08 +00:00
|
|
|
match effect {
|
2018-01-05 12:57:39 +00:00
|
|
|
// TODO: does BLT support bold/italic/underline?
|
2018-01-09 14:17:49 +00:00
|
|
|
Effect::Bold
|
|
|
|
| Effect::Italic
|
|
|
|
| Effect::Underline
|
2018-06-11 06:29:10 +00:00
|
|
|
| Effect::Simple => {}
|
2016-10-11 23:23:08 +00:00
|
|
|
// TODO: how to do this correctly?`
|
|
|
|
// BLT itself doesn't do this kind of thing,
|
|
|
|
// we'd need the colours in our position,
|
|
|
|
// but `f()` can do whatever
|
2018-06-11 06:29:10 +00:00
|
|
|
Effect::Reverse => {
|
|
|
|
terminal::set_colors(state::background(), state::foreground())
|
|
|
|
}
|
2018-04-01 22:35:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn unset_effect(&self, effect: Effect) {
|
|
|
|
match effect {
|
|
|
|
// TODO: does BLT support bold/italic/underline?
|
|
|
|
Effect::Bold
|
|
|
|
| Effect::Italic
|
|
|
|
| Effect::Underline
|
2018-06-11 06:29:10 +00:00
|
|
|
| Effect::Simple => {}
|
2018-04-01 22:35:37 +00:00
|
|
|
// The process of reversing is the same as unreversing
|
2018-06-11 06:29:10 +00:00
|
|
|
Effect::Reverse => {
|
|
|
|
terminal::set_colors(state::background(), state::foreground())
|
|
|
|
}
|
2016-10-11 23:23:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn has_colors(&self) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2018-04-03 01:08:12 +00:00
|
|
|
fn screen_size(&self) -> Vec2 {
|
2016-10-11 23:23:08 +00:00
|
|
|
let Size { width, height } = terminal::state::size();
|
2018-04-03 01:08:12 +00:00
|
|
|
(width, height).into()
|
2016-10-11 23:23:08 +00:00
|
|
|
}
|
|
|
|
|
2017-06-13 06:29:26 +00:00
|
|
|
fn clear(&self, color: Color) {
|
2017-12-30 22:03:42 +00:00
|
|
|
terminal::set_background(colour_to_blt_colour(
|
|
|
|
color,
|
|
|
|
ColorRole::Background,
|
|
|
|
));
|
2016-10-11 23:23:08 +00:00
|
|
|
terminal::clear(None);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn refresh(&mut self) {
|
|
|
|
terminal::refresh();
|
|
|
|
}
|
|
|
|
|
2018-04-03 01:08:12 +00:00
|
|
|
fn print_at(&self, pos: Vec2, text: &str) {
|
|
|
|
terminal::print_xy(pos.x as i32, pos.y as i32, text);
|
2016-10-11 23:23:08 +00:00
|
|
|
}
|
|
|
|
|
2019-02-28 01:07:55 +00:00
|
|
|
fn poll_event(&mut self) -> Option<Event> {
|
|
|
|
self.parse_next()
|
2016-10-11 23:23:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-01 22:35:37 +00:00
|
|
|
fn blt_colour_to_colour(c: BltColor) -> Color {
|
|
|
|
Color::Rgb(c.red, c.green, c.blue)
|
|
|
|
}
|
|
|
|
|
2017-07-16 13:05:04 +00:00
|
|
|
fn colour_to_blt_colour(clr: Color, role: ColorRole) -> BltColor {
|
2017-06-13 06:29:26 +00:00
|
|
|
let (r, g, b) = match clr {
|
2017-07-17 23:36:34 +00:00
|
|
|
Color::TerminalDefault => {
|
2017-07-16 13:05:04 +00:00
|
|
|
let clr = match role {
|
|
|
|
ColorRole::Foreground => state::foreground(),
|
|
|
|
ColorRole::Background => state::background(),
|
|
|
|
};
|
|
|
|
|
|
|
|
return clr;
|
2017-07-17 23:36:34 +00:00
|
|
|
}
|
2017-07-16 13:05:04 +00:00
|
|
|
|
2016-10-11 23:23:08 +00:00
|
|
|
// Colours taken from
|
|
|
|
// https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
|
|
|
Color::Dark(BaseColor::Black) => (0, 0, 0),
|
|
|
|
Color::Dark(BaseColor::Red) => (170, 0, 0),
|
|
|
|
Color::Dark(BaseColor::Green) => (0, 170, 0),
|
|
|
|
Color::Dark(BaseColor::Yellow) => (170, 85, 0),
|
|
|
|
Color::Dark(BaseColor::Blue) => (0, 0, 170),
|
|
|
|
Color::Dark(BaseColor::Magenta) => (170, 0, 170),
|
|
|
|
Color::Dark(BaseColor::Cyan) => (0, 170, 170),
|
|
|
|
Color::Dark(BaseColor::White) => (170, 170, 170),
|
|
|
|
|
|
|
|
Color::Light(BaseColor::Black) => (85, 85, 85),
|
|
|
|
Color::Light(BaseColor::Red) => (255, 85, 85),
|
|
|
|
Color::Light(BaseColor::Green) => (85, 255, 85),
|
|
|
|
Color::Light(BaseColor::Yellow) => (255, 255, 85),
|
|
|
|
Color::Light(BaseColor::Blue) => (85, 85, 255),
|
|
|
|
Color::Light(BaseColor::Magenta) => (255, 85, 255),
|
|
|
|
Color::Light(BaseColor::Cyan) => (85, 255, 255),
|
|
|
|
Color::Light(BaseColor::White) => (255, 255, 255),
|
|
|
|
|
|
|
|
Color::Rgb(r, g, b) => (r, g, b),
|
2017-10-12 23:38:55 +00:00
|
|
|
Color::RgbLowRes(r, g, b) => (
|
|
|
|
(r as f32 / 5.0 * 255.0) as u8,
|
|
|
|
(g as f32 / 5.0 * 255.0) as u8,
|
|
|
|
(b as f32 / 5.0 * 255.0) as u8,
|
|
|
|
),
|
2016-10-11 23:23:08 +00:00
|
|
|
};
|
|
|
|
BltColor::from_rgb(r, g, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn blt_keycode_to_char(kc: KeyCode, shift: bool) -> char {
|
|
|
|
match kc {
|
2018-11-05 19:03:52 +00:00
|
|
|
KeyCode::A => {
|
|
|
|
if shift {
|
|
|
|
'A'
|
|
|
|
} else {
|
|
|
|
'a'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::B => {
|
|
|
|
if shift {
|
|
|
|
'B'
|
|
|
|
} else {
|
|
|
|
'b'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::C => {
|
|
|
|
if shift {
|
|
|
|
'C'
|
|
|
|
} else {
|
|
|
|
'c'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::D => {
|
|
|
|
if shift {
|
|
|
|
'D'
|
|
|
|
} else {
|
|
|
|
'd'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::E => {
|
|
|
|
if shift {
|
|
|
|
'E'
|
|
|
|
} else {
|
|
|
|
'e'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::F => {
|
|
|
|
if shift {
|
|
|
|
'F'
|
|
|
|
} else {
|
|
|
|
'f'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::G => {
|
|
|
|
if shift {
|
|
|
|
'G'
|
|
|
|
} else {
|
|
|
|
'g'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::H => {
|
|
|
|
if shift {
|
|
|
|
'H'
|
|
|
|
} else {
|
|
|
|
'h'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::I => {
|
|
|
|
if shift {
|
|
|
|
'I'
|
|
|
|
} else {
|
|
|
|
'i'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::J => {
|
|
|
|
if shift {
|
|
|
|
'J'
|
|
|
|
} else {
|
|
|
|
'j'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::K => {
|
|
|
|
if shift {
|
|
|
|
'K'
|
|
|
|
} else {
|
|
|
|
'k'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::L => {
|
|
|
|
if shift {
|
|
|
|
'L'
|
|
|
|
} else {
|
|
|
|
'l'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::M => {
|
|
|
|
if shift {
|
|
|
|
'M'
|
|
|
|
} else {
|
|
|
|
'm'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::N => {
|
|
|
|
if shift {
|
|
|
|
'N'
|
|
|
|
} else {
|
|
|
|
'n'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::O => {
|
|
|
|
if shift {
|
|
|
|
'O'
|
|
|
|
} else {
|
|
|
|
'o'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::P => {
|
|
|
|
if shift {
|
|
|
|
'P'
|
|
|
|
} else {
|
|
|
|
'p'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Q => {
|
|
|
|
if shift {
|
|
|
|
'Q'
|
|
|
|
} else {
|
|
|
|
'q'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::R => {
|
|
|
|
if shift {
|
|
|
|
'R'
|
|
|
|
} else {
|
|
|
|
'r'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::S => {
|
|
|
|
if shift {
|
|
|
|
'S'
|
|
|
|
} else {
|
|
|
|
's'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::T => {
|
|
|
|
if shift {
|
|
|
|
'T'
|
|
|
|
} else {
|
|
|
|
't'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::U => {
|
|
|
|
if shift {
|
|
|
|
'U'
|
|
|
|
} else {
|
|
|
|
'u'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::V => {
|
|
|
|
if shift {
|
|
|
|
'V'
|
|
|
|
} else {
|
|
|
|
'v'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::W => {
|
|
|
|
if shift {
|
|
|
|
'W'
|
|
|
|
} else {
|
|
|
|
'w'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::X => {
|
|
|
|
if shift {
|
|
|
|
'X'
|
|
|
|
} else {
|
|
|
|
'x'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Y => {
|
|
|
|
if shift {
|
|
|
|
'Y'
|
|
|
|
} else {
|
|
|
|
'y'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Z => {
|
|
|
|
if shift {
|
|
|
|
'Z'
|
|
|
|
} else {
|
|
|
|
'z'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row1 => {
|
|
|
|
if shift {
|
|
|
|
'!'
|
|
|
|
} else {
|
|
|
|
'1'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row2 => {
|
|
|
|
if shift {
|
|
|
|
'@'
|
|
|
|
} else {
|
|
|
|
'2'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row3 => {
|
|
|
|
if shift {
|
|
|
|
'#'
|
|
|
|
} else {
|
|
|
|
'3'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row4 => {
|
|
|
|
if shift {
|
|
|
|
'$'
|
|
|
|
} else {
|
|
|
|
'4'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row5 => {
|
|
|
|
if shift {
|
|
|
|
'%'
|
|
|
|
} else {
|
|
|
|
'5'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row6 => {
|
|
|
|
if shift {
|
|
|
|
'^'
|
|
|
|
} else {
|
|
|
|
'6'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row7 => {
|
|
|
|
if shift {
|
|
|
|
'&'
|
|
|
|
} else {
|
|
|
|
'7'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row8 => {
|
|
|
|
if shift {
|
|
|
|
'*'
|
|
|
|
} else {
|
|
|
|
'8'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row9 => {
|
|
|
|
if shift {
|
|
|
|
'('
|
|
|
|
} else {
|
|
|
|
'9'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Row0 => {
|
|
|
|
if shift {
|
|
|
|
')'
|
|
|
|
} else {
|
|
|
|
'0'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Grave => {
|
|
|
|
if shift {
|
|
|
|
'~'
|
|
|
|
} else {
|
|
|
|
'`'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Minus => {
|
|
|
|
if shift {
|
|
|
|
'_'
|
|
|
|
} else {
|
|
|
|
'-'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Equals => {
|
|
|
|
if shift {
|
|
|
|
'+'
|
|
|
|
} else {
|
|
|
|
'='
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::LeftBracket => {
|
|
|
|
if shift {
|
|
|
|
'{'
|
|
|
|
} else {
|
|
|
|
'['
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::RightBracket => {
|
|
|
|
if shift {
|
|
|
|
'}'
|
|
|
|
} else {
|
|
|
|
']'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Backslash => {
|
|
|
|
if shift {
|
|
|
|
'|'
|
|
|
|
} else {
|
|
|
|
'\\'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Semicolon => {
|
|
|
|
if shift {
|
|
|
|
':'
|
|
|
|
} else {
|
|
|
|
';'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Apostrophe => {
|
|
|
|
if shift {
|
|
|
|
'"'
|
|
|
|
} else {
|
|
|
|
'\''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Comma => {
|
|
|
|
if shift {
|
|
|
|
'<'
|
|
|
|
} else {
|
|
|
|
','
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Period => {
|
|
|
|
if shift {
|
|
|
|
'>'
|
|
|
|
} else {
|
|
|
|
'.'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Slash => {
|
|
|
|
if shift {
|
|
|
|
'?'
|
|
|
|
} else {
|
|
|
|
'/'
|
|
|
|
}
|
|
|
|
}
|
2016-10-11 23:23:08 +00:00
|
|
|
KeyCode::Space => ' ',
|
|
|
|
KeyCode::NumDivide => '/',
|
|
|
|
KeyCode::NumMultiply => '*',
|
|
|
|
KeyCode::NumMinus => '-',
|
|
|
|
KeyCode::NumPlus => '+',
|
|
|
|
KeyCode::NumPeriod => '.',
|
|
|
|
KeyCode::Num1 => '1',
|
|
|
|
KeyCode::Num2 => '2',
|
|
|
|
KeyCode::Num3 => '3',
|
|
|
|
KeyCode::Num4 => '4',
|
|
|
|
KeyCode::Num5 => '5',
|
|
|
|
KeyCode::Num6 => '6',
|
|
|
|
KeyCode::Num7 => '7',
|
|
|
|
KeyCode::Num8 => '8',
|
|
|
|
KeyCode::Num9 => '9',
|
|
|
|
KeyCode::Num0 => '0',
|
2017-10-12 23:38:55 +00:00
|
|
|
_ => unreachable!("Found unknown input: {:?}", kc),
|
2016-10-11 23:23:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn blt_keycode_to_key(kc: KeyCode) -> Key {
|
|
|
|
match kc {
|
|
|
|
KeyCode::F1 => Key::F1,
|
|
|
|
KeyCode::F2 => Key::F2,
|
|
|
|
KeyCode::F3 => Key::F3,
|
|
|
|
KeyCode::F4 => Key::F4,
|
|
|
|
KeyCode::F5 => Key::F5,
|
|
|
|
KeyCode::F6 => Key::F6,
|
|
|
|
KeyCode::F7 => Key::F7,
|
|
|
|
KeyCode::F8 => Key::F8,
|
|
|
|
KeyCode::F9 => Key::F9,
|
|
|
|
KeyCode::F10 => Key::F10,
|
|
|
|
KeyCode::F11 => Key::F11,
|
|
|
|
KeyCode::F12 => Key::F12,
|
2017-06-13 06:29:26 +00:00
|
|
|
KeyCode::NumEnter | KeyCode::Enter => Key::Enter,
|
2016-10-11 23:23:08 +00:00
|
|
|
KeyCode::Escape => Key::Esc,
|
|
|
|
KeyCode::Backspace => Key::Backspace,
|
|
|
|
KeyCode::Tab => Key::Tab,
|
|
|
|
KeyCode::Pause => Key::PauseBreak,
|
|
|
|
KeyCode::Insert => Key::Ins,
|
|
|
|
KeyCode::Home => Key::Home,
|
|
|
|
KeyCode::PageUp => Key::PageUp,
|
|
|
|
KeyCode::Delete => Key::Del,
|
|
|
|
KeyCode::End => Key::End,
|
|
|
|
KeyCode::PageDown => Key::PageDown,
|
|
|
|
KeyCode::Right => Key::Right,
|
|
|
|
KeyCode::Left => Key::Left,
|
|
|
|
KeyCode::Down => Key::Down,
|
|
|
|
KeyCode::Up => Key::Up,
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
2017-10-13 07:20:27 +00:00
|
|
|
|
|
|
|
fn blt_keycode_to_mouse_button(kc: KeyCode) -> Option<MouseButton> {
|
|
|
|
Some(match kc {
|
|
|
|
KeyCode::MouseLeft => MouseButton::Left,
|
|
|
|
KeyCode::MouseRight => MouseButton::Right,
|
|
|
|
KeyCode::MouseMiddle => MouseButton::Middle,
|
|
|
|
_ => return None,
|
|
|
|
})
|
|
|
|
}
|