Add popup method for Menu.
This commit is contained in:
parent
667384ef74
commit
13c0a05fdd
4 changed files with 95 additions and 0 deletions
|
@ -44,11 +44,27 @@ bool Menu::IsCommandIdEnabled(int command_id) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Menu::IsCommandIdVisible(int command_id) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Menu::GetAcceleratorForCommandId(int command_id,
|
bool Menu::GetAcceleratorForCommandId(int command_id,
|
||||||
ui::Accelerator* accelerator) {
|
ui::Accelerator* accelerator) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Menu::IsItemForCommandIdDynamic(int command_id) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string16 Menu::GetLabelForCommandId(int command_id) const {
|
||||||
|
return string16();
|
||||||
|
}
|
||||||
|
|
||||||
|
string16 Menu::GetSublabelForCommandId(int command_id) const {
|
||||||
|
return string16();
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::ExecuteCommand(int command_id, int event_flags) {
|
void Menu::ExecuteCommand(int command_id, int event_flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +272,22 @@ v8::Handle<v8::Value> Menu::IsVisibleAt(const v8::Arguments &args) {
|
||||||
return v8::Boolean::New(self->model_->IsVisibleAt(args[0]->IntegerValue()));
|
return v8::Boolean::New(self->model_->IsVisibleAt(args[0]->IntegerValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
v8::Handle<v8::Value> Menu::Popup(const v8::Arguments &args) {
|
||||||
|
UNWRAP_MEMNU_AND_CHECK;
|
||||||
|
|
||||||
|
if (!args[0]->IsObject() || !args[1]->IsNumber() || !args[2]->IsNumber())
|
||||||
|
return node::ThrowTypeError("Bad argument");
|
||||||
|
|
||||||
|
NativeWindow* window = Unwrap<NativeWindow>(args[0]->ToObject());
|
||||||
|
if (!window)
|
||||||
|
return node::ThrowTypeError("Invalid window");
|
||||||
|
|
||||||
|
self->Popup(window, args[1]->IntegerValue(), args[2]->IntegerValue());
|
||||||
|
|
||||||
|
return v8::Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Menu::Initialize(v8::Handle<v8::Object> target) {
|
void Menu::Initialize(v8::Handle<v8::Object> target) {
|
||||||
v8::HandleScope scope;
|
v8::HandleScope scope;
|
||||||
|
@ -269,9 +301,12 @@ void Menu::Initialize(v8::Handle<v8::Object> target) {
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "insertRadioItem", InsertRadioItem);
|
NODE_SET_PROTOTYPE_METHOD(t, "insertRadioItem", InsertRadioItem);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "insertSeparator", InsertSeparator);
|
NODE_SET_PROTOTYPE_METHOD(t, "insertSeparator", InsertSeparator);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "insertSubMenu", InsertSubMenu);
|
NODE_SET_PROTOTYPE_METHOD(t, "insertSubMenu", InsertSubMenu);
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "setIcon", SetIcon);
|
NODE_SET_PROTOTYPE_METHOD(t, "setIcon", SetIcon);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "setSublabel", SetSublabel);
|
NODE_SET_PROTOTYPE_METHOD(t, "setSublabel", SetSublabel);
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "clear", Clear);
|
NODE_SET_PROTOTYPE_METHOD(t, "clear", Clear);
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "getIndexOfCommandId", GetIndexOfCommandId);
|
NODE_SET_PROTOTYPE_METHOD(t, "getIndexOfCommandId", GetIndexOfCommandId);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "getItemCount", GetItemCount);
|
NODE_SET_PROTOTYPE_METHOD(t, "getItemCount", GetItemCount);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "getCommandIdAt", GetCommandIdAt);
|
NODE_SET_PROTOTYPE_METHOD(t, "getCommandIdAt", GetCommandIdAt);
|
||||||
|
@ -281,6 +316,8 @@ void Menu::Initialize(v8::Handle<v8::Object> target) {
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "isEnabledAt", IsEnabledAt);
|
NODE_SET_PROTOTYPE_METHOD(t, "isEnabledAt", IsEnabledAt);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "isVisibleAt", IsVisibleAt);
|
NODE_SET_PROTOTYPE_METHOD(t, "isVisibleAt", IsVisibleAt);
|
||||||
|
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "popup", Popup);
|
||||||
|
|
||||||
target->Set(v8::String::NewSymbol("Menu"), t->GetFunction());
|
target->Set(v8::String::NewSymbol("Menu"), t->GetFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
class NativeWindow;
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Menu : public EventEmitter,
|
class Menu : public EventEmitter,
|
||||||
|
@ -28,11 +30,17 @@ class Menu : public EventEmitter,
|
||||||
// ui::SimpleMenuModel::Delegate implementations:
|
// ui::SimpleMenuModel::Delegate implementations:
|
||||||
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
|
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
|
||||||
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
|
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
|
||||||
|
virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
|
||||||
virtual bool GetAcceleratorForCommandId(
|
virtual bool GetAcceleratorForCommandId(
|
||||||
int command_id,
|
int command_id,
|
||||||
ui::Accelerator* accelerator) OVERRIDE;
|
ui::Accelerator* accelerator) OVERRIDE;
|
||||||
|
virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
|
||||||
|
virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE;
|
||||||
|
virtual string16 GetSublabelForCommandId(int command_id) const OVERRIDE;
|
||||||
virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
|
virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
|
||||||
|
|
||||||
|
virtual void Popup(NativeWindow* window, int x, int y) = 0;
|
||||||
|
|
||||||
scoped_ptr<ui::SimpleMenuModel> model_;
|
scoped_ptr<ui::SimpleMenuModel> model_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -58,6 +66,8 @@ class Menu : public EventEmitter,
|
||||||
static v8::Handle<v8::Value> IsEnabledAt(const v8::Arguments &args);
|
static v8::Handle<v8::Value> IsEnabledAt(const v8::Arguments &args);
|
||||||
static v8::Handle<v8::Value> IsVisibleAt(const v8::Arguments &args);
|
static v8::Handle<v8::Value> IsVisibleAt(const v8::Arguments &args);
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> Popup(const v8::Arguments &args);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ class MenuMac : public Menu {
|
||||||
virtual ~MenuMac();
|
virtual ~MenuMac();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void Popup(NativeWindow* window, int x, int y) OVERRIDE;
|
||||||
|
|
||||||
scoped_nsobject<MenuController> controller_;
|
scoped_nsobject<MenuController> controller_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
#import "browser/api/atom_api_menu_mac.h"
|
#import "browser/api/atom_api_menu_mac.h"
|
||||||
|
|
||||||
|
#include "base/message_loop.h"
|
||||||
|
#include "base/mac/scoped_sending_event.h"
|
||||||
|
#include "browser/native_window.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "content/public/browser/web_contents_view.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
@ -17,6 +23,46 @@ MenuMac::MenuMac(v8::Handle<v8::Object> wrapper)
|
||||||
MenuMac::~MenuMac() {
|
MenuMac::~MenuMac() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuMac::Popup(NativeWindow* native_window, int ox, int oy) {
|
||||||
|
NSWindow* window = native_window->GetNativeWindow();
|
||||||
|
content::WebContents* web_contents = native_window->GetWebContents();
|
||||||
|
|
||||||
|
CGFloat x = ox;
|
||||||
|
CGFloat y = oy;
|
||||||
|
|
||||||
|
// Fake out a context menu event.
|
||||||
|
NSEvent* currentEvent = [NSApp currentEvent];
|
||||||
|
NSView* web_view = web_contents->GetView()->GetNativeView();
|
||||||
|
NSPoint position = { x, web_view.bounds.size.height - y };
|
||||||
|
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||||
|
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||||
|
location:position
|
||||||
|
modifierFlags:NSRightMouseDownMask
|
||||||
|
timestamp:eventTime
|
||||||
|
windowNumber:[window windowNumber]
|
||||||
|
context:nil
|
||||||
|
eventNumber:0
|
||||||
|
clickCount:1
|
||||||
|
pressure:1.0];
|
||||||
|
|
||||||
|
{
|
||||||
|
// Make sure events can be pumped while the menu is up.
|
||||||
|
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
|
||||||
|
|
||||||
|
// One of the events that could be pumped is |window.close()|.
|
||||||
|
// User-initiated event-tracking loops protect against this by
|
||||||
|
// setting flags in -[CrApplication sendEvent:], but since
|
||||||
|
// web-content menus are initiated by IPC message the setup has to
|
||||||
|
// be done manually.
|
||||||
|
base::mac::ScopedSendingEvent sendingEventScoper;
|
||||||
|
|
||||||
|
// Show the menu.
|
||||||
|
[NSMenu popUpContextMenu:[controller_ menu]
|
||||||
|
withEvent:clickEvent
|
||||||
|
forView:web_view];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Menu* Menu::Create(v8::Handle<v8::Object> wrapper) {
|
Menu* Menu::Create(v8::Handle<v8::Object> wrapper) {
|
||||||
return new MenuMac(wrapper);
|
return new MenuMac(wrapper);
|
||||||
|
|
Loading…
Reference in a new issue