Browse Source

views: Show menubar's submenu when "Alt+Key" is pressed.

Cheng Zhao 10 years ago
parent
commit
ba41634ad6

+ 10 - 3
atom/browser/native_window_views.cc

@@ -572,9 +572,16 @@ void NativeWindowViews::HandleKeyboardEvent(
     const content::NativeWebKeyboardEvent& event) {
   keyboard_event_handler_->HandleKeyboardEvent(event, GetFocusManager());
 
-  if (menu_bar_ && menu_bar_visible_ && IsAltKey(event)) {
-    menu_bar_->SetAcceleratorVisibility(
-        event.type == blink::WebInputEvent::RawKeyDown);
+  if (menu_bar_ && menu_bar_visible_) {
+    // Toggle accelerator when "Alt" is pressed.
+    if (IsAltKey(event))
+      menu_bar_->SetAcceleratorVisibility(
+          event.type == blink::WebInputEvent::RawKeyDown);
+
+    // Show the submenu when "Alt+Key" is pressed.
+    if (event.type == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) &&
+        IsAltModifier(event))
+      menu_bar_->ActivateAccelerator(event.windowsKeyCode);
   }
 
   if (!menu_bar_autohide_)

+ 11 - 0
atom/browser/ui/views/menu_bar.cc

@@ -90,6 +90,17 @@ void MenuBar::SetAcceleratorVisibility(bool visible) {
     static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
 }
 
+void MenuBar::ActivateAccelerator(base::char16 key) {
+  for (int i = 0; i < child_count(); ++i) {
+    SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
+    if (button->accelerator() == key) {
+      SetAcceleratorVisibility(false);
+      button->Activate();
+      return;
+    }
+  }
+}
+
 int MenuBar::GetItemCount() const {
   return menu_model_->GetItemCount();
 }

+ 3 - 0
atom/browser/ui/views/menu_bar.h

@@ -34,6 +34,9 @@ class MenuBar : public views::View,
   // Shows underline under accelerators.
   void SetAcceleratorVisibility(bool visible);
 
+  // Shows the submenu whose accelerator is |key|.
+  void ActivateAccelerator(base::char16 key);
+
   // Returns there are how many items in the root menu.
   int GetItemCount() const;
 

+ 10 - 4
atom/browser/ui/views/submenu_button.cc

@@ -27,15 +27,18 @@ SubmenuButton::SubmenuButton(views::ButtonListener* listener,
                              views::MenuButtonListener* menu_button_listener)
     : views::MenuButton(listener, FilterAccecelator(title),
                         menu_button_listener, false),
+      accelerator_(0),
       show_underline_(false),
       underline_start_(-1),
       underline_end_(-1),
       text_width_(0),
       text_height_(0),
       underline_color_(SK_ColorBLACK) {
-  GetUnderlinePosition(title, &underline_start_, &underline_end_);
-  gfx::Canvas::SizeStringInt(text(), font_list(), &text_width_,
-                             &text_height_, 0, 0);
+  if (GetUnderlinePosition(title, &underline_start_, &underline_end_)) {
+    gfx::Canvas::SizeStringInt(text(), font_list(), &text_width_,
+                               &text_height_, 0, 0);
+    accelerator_ = text()[underline_start_];
+  }
 }
 
 SubmenuButton::~SubmenuButton() {
@@ -65,14 +68,17 @@ void SubmenuButton::OnPaint(gfx::Canvas* canvas) {
   }
 }
 
-void SubmenuButton::GetUnderlinePosition(
+bool SubmenuButton::GetUnderlinePosition(
     const base::string16& text, int* start, int* end) {
   int pos, span;
   gfx::RemoveAcceleratorChar(text, '&', &pos, &span);
   if (pos > -1 && span != 0) {
     GetCharacterPosition(text, pos, start);
     GetCharacterPosition(text, pos + span, end);
+    return true;
   }
+
+  return false;
 }
 
 void SubmenuButton::GetCharacterPosition(

+ 5 - 1
atom/browser/ui/views/submenu_button.h

@@ -20,15 +20,19 @@ class SubmenuButton : public views::MenuButton {
   void SetAcceleratorVisibility(bool visible);
   void SetUnderlineColor(SkColor color);
 
+  base::char16 accelerator() const { return accelerator_; }
+
   // views::MenuButton:
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
 
  private:
-  void GetUnderlinePosition(
+  bool GetUnderlinePosition(
       const base::string16& text, int* start, int* end);
   void GetCharacterPosition(
       const base::string16& text, int index, int* pos);
 
+  base::char16 accelerator_;
+
   bool show_underline_;
 
   int underline_start_;