win: Update states when setting checked property.

This commit is contained in:
Cheng Zhao 2014-05-26 11:34:36 +08:00
parent 6ee437e9bf
commit dfa1ae1c20
8 changed files with 50 additions and 9 deletions

View file

@ -44,7 +44,9 @@ v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
} // namespace } // namespace
Menu::Menu() : model_(new ui::SimpleMenuModel(this)) { Menu::Menu()
: model_(new ui::SimpleMenuModel(this)),
parent_(NULL) {
} }
Menu::~Menu() { Menu::~Menu() {
@ -167,6 +169,7 @@ void Menu::InsertSubMenuAt(int index,
int command_id, int command_id,
const base::string16& label, const base::string16& label,
Menu* menu) { Menu* menu) {
menu->parent_ = this;
model_->InsertSubMenuAt(index, command_id, label, menu->model_.get()); model_->InsertSubMenuAt(index, command_id, label, menu->model_.get());
} }
@ -231,6 +234,9 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isVisibleAt", &Menu::IsVisibleAt) .SetMethod("isVisibleAt", &Menu::IsVisibleAt)
#if defined(OS_WIN) || defined(TOOLKIT_GTK) #if defined(OS_WIN) || defined(TOOLKIT_GTK)
.SetMethod("_attachToWindow", &Menu::AttachToWindow) .SetMethod("_attachToWindow", &Menu::AttachToWindow)
#endif
#if defined(OS_WIN)
.SetMethod("_updateStates", &Menu::UpdateStates)
#endif #endif
.SetMethod("_popup", &Menu::Popup); .SetMethod("_popup", &Menu::Popup);
} }

View file

@ -54,6 +54,7 @@ class Menu : public mate::Wrappable,
virtual void Popup(Window* window) = 0; virtual void Popup(Window* window) = 0;
scoped_ptr<ui::SimpleMenuModel> model_; scoped_ptr<ui::SimpleMenuModel> model_;
Menu* parent_;
private: private:
void InsertItemAt(int index, int command_id, const base::string16& label); void InsertItemAt(int index, int command_id, const base::string16& label);
@ -80,8 +81,12 @@ class Menu : public mate::Wrappable,
bool IsEnabledAt(int index) const; bool IsEnabledAt(int index) const;
bool IsVisibleAt(int index) const; bool IsVisibleAt(int index) const;
#if defined(OS_WIN)
virtual void UpdateStates() = 0;
#endif
#if defined(OS_WIN) || defined(TOOLKIT_GTK) #if defined(OS_WIN) || defined(TOOLKIT_GTK)
void AttachToWindow(Window* window); virtual void AttachToWindow(Window* window) = 0;
#endif #endif
DISALLOW_COPY_AND_ASSIGN(Menu); DISALLOW_COPY_AND_ASSIGN(Menu);

View file

@ -37,7 +37,7 @@ void MenuGtk::Popup(Window* window) {
menu_gtk_->PopupAsContext(point, triggering_event_time); menu_gtk_->PopupAsContext(point, triggering_event_time);
} }
void Menu::AttachToWindow(Window* window) { void MenuGtk::AttachToWindow(Window* window) {
static_cast<NativeWindowGtk*>(window->window())->SetMenu(model_.get()); static_cast<NativeWindowGtk*>(window->window())->SetMenu(model_.get());
} }

View file

@ -19,6 +19,7 @@ class MenuGtk : public Menu,
protected: protected:
virtual void Popup(Window* window) OVERRIDE; virtual void Popup(Window* window) OVERRIDE;
virtual void AttachToWindow(Window* window) OVERRIDE;
private: private:
scoped_ptr<::MenuGtk> menu_gtk_; scoped_ptr<::MenuGtk> menu_gtk_;

View file

@ -15,17 +15,28 @@ namespace atom {
namespace api { namespace api {
MenuWin::MenuWin() { MenuWin::MenuWin() : menu_(NULL) {
} }
void MenuWin::Popup(Window* window) { void MenuWin::Popup(Window* window) {
gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
menu_.reset(new atom::Menu2(model_.get())); popup_menu_.reset(new atom::Menu2(model_.get()));
menu_ = popup_menu_.get();
menu_->RunContextMenuAt(cursor); menu_->RunContextMenuAt(cursor);
} }
void Menu::AttachToWindow(Window* window) { void MenuWin::UpdateStates() {
static_cast<NativeWindowWin*>(window->window())->SetMenu(model_.get()); MenuWin* top = this;
while (top->parent_)
top = static_cast<MenuWin*>(top->parent_);
if (top->menu_)
top->menu_->UpdateStates();
}
void MenuWin::AttachToWindow(Window* window) {
NativeWindowWin* nw = static_cast<NativeWindowWin*>(window->window());
nw->SetMenu(model_.get());
menu_ = nw->menu();
} }
// static // static

View file

@ -19,9 +19,12 @@ class MenuWin : public Menu {
protected: protected:
virtual void Popup(Window* window) OVERRIDE; virtual void Popup(Window* window) OVERRIDE;
virtual void UpdateStates() OVERRIDE;
virtual void AttachToWindow(Window* window) OVERRIDE;
private: private:
scoped_ptr<atom::Menu2> menu_; atom::Menu2* menu_; // Weak ref, could be window menu or popup menu.
scoped_ptr<atom::Menu2> popup_menu_;
DISALLOW_COPY_AND_ASSIGN(MenuWin); DISALLOW_COPY_AND_ASSIGN(MenuWin);
}; };

View file

@ -64,7 +64,18 @@ Menu::insert = (pos, item) ->
switch item.type switch item.type
when 'normal' then @insertItem pos, item.commandId, item.label when 'normal' then @insertItem pos, item.commandId, item.label
when 'checkbox' then @insertCheckItem pos, item.commandId, item.label when 'checkbox'
# Update states when clicked on Windows.
if process.platform is 'win32'
v8Util.setHiddenValue item, 'checked', item.checked
Object.defineProperty item, 'checked',
enumerable: true
get: -> v8Util.getHiddenValue item, 'checked'
set: (val) =>
v8Util.setHiddenValue item, 'checked', val
@_updateStates() if process.platform is 'win32'
@insertCheckItem pos, item.commandId, item.label
when 'separator' then @insertSeparator pos when 'separator' then @insertSeparator pos
when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu
when 'radio' when 'radio'
@ -83,6 +94,9 @@ Menu::insert = (pos, item) ->
v8Util.setHiddenValue otherItem, 'checked', false v8Util.setHiddenValue otherItem, 'checked', false
v8Util.setHiddenValue item, 'checked', true v8Util.setHiddenValue item, 'checked', true
# Update states when clicked on Windows.
@_updateStates() if process.platform is 'win32'
@insertRadioItem pos, item.commandId, item.label, item.groupId @insertRadioItem pos, item.commandId, item.label, item.groupId
@setSublabel pos, item.sublabel if item.sublabel? @setSublabel pos, item.sublabel if item.sublabel?

View file

@ -81,6 +81,7 @@ class NativeWindowWin : public NativeWindow,
void SetMenu(ui::MenuModel* menu_model); void SetMenu(ui::MenuModel* menu_model);
views::Widget* window() const { return window_.get(); } views::Widget* window() const { return window_.get(); }
atom::Menu2* menu() const { return menu_.get(); }
SkRegion* draggable_region() { return draggable_region_.get(); } SkRegion* draggable_region() { return draggable_region_.get(); }
protected: protected: