Allow positioning the context menu

This commit is contained in:
Joao Moreno 2014-11-25 16:47:41 +01:00
parent 03f19bea6b
commit 46e6b5ec3e
7 changed files with 40 additions and 5 deletions

View file

@ -246,7 +246,8 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isEnabledAt", &Menu::IsEnabledAt) .SetMethod("isEnabledAt", &Menu::IsEnabledAt)
.SetMethod("isVisibleAt", &Menu::IsVisibleAt) .SetMethod("isVisibleAt", &Menu::IsVisibleAt)
.SetMethod("attachToWindow", &Menu::AttachToWindow) .SetMethod("attachToWindow", &Menu::AttachToWindow)
.SetMethod("_popup", &Menu::Popup); .SetMethod("_popup", &Menu::Popup)
.SetMethod("_popupAt", &Menu::PopupAt);
} }
} // namespace api } // namespace api

View file

@ -55,6 +55,7 @@ class Menu : public mate::Wrappable,
virtual void AttachToWindow(Window* window); virtual void AttachToWindow(Window* window);
virtual void Popup(Window* window) = 0; virtual void Popup(Window* window) = 0;
virtual void PopupAt(Window* window, int x, int y) = 0;
scoped_ptr<ui::SimpleMenuModel> model_; scoped_ptr<ui::SimpleMenuModel> model_;
Menu* parent_; Menu* parent_;

View file

@ -20,6 +20,7 @@ class MenuMac : public Menu {
MenuMac(); MenuMac();
virtual void Popup(Window* window) OVERRIDE; virtual void Popup(Window* window) OVERRIDE;
virtual void PopupAt(Window* window, int x, int y) OVERRIDE;
base::scoped_nsobject<AtomMenuController> menu_controller_; base::scoped_nsobject<AtomMenuController> menu_controller_;

View file

@ -46,6 +46,21 @@ void MenuMac::Popup(Window* window) {
forView:web_contents->GetContentNativeView()]; forView:web_contents->GetContentNativeView()];
} }
void MenuMac::PopupAt(Window* window, int x, int y) {
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:model_.get()]);
NativeWindow* native_window = window->window();
content::WebContents* web_contents = native_window->GetWebContents();
NSView* view = web_contents->GetContentNativeView();
NSMenu* menu = [menu_controller menu];
// Show the menu.
[menu popUpMenuPositioningItem:[menu itemAtIndex:0]
atLocation:NSMakePoint(x, [view frame].size.height - y)
inView:view];
}
// static // static
void Menu::SetApplicationMenu(Menu* base_menu) { void Menu::SetApplicationMenu(Menu* base_menu) {
MenuMac* menu = static_cast<MenuMac*>(base_menu); MenuMac* menu = static_cast<MenuMac*>(base_menu);

View file

@ -5,6 +5,7 @@
#include "atom/browser/api/atom_api_menu_views.h" #include "atom/browser/api/atom_api_menu_views.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/gfx/screen.h" #include "ui/gfx/screen.h"
#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/menu/menu_runner.h"
@ -16,14 +17,24 @@ MenuViews::MenuViews() {
} }
void MenuViews::Popup(Window* window) { void MenuViews::Popup(Window* window) {
gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); PopupAtPoint(window, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
}
void MenuViews::PopupAt(Window* window, int x, int y) {
NativeWindow* nativeWindowViews = static_cast<NativeWindow*>(window->window());
content::RenderWidgetHostView* view = nativeWindowViews->GetWebContents()->GetRenderWidgetHostView();
gfx::Point viewOrigin = view->GetViewBounds().origin();
PopupAtPoint(window, gfx::Point(viewOrigin.x() + x, viewOrigin.y() + y));
}
void MenuViews::PopupAtPoint(Window* window, gfx::Point point) {
views::MenuRunner menu_runner( views::MenuRunner menu_runner(
model(), model(),
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS); views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
ignore_result(menu_runner.RunMenuAt( ignore_result(menu_runner.RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(), static_cast<NativeWindowViews*>(window->window())->widget(),
NULL, NULL,
gfx::Rect(cursor, gfx::Size()), gfx::Rect(point, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT, views::MENU_ANCHOR_TOPLEFT,
ui::MENU_SOURCE_MOUSE)); ui::MENU_SOURCE_MOUSE));
} }

View file

@ -6,6 +6,7 @@
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_ #define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
#include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_menu.h"
#include "ui/gfx/screen.h"
namespace atom { namespace atom {
@ -17,8 +18,10 @@ class MenuViews : public Menu {
protected: protected:
virtual void Popup(Window* window) OVERRIDE; virtual void Popup(Window* window) OVERRIDE;
virtual void PopupAt(Window* window, int x, int y) OVERRIDE;
private: private:
void PopupAtPoint(Window* window, gfx::Point point);
DISALLOW_COPY_AND_ASSIGN(MenuViews); DISALLOW_COPY_AND_ASSIGN(MenuViews);
}; };

View file

@ -45,9 +45,12 @@ Menu::_init = ->
break break
v8Util.setHiddenValue group[0], 'checked', true unless checked v8Util.setHiddenValue group[0], 'checked', true unless checked
Menu::popup = (window) -> Menu::popup = (window, x, y) ->
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
@_popup window if x? and y?
@_popupAt(window, x, y)
else
@_popup window
Menu::append = (item) -> Menu::append = (item) ->
@insert @getItemCount(), item @insert @getItemCount(), item