From 6dc01945afc5f61d65845aff7425b0b0bce945e7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 5 Aug 2014 00:00:39 +0800 Subject: [PATCH] Make Accelerator a standalone JS type. This makes menu and global-shortcut share the same code on accelerator. --- atom.gyp | 2 + atom/browser/api/atom_api_global_shortcut.cc | 40 ++++++------------ atom/browser/api/atom_api_global_shortcut.h | 7 ++-- atom/browser/api/atom_api_menu.cc | 9 +--- .../accelerator_converter.cc | 20 +++++++++ .../accelerator_converter.h | 24 +++++++++++ docs/api/accelerator.md | 41 +++++++++++++++++++ docs/api/global-shortcut.md | 26 ++++-------- docs/api/menu-item.md | 10 +---- 9 files changed, 114 insertions(+), 65 deletions(-) create mode 100644 atom/common/native_mate_converters/accelerator_converter.cc create mode 100644 atom/common/native_mate_converters/accelerator_converter.h create mode 100644 docs/api/accelerator.md diff --git a/atom.gyp b/atom.gyp index 2b9197a8b7da..4fbfcf95bdee 100644 --- a/atom.gyp +++ b/atom.gyp @@ -194,6 +194,8 @@ 'atom/common/draggable_region.cc', 'atom/common/draggable_region.h', 'atom/common/linux/application_info.cc', + 'atom/common/native_mate_converters/accelerator_converter.cc', + 'atom/common/native_mate_converters/accelerator_converter.h', 'atom/common/native_mate_converters/file_path_converter.h', 'atom/common/native_mate_converters/function_converter.h', 'atom/common/native_mate_converters/gurl_converter.h', diff --git a/atom/browser/api/atom_api_global_shortcut.cc b/atom/browser/api/atom_api_global_shortcut.cc index bb4de6cf1668..827cd01ecb83 100644 --- a/atom/browser/api/atom_api_global_shortcut.cc +++ b/atom/browser/api/atom_api_global_shortcut.cc @@ -6,8 +6,9 @@ #include -#include "atom/browser/ui/accelerator_util.h" +#include "atom/common/native_mate_converters/accelerator_converter.h" #include "atom/common/native_mate_converters/function_converter.h" +#include "base/stl_util.h" #include "native_mate/dictionary.h" #include "atom/common/node_includes.h" @@ -36,52 +37,35 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) { accelerator_callback_map_[accelerator].Run(); } -bool GlobalShortcut::Register(const std::string& keycode, - const base::Closure& callback) { - ui::Accelerator accelerator; - if (!accelerator_util::StringToAccelerator(keycode, &accelerator)) { - LOG(ERROR) << keycode << " is invalid."; - return false; - } +bool GlobalShortcut::Register(const ui::Accelerator& accelerator, + const base::Closure& callback) { if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator( accelerator, this)) { return false; } + accelerator_callback_map_[accelerator] = callback; return true; } -void GlobalShortcut::Unregister(const std::string& keycode) { - ui::Accelerator accelerator; - if (!accelerator_util::StringToAccelerator(keycode, &accelerator)) { - LOG(ERROR) << "The keycode: " << keycode << " is invalid."; +void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) { + if (!ContainsKey(accelerator_callback_map_, accelerator)) return; - } - if (accelerator_callback_map_.find(accelerator) == - accelerator_callback_map_.end()) { - LOG(ERROR) << "The keycode: " << keycode << " isn't registered yet!"; - return; - } + accelerator_callback_map_.erase(accelerator); GlobalShortcutListener::GetInstance()->UnregisterAccelerator( accelerator, this); } +bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) { + return ContainsKey(accelerator_callback_map_, accelerator); +} + void GlobalShortcut::UnregisterAll() { accelerator_callback_map_.clear(); GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this); } -bool GlobalShortcut::IsRegistered(const std::string& keycode) { - ui::Accelerator accelerator; - if (!accelerator_util::StringToAccelerator(keycode, &accelerator)) { - LOG(ERROR) << "The keycode: " << keycode << " is invalid."; - return false; - } - return accelerator_callback_map_.find(accelerator) != - accelerator_callback_map_.end(); -} - // static mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder( v8::Isolate* isolate) { diff --git a/atom/browser/api/atom_api_global_shortcut.h b/atom/browser/api/atom_api_global_shortcut.h index cb731c665d3d..b9d04e29fe5b 100644 --- a/atom/browser/api/atom_api_global_shortcut.h +++ b/atom/browser/api/atom_api_global_shortcut.h @@ -34,9 +34,10 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer, private: typedef std::map AcceleratorCallbackMap; - bool Register(const std::string& keycode, const base::Closure& callback); - bool IsRegistered(const std::string& keycode); - void Unregister(const std::string& keycode); + bool Register(const ui::Accelerator& accelerator, + const base::Closure& callback); + bool IsRegistered(const ui::Accelerator& accelerator); + void Unregister(const ui::Accelerator& accelerator); void UnregisterAll(); // GlobalShortcutListener::Observer implementation. diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index 0a4847668147..a08070f19603 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -5,7 +5,7 @@ #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/native_window.h" -#include "atom/browser/ui/accelerator_util.h" +#include "atom/common/native_mate_converters/accelerator_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" @@ -92,12 +92,7 @@ bool Menu::GetAcceleratorForCommandId(int command_id, GetWrapper(isolate), "getAcceleratorForCommandId", command_id); - if (shortcut->IsString()) { - std::string shortcut_str = mate::V8ToString(shortcut); - return accelerator_util::StringToAccelerator(shortcut_str, accelerator); - } - - return false; + return mate::ConvertFromV8(isolate, shortcut, accelerator); } bool Menu::IsItemForCommandIdDynamic(int command_id) const { diff --git a/atom/common/native_mate_converters/accelerator_converter.cc b/atom/common/native_mate_converters/accelerator_converter.cc new file mode 100644 index 000000000000..e860dc141342 --- /dev/null +++ b/atom/common/native_mate_converters/accelerator_converter.cc @@ -0,0 +1,20 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/native_mate_converters/accelerator_converter.h" + +#include "atom/browser/ui/accelerator_util.h" + +namespace mate { + +// static +bool Converter::FromV8( + v8::Isolate* isolate, v8::Handle val, ui::Accelerator* out) { + std::string keycode; + if (!ConvertFromV8(isolate, val, &keycode)) + return false; + return accelerator_util::StringToAccelerator(keycode, out); +} + +} // namespace mate diff --git a/atom/common/native_mate_converters/accelerator_converter.h b/atom/common/native_mate_converters/accelerator_converter.h new file mode 100644 index 000000000000..a60345e628eb --- /dev/null +++ b/atom/common/native_mate_converters/accelerator_converter.h @@ -0,0 +1,24 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_ + +#include "native_mate/converter.h" + +namespace ui { +class Accelerator; +} + +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + ui::Accelerator* out); +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_ diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md new file mode 100644 index 000000000000..0cfb2d282c23 --- /dev/null +++ b/docs/api/accelerator.md @@ -0,0 +1,41 @@ +# Accelerator + +An accelerator is string that represents a keyboard shortcut, it can contain +multiple modifiers and key codes, combined by the `+` character. + +Examples: + +* `Command+A` +* `Ctrl+Shift+Z` + +## Platform notice + +On Linux and Windows, the `Command` key would not have any effect, you can +use `CommandOrControl` which represents `Command` on OS X and `Control` on +Linux and Windows to define some accelerators. + +## Available modifiers + +* `Command` (or `Cmd` for short) +* `Control` (or `Ctrl` for short) +* `CommandOrControl` (or `CmdOrCtrl` for short) +* `Alt` +* `Shift` + +## Available key codes + +* `0` to `9` +* `A` to `Z` +* `F1` to `F24` +* Punctuations like `~`, `!`, `@`, `#`, `$`, etc. +* `Space` +* `Backspace` +* `Delete` +* `Insert` +* `Return` (or `Enter` as alias) +* `Up`, `Down`, `Left` and `Right` +* `Home` and `End` +* `PageUp` and `PageDown` +* `Escape` (or `Esc` for short) +* `VolumeUp`, `VolumeDown` and `VolumeMute` +* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause` diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index 7f08051c40bf..285c26995afb 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -22,33 +22,23 @@ globalShortcut.unregister('ctrl+x'); globalShortcut.unregisterAll(); ``` -## globalShortcut.register(keycode, callback) +## globalShortcut.register(accelerator, callback) -* `keycode` String +* `accelerator` [Accelerator](accelerator.md) * `callback` Function -Registers a global shortcut of `keycode`, the `callback` would be called when +Registers a global shortcut of `accelerator`, the `callback` would be called when the registered shortcut is pressed by user. -`keycode` is a string to specify shortcut key, such as "ctrl+shift+a". +## globalShortcut.isRegistered(accelerator) -A `keycode` consists of modifier and key two parts: +* `accelerator` [Accelerator](accelerator.md) -__Modifiers__: control(ctrl), command(cmd), alt, shift, commandorcontrol(cmdorctrl). +Returns whether shortcut of `accelerator` is registered. -__Supported keys__: 0-9, a-z, up, down, left, right, home, end, pagedown, pageup, -insert, delete, esc, space, backspace, tab, f1-f12, volumeup, volumedown, media -keys(medianextrack, mediaprevioustrack, mediastop, mediaplaypause). +## globalShortcut.unregister(accelerator) -## globalShortcut.isRegistered(keycode) - -* `keycode` String - -Return whether the shortcut is registered. - -## globalShortcut.unregister(keycode) - -* `keycode` String +* `accelerator` [Accelerator](accelerator.md) Unregisters the global shortcut of `keycode`. diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index ad2e42b69625..f1a351211478 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -12,17 +12,9 @@ `radio` * `label` String * `sublabel` String - * `accelerator` String - In the form of `Command+R`, `Ctrl+C`, - `Shift+Command+D`, `D`, etc. + * `accelerator` [Accelerator](accelerator.md) * `enabled` Boolean * `visible` Boolean * `checked` Boolean * `submenu` Menu - Should be specified for `submenu` type menu item, when it's specified the `type: 'submenu'` can be omitted for the menu item - -## Notes on accelerator - -On Linux and Windows, the `Command` key would not have any effect, you can -use `CommandOrControl` which represents `Command` on OS X and `Control` on -Linux and Windows to define some accelerators, you can also use its short -alias `CmdOrCtrl`.