Merge pull request #11754 from electron/menu-events

Add and document menu events
This commit is contained in:
shelley vohr 2018-01-29 12:40:57 -05:00 committed by GitHub
commit 12d4f984f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 6 deletions

View file

@ -23,9 +23,13 @@ Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: model_(new AtomMenuModel(this)), : model_(new AtomMenuModel(this)),
parent_(nullptr) { parent_(nullptr) {
InitWith(isolate, wrapper); InitWith(isolate, wrapper);
model_->AddObserver(this);
} }
Menu::~Menu() { Menu::~Menu() {
if (model_) {
model_->RemoveObserver(this);
}
} }
void Menu::AfterInit(v8::Isolate* isolate) { void Menu::AfterInit(v8::Isolate* isolate) {
@ -153,6 +157,14 @@ bool Menu::IsVisibleAt(int index) const {
return model_->IsVisibleAt(index); return model_->IsVisibleAt(index);
} }
void Menu::OnMenuWillClose() {
Emit("menu-will-close");
}
void Menu::OnMenuWillShow() {
Emit("menu-will-show");
}
// static // static
void Menu::BuildPrototype(v8::Isolate* isolate, void Menu::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) { v8::Local<v8::FunctionTemplate> prototype) {

View file

@ -18,7 +18,8 @@ namespace atom {
namespace api { namespace api {
class Menu : public mate::TrackableObject<Menu>, class Menu : public mate::TrackableObject<Menu>,
public AtomMenuModel::Delegate { public AtomMenuModel::Delegate,
public AtomMenuModel::Observer {
public: public:
static mate::WrappableBase* New(mate::Arguments* args); static mate::WrappableBase* New(mate::Arguments* args);
@ -60,6 +61,10 @@ class Menu : public mate::TrackableObject<Menu>,
std::unique_ptr<AtomMenuModel> model_; std::unique_ptr<AtomMenuModel> model_;
Menu* parent_; Menu* parent_;
// Observable:
void OnMenuWillClose() override;
void OnMenuWillShow() override;
private: private:
void InsertItemAt(int index, int command_id, const base::string16& label); void InsertItemAt(int index, int command_id, const base::string16& label);
void InsertSeparatorAt(int index); void InsertSeparatorAt(int index);

View file

@ -42,8 +42,16 @@ bool AtomMenuModel::GetAcceleratorAtWithParams(
void AtomMenuModel::MenuWillClose() { void AtomMenuModel::MenuWillClose() {
ui::SimpleMenuModel::MenuWillClose(); ui::SimpleMenuModel::MenuWillClose();
for (Observer& observer : observers_) for (Observer& observer : observers_) {
observer.MenuWillClose(); observer.OnMenuWillClose();
}
}
void AtomMenuModel::MenuWillShow() {
ui::SimpleMenuModel::MenuWillShow();
for (Observer& observer : observers_) {
observer.OnMenuWillShow();
}
} }
AtomMenuModel* AtomMenuModel::GetSubmenuModelAt(int index) { AtomMenuModel* AtomMenuModel::GetSubmenuModelAt(int index) {

View file

@ -36,8 +36,11 @@ class AtomMenuModel : public ui::SimpleMenuModel {
public: public:
virtual ~Observer() {} virtual ~Observer() {}
// Notifies the menu will open.
virtual void OnMenuWillShow() {}
// Notifies the menu has been closed. // Notifies the menu has been closed.
virtual void MenuWillClose() {} virtual void OnMenuWillClose() {}
}; };
explicit AtomMenuModel(Delegate* delegate); explicit AtomMenuModel(Delegate* delegate);
@ -54,6 +57,7 @@ class AtomMenuModel : public ui::SimpleMenuModel {
// ui::SimpleMenuModel: // ui::SimpleMenuModel:
void MenuWillClose() override; void MenuWillClose() override;
void MenuWillShow() override;
using SimpleMenuModel::GetSubmenuModelAt; using SimpleMenuModel::GetSubmenuModelAt;
AtomMenuModel* GetSubmenuModelAt(int index); AtomMenuModel* GetSubmenuModelAt(int index);

View file

@ -35,7 +35,7 @@ class TrayIconCocoa : public TrayIcon,
protected: protected:
// AtomMenuModel::Observer: // AtomMenuModel::Observer:
void MenuWillClose() override; void OnMenuWillClose() override;
private: private:
// Atom custom view for NSStatusItem. // Atom custom view for NSStatusItem.

View file

@ -461,7 +461,7 @@ gfx::Rect TrayIconCocoa::GetBounds() {
return bounds; return bounds;
} }
void TrayIconCocoa::MenuWillClose() { void TrayIconCocoa::OnMenuWillClose() {
[status_item_view_ setNeedsDisplay:YES]; [status_item_view_ setNeedsDisplay:YES];
} }

View file

@ -99,6 +99,29 @@ Returns `MenuItem` the item with the specified `id`
Inserts the `menuItem` to the `pos` position of the menu. Inserts the `menuItem` to the `pos` position of the menu.
### Instance Events
Objects created with `new Menu` emit the following events:
**Note:** Some events are only available on specific operating systems and are
labeled as such.
#### Event: 'menu-will-show'
Returns:
* `event` Event
Emitted when `menu.popup()` is called.
#### Event: 'menu-will-close'
Returns:
* `event` Event
Emitted when a popup is closed either manually or with `menu.closePopup()`.
### Instance Properties ### Instance Properties
`menu` objects also have the following properties: `menu` objects also have the following properties:

View file

@ -284,6 +284,17 @@ describe('Menu module', () => {
return closeWindow(w).then(() => { w = null }) return closeWindow(w).then(() => { w = null })
}) })
it('should emit menu-will-show event', (done) => {
menu.on('menu-will-show', () => { done() })
menu.popup(w)
})
it('should emit menu-will-close event', (done) => {
menu.on('menu-will-close', () => { done() })
menu.popup(w)
menu.closePopup()
})
it('returns immediately', () => { it('returns immediately', () => {
const { browserWindow, x, y } = menu.popup(w, {x: 100, y: 101}) const { browserWindow, x, y } = menu.popup(w, {x: 100, y: 101})