Add keyboard shortcuts to glutin browser

This commit is contained in:
Jesse Ruderman 2015-06-27 03:06:18 -07:00
parent 8892f8175d
commit 1ff4fe02d9
4 changed files with 90 additions and 15 deletions

View file

@ -851,6 +851,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.on_zoom_window_event(magnification);
}
WindowEvent::ResetZoom => {
self.on_zoom_reset_window_event();
}
WindowEvent::PinchZoom(magnification) => {
self.on_pinch_zoom_window_event(magnification);
}
@ -1066,6 +1070,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.scene.set_root_layer_size(self.window_size.as_f32());
}
fn on_zoom_reset_window_event(&mut self) {
self.page_zoom = ScaleFactor::new(1.0);
self.update_zoom_transform();
self.send_window_size();
}
fn on_zoom_window_event(&mut self, magnification: f32) {
self.page_zoom = ScaleFactor::new((self.page_zoom.get() * magnification).max(1.0));
self.update_zoom_transform();

View file

@ -64,6 +64,8 @@ pub enum WindowEvent {
Zoom(f32),
/// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel).
PinchZoom(f32),
/// Sent when the user resets zoom to default.
ResetZoom,
/// Sent when the user uses chrome navigation (i.e. backspace or shift-backspace).
Navigation(WindowNavigateMsg),
/// Sent when the user quits the application
@ -86,6 +88,7 @@ impl Debug for WindowEvent {
WindowEvent::Scroll(..) => write!(f, "Scroll"),
WindowEvent::Zoom(..) => write!(f, "Zoom"),
WindowEvent::PinchZoom(..) => write!(f, "PinchZoom"),
WindowEvent::ResetZoom => write!(f, "ResetZoom"),
WindowEvent::Navigation(..) => write!(f, "Navigation"),
WindowEvent::Quit => write!(f, "Quit"),
}

View file

@ -192,6 +192,7 @@ pub enum Key {
bitflags! {
flags KeyModifiers: u8 {
const NONE = 0x00,
const SHIFT = 0x01,
const CONTROL = 0x02,
const ALT = 0x04,

View file

@ -30,7 +30,7 @@ use euclid::point::Point2D;
#[cfg(feature = "window")]
use glutin::{Api, ElementState, Event, GlRequest, MouseButton, VirtualKeyCode, MouseScrollDelta};
#[cfg(feature = "window")]
use msg::constellation_msg::{KeyState, CONTROL, SHIFT, ALT};
use msg::constellation_msg::{KeyState, NONE, CONTROL, SHIFT, ALT, SUPER};
#[cfg(feature = "window")]
use std::cell::{Cell, RefCell};
#[cfg(feature = "window")]
@ -51,9 +51,26 @@ bitflags! {
const RIGHT_SHIFT = 8,
const LEFT_ALT = 16,
const RIGHT_ALT = 32,
const LEFT_SUPER = 64,
const RIGHT_SUPER = 128,
}
}
// Some shortcuts use Cmd on Mac and Control on other systems.
#[cfg(all(feature = "window", target_os="macos"))]
const CMD_OR_CONTROL : constellation_msg::KeyModifiers = SUPER;
#[cfg(all(feature = "window", not(target_os="macos")))]
const CMD_OR_CONTROL : constellation_msg::KeyModifiers = CONTROL;
// Some shortcuts use Cmd on Mac and Alt on other systems.
#[cfg(all(feature = "window", target_os="macos"))]
const CMD_OR_ALT : constellation_msg::KeyModifiers = SUPER;
#[cfg(all(feature = "window", not(target_os="macos")))]
const CMD_OR_ALT : constellation_msg::KeyModifiers = ALT;
// This should vary by zoom level and maybe actual text size (focused or under cursor)
const LINE_HEIGHT : f32 = 38.0;
/// The type of a window.
#[cfg(feature = "window")]
pub struct Window {
@ -152,6 +169,8 @@ impl Window {
(_, VirtualKeyCode::RShift) => self.toggle_modifier(RIGHT_SHIFT),
(_, VirtualKeyCode::LAlt) => self.toggle_modifier(LEFT_ALT),
(_, VirtualKeyCode::RAlt) => self.toggle_modifier(RIGHT_ALT),
(_, VirtualKeyCode::LWin) => self.toggle_modifier(LEFT_SUPER),
(_, VirtualKeyCode::RWin) => self.toggle_modifier(RIGHT_SUPER),
(ElementState::Pressed, VirtualKeyCode::Escape) => return true,
(_, key_code) => {
match Window::glutin_key_to_script_key(key_code) {
@ -199,10 +218,7 @@ impl Window {
} else {
match delta {
MouseScrollDelta::LineDelta(dx, dy) => {
// this should use the actual line height
// of the frame under the mouse
let line_height = 57.0;
self.scroll_window(dx, dy * line_height);
self.scroll_window(dx, dy * LINE_HEIGHT);
}
MouseScrollDelta::PixelDelta(dx, dy) => self.scroll_window(dx, dy)
}
@ -452,8 +468,28 @@ impl Window {
if modifiers.intersects(LEFT_ALT | RIGHT_ALT) {
result.insert(ALT);
}
if modifiers.intersects(LEFT_SUPER | RIGHT_SUPER) {
result.insert(SUPER);
}
result
}
#[cfg(all(feature = "window", not(target_os="win")))]
fn platform_handle_key(&self, key: Key, mods: constellation_msg::KeyModifiers) {
match (mods, key) {
(CMD_OR_CONTROL, Key::LeftBracket) => {
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back));
}
(CMD_OR_CONTROL, Key::RightBracket) => {
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward));
}
_ => {}
}
}
#[cfg(all(feature = "window", target_os="win"))]
fn platform_handle_key(&self, key: Key, mods: constellation_msg::KeyModifiers) {
}
}
// WindowProxy is not implemented for android yet
@ -608,26 +644,51 @@ impl WindowMethods for Window {
/// Helper function to handle keyboard events.
fn handle_key(&self, key: Key, mods: constellation_msg::KeyModifiers) {
match key {
Key::Equal if mods.contains(CONTROL) => { // Ctrl-+
match (mods, key) {
(_, Key::Equal) if mods & !SHIFT == CMD_OR_CONTROL => {
self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.1));
}
Key::Minus if mods.contains(CONTROL) => { // Ctrl--
(CMD_OR_CONTROL, Key::Minus) => {
self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.0/1.1));
}
Key::Backspace if mods.contains(SHIFT) => { // Shift-Backspace
(CMD_OR_CONTROL, Key::Num0) |
(CMD_OR_CONTROL, Key::Kp0) => {
self.event_queue.borrow_mut().push(WindowEvent::ResetZoom);
}
(SHIFT, Key::Backspace) => {
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward));
}
Key::Backspace => { // Backspace
(NONE, Key::Backspace) => {
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back));
}
Key::PageDown => {
self.scroll_window(0.0, -self.framebuffer_size().as_f32().to_untyped().height);
(CMD_OR_ALT, Key::Right) => {
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward));
}
Key::PageUp => {
self.scroll_window(0.0, self.framebuffer_size().as_f32().to_untyped().height);
(CMD_OR_ALT, Key::Left) => {
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back));
}
(NONE, Key::PageDown) |
(NONE, Key::Space) => {
self.scroll_window(0.0, -self.framebuffer_size().as_f32().to_untyped().height + 2.0 * LINE_HEIGHT);
}
(NONE, Key::PageUp) |
(SHIFT, Key::Space) => {
self.scroll_window(0.0, self.framebuffer_size().as_f32().to_untyped().height - 2.0 * LINE_HEIGHT);
}
(NONE, Key::Up) => {
self.scroll_window(0.0, 3.0 * LINE_HEIGHT);
}
(NONE, Key::Down) => {
self.scroll_window(0.0, -3.0 * LINE_HEIGHT);
}
_ => {
self.platform_handle_key(key, mods);
}
_ => {}
}
}