Merge pull request #870 from joaomoreno/popup
Allow positioning the context menu
This commit is contained in:
commit
8a736abac7
8 changed files with 47 additions and 7 deletions
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,25 @@ 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());
|
||||||
|
gfx::Point viewOrigin = nativeWindowViews->GetWebContents()
|
||||||
|
->GetRenderWidgetHostView()->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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,11 @@ 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
|
||||||
|
if x? and y?
|
||||||
|
@_popupAt(window, x, y)
|
||||||
|
else
|
||||||
@_popup window
|
@_popup window
|
||||||
|
|
||||||
Menu::append = (item) ->
|
Menu::append = (item) ->
|
||||||
|
|
|
@ -191,11 +191,15 @@ Generally, the `template` is just an array of `options` for constructing
|
||||||
You can also attach other fields to element of the `template`, and they will
|
You can also attach other fields to element of the `template`, and they will
|
||||||
become properties of the constructed menu items.
|
become properties of the constructed menu items.
|
||||||
|
|
||||||
### Menu.popup(browserWindow)
|
### Menu.popup(browserWindow, [x, y])
|
||||||
|
|
||||||
* `browserWindow` BrowserWindow
|
* `browserWindow` BrowserWindow
|
||||||
|
* `x` Number
|
||||||
|
* `y` Number
|
||||||
|
|
||||||
Popups the this as context menu in the `browserWindow`.
|
Popups this menu as a context menu in the `browserWindow`. You can optionally
|
||||||
|
provide a `(x,y)` coordinate to place the menu at, otherwise it will be placed
|
||||||
|
at the current mouse cursor position.
|
||||||
|
|
||||||
### Menu.append(menuItem)
|
### Menu.append(menuItem)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue