123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- // Copyright (c) 2018 GitHub, Inc.
- // Use of this source code is governed by the MIT license that can be
- // found in the LICENSE file.
- #include "atom/browser/ui/views/root_view.h"
- #include "atom/browser/native_window.h"
- #include "atom/browser/ui/views/menu_bar.h"
- #include "content/public/browser/native_web_keyboard_event.h"
- namespace atom {
- namespace {
- // The menu bar height in pixels.
- #if defined(OS_WIN)
- const int kMenuBarHeight = 20;
- #else
- const int kMenuBarHeight = 25;
- #endif
- bool IsAltKey(const content::NativeWebKeyboardEvent& event) {
- return event.windows_key_code == ui::VKEY_MENU;
- }
- bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
- typedef content::NativeWebKeyboardEvent::Modifiers Modifiers;
- int modifiers = event.GetModifiers();
- modifiers &= ~Modifiers::kNumLockOn;
- modifiers &= ~Modifiers::kCapsLockOn;
- return (modifiers == Modifiers::kAltKey) ||
- (modifiers == (Modifiers::kAltKey | Modifiers::kIsLeft)) ||
- (modifiers == (Modifiers::kAltKey | Modifiers::kIsRight));
- }
- } // namespace
- RootView::RootView(NativeWindow* window) : window_(window) {
- set_owned_by_client();
- }
- RootView::~RootView() {}
- void RootView::SetMenu(AtomMenuModel* menu_model) {
- if (menu_model == nullptr) {
- // Remove accelerators
- accelerator_table_.clear();
- GetFocusManager()->UnregisterAccelerators(this);
- // and menu bar.
- SetMenuBarVisibility(false);
- menu_bar_.reset();
- return;
- }
- RegisterAccelerators(menu_model);
- // Do not show menu bar in frameless window.
- if (!window_->has_frame())
- return;
- if (!menu_bar_) {
- menu_bar_.reset(new MenuBar(this));
- menu_bar_->set_owned_by_client();
- if (!menu_bar_autohide_)
- SetMenuBarVisibility(true);
- }
- menu_bar_->SetMenu(menu_model);
- Layout();
- }
- bool RootView::HasMenu() const {
- return !!menu_bar_;
- }
- int RootView::GetMenuBarHeight() const {
- return kMenuBarHeight;
- }
- void RootView::SetAutoHideMenuBar(bool auto_hide) {
- menu_bar_autohide_ = auto_hide;
- }
- bool RootView::IsMenuBarAutoHide() const {
- return menu_bar_autohide_;
- }
- void RootView::SetMenuBarVisibility(bool visible) {
- if (!window_->content_view() || !menu_bar_ || menu_bar_visible_ == visible)
- return;
- // Always show the accelerator when the auto-hide menu bar shows.
- if (menu_bar_autohide_)
- menu_bar_->SetAcceleratorVisibility(visible);
- menu_bar_visible_ = visible;
- if (visible) {
- DCHECK_EQ(child_count(), 1);
- AddChildView(menu_bar_.get());
- } else {
- DCHECK_EQ(child_count(), 2);
- RemoveChildView(menu_bar_.get());
- }
- Layout();
- }
- bool RootView::IsMenuBarVisible() const {
- return menu_bar_visible_;
- }
- void RootView::HandleKeyEvent(const content::NativeWebKeyboardEvent& event) {
- if (!menu_bar_)
- return;
- // Show accelerator when "Alt" is pressed.
- if (menu_bar_visible_ && IsAltKey(event))
- menu_bar_->SetAcceleratorVisibility(event.GetType() ==
- blink::WebInputEvent::kRawKeyDown);
- // Show the submenu when "Alt+Key" is pressed.
- if (event.GetType() == blink::WebInputEvent::kRawKeyDown &&
- !IsAltKey(event) && IsAltModifier(event)) {
- if (!menu_bar_visible_ &&
- (menu_bar_->HasAccelerator(event.windows_key_code)))
- SetMenuBarVisibility(true);
- menu_bar_->ActivateAccelerator(event.windows_key_code);
- return;
- }
- if (!menu_bar_autohide_)
- return;
- // Toggle the menu bar only when a single Alt is released.
- if (event.GetType() == blink::WebInputEvent::kRawKeyDown && IsAltKey(event)) {
- // When a single Alt is pressed:
- menu_bar_alt_pressed_ = true;
- } else if (event.GetType() == blink::WebInputEvent::kKeyUp &&
- IsAltKey(event) && menu_bar_alt_pressed_) {
- // When a single Alt is released right after a Alt is pressed:
- menu_bar_alt_pressed_ = false;
- SetMenuBarVisibility(!menu_bar_visible_);
- } else {
- // When any other keys except single Alt have been pressed/released:
- menu_bar_alt_pressed_ = false;
- }
- }
- void RootView::ResetAltState() {
- menu_bar_alt_pressed_ = false;
- }
- void RootView::Layout() {
- if (!window_->content_view()) // Not ready yet.
- return;
- const auto menu_bar_bounds =
- menu_bar_visible_ ? gfx::Rect(0, 0, size().width(), kMenuBarHeight)
- : gfx::Rect();
- if (menu_bar_)
- menu_bar_->SetBoundsRect(menu_bar_bounds);
- window_->content_view()->SetBoundsRect(
- gfx::Rect(0, menu_bar_bounds.height(), size().width(),
- size().height() - menu_bar_bounds.height()));
- }
- gfx::Size RootView::GetMinimumSize() const {
- return window_->GetMinimumSize();
- }
- gfx::Size RootView::GetMaximumSize() const {
- return window_->GetMaximumSize();
- }
- bool RootView::AcceleratorPressed(const ui::Accelerator& accelerator) {
- return accelerator_util::TriggerAcceleratorTableCommand(&accelerator_table_,
- accelerator);
- }
- void RootView::RegisterAccelerators(AtomMenuModel* menu_model) {
- // Clear previous accelerators.
- views::FocusManager* focus_manager = GetFocusManager();
- accelerator_table_.clear();
- focus_manager->UnregisterAccelerators(this);
- // Register accelerators with focus manager.
- accelerator_util::GenerateAcceleratorTable(&accelerator_table_, menu_model);
- for (const auto& iter : accelerator_table_) {
- focus_manager->RegisterAccelerator(
- iter.first, ui::AcceleratorManager::kNormalPriority, this);
- }
- }
- } // namespace atom
|