Update GlobalShortcut API design.

* Rename Shortcut API to GlobalShortcut for better suite.
* Implement the new design interfaces.
* Put the chromium related source code to the same directory as in chrome.
This commit is contained in:
Haojian Wu 2014-07-31 12:22:29 +08:00
parent b2217474c1
commit 035679057e
16 changed files with 288 additions and 302 deletions

View file

@ -0,0 +1,123 @@
// 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/browser/api/atom_api_global_shortcut.h"
#include <string>
#include "atom/browser/ui/accelerator_util.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using extensions::GlobalShortcutListener;
namespace atom {
namespace api {
GlobalShortcut::GlobalShortcut() {
}
GlobalShortcut::~GlobalShortcut() {
UnregisterAll();
}
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
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;
}
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.";
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);
}
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) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("register",
base::Bind(&GlobalShortcut::Register,
base::Unretained(this)))
.SetMethod("isRegistered",
base::Bind(&GlobalShortcut::IsRegistered,
base::Unretained(this)))
.SetMethod("unregister",
base::Bind(&GlobalShortcut::Unregister,
base::Unretained(this)))
.SetMethod("unregisterAll",
base::Bind(&GlobalShortcut::UnregisterAll,
base::Unretained(this)));
}
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new GlobalShortcut);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_global_shortcut, Initialize)

View file

@ -0,0 +1,54 @@
// 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_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#include <map>
#include <string>
#include "base/callback.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.h"
#include "ui/base/accelerators/accelerator.h"
namespace atom {
namespace api {
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
public mate::Wrappable {
public:
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
protected:
GlobalShortcut();
virtual ~GlobalShortcut();
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
bool Register(const std::string& keycode, const base::Closure& callback);
bool IsRegistered(const std::string& keycode);
void Unregister(const std::string& keycode);
void UnregisterAll();
// GlobalShortcutListener::Observer implementation.
virtual void OnKeyPressed(const ui::Accelerator& accelerator) OVERRIDE;
AcceleratorCallbackMap accelerator_callback_map_;
DISALLOW_COPY_AND_ASSIGN(GlobalShortcut);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_

View file

@ -1,110 +0,0 @@
// 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/browser/api/atom_api_shortcut.h"
#include <string>
#include <vector>
#include "atom/browser/ui/accelerator_util.h"
#include "base/values.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
Shortcut::Shortcut(const std::string& key) {
is_key_valid_ = accelerator_util::StringToAccelerator(key, &accelerator_);
}
Shortcut::~Shortcut() {
Unregister();
}
// static
mate::Wrappable* Shortcut::Create(const std::string& key) {
return new Shortcut(key);
}
void Shortcut::OnActive() {
Emit("active");
}
void Shortcut::OnFailed(const std::string& error_msg) {
base::ListValue args;
args.AppendString(error_msg);
Emit("failed", args);
}
void Shortcut::SetKey(const std::string& key) {
// We need to unregister the previous key before set new key eachtime.
Unregister();
is_key_valid_ = accelerator_util::StringToAccelerator(key, &accelerator_);
}
void Shortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator != accelerator_) {
// This should never occur, because if it does, GlobalShortcutListener
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
OnActive();
}
void Shortcut::Register() {
if (!is_key_valid_) {
OnFailed("Shortcut is invalid.");
return;
}
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
accelerator_, this))
OnFailed("Fail to register the shortcut.");
}
void Shortcut::Unregister() {
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
accelerator_, this);
}
bool Shortcut::IsRegistered() {
return GlobalShortcutListener::GetInstance()->IsAcceleratorRegistered(
accelerator_);
}
// static
void Shortcut::BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("setKey", &Shortcut::SetKey)
.SetMethod("register", &Shortcut::Register)
.SetMethod("unregister", &Shortcut::Unregister)
.SetMethod("isRegistered", &Shortcut::IsRegistered);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
using atom::api::Shortcut;
v8::Isolate* isolate = context->GetIsolate();
v8::Handle<v8::Function> constructor = mate::CreateConstructor<Shortcut>(
isolate, "Shortcut", base::Bind(&Shortcut::Create));
mate::Dictionary dict(isolate, exports);
dict.Set("Shortcut", static_cast<v8::Handle<v8::Value>>(constructor));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_shortcut, Initialize)

View file

@ -1,67 +0,0 @@
// 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_BROWSER_API_ATOM_API_SHORTCUT_H_
#define ATOM_BROWSER_API_ATOM_API_SHORTCUT_H_
#include <string>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "chrome/browser/ui/shortcut/global_shortcut_listener.h"
#include "ui/base/accelerators/accelerator.h"
namespace mate {
class Dictionary;
}
namespace atom {
class Shortcut;
namespace api {
class Menu;
class Shortcut : public mate::EventEmitter,
public GlobalShortcutListener::Observer {
public:
static mate::Wrappable* Create(const std::string& key);
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
protected:
explicit Shortcut(const std::string& key);
virtual ~Shortcut();
const ui::Accelerator& GetAccelerator() const {
return accelerator_;
}
void OnActive();
void OnFailed(const std::string& error_msg);
// GlobalShortcutListener::Observer implementation.
virtual void OnKeyPressed(const ui::Accelerator& accelerator) OVERRIDE;
void SetKey(const std::string& key);
void Register();
void Unregister();
bool IsRegistered();
private:
bool is_key_valid_;
ui::Accelerator accelerator_;
DISALLOW_COPY_AND_ASSIGN(Shortcut);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_SHORTCUT_H_

View file

@ -0,0 +1,5 @@
bindings = process.atomBinding 'global_shortcut'
globalShortcut = bindings.globalShortcut
module.exports = globalShortcut

View file

@ -1,7 +0,0 @@
EventEmitter = require('events').EventEmitter
bindings = process.atomBinding 'shortcut'
Shortcut = bindings.Shortcut
Shortcut::__proto__ = EventEmitter.prototype
module.exports = Shortcut