// Copyright (c) 2014 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/menu_bar.h" #if defined(USE_X11) #include "gtk/gtk.h" #endif #include "atom/browser/ui/views/menu_delegate.h" #include "atom/browser/ui/views/submenu_button.h" #include "ui/base/models/menu_model.h" #include "ui/views/background.h" #include "ui/views/layout/box_layout.h" #if defined(OS_WIN) #include "ui/gfx/color_utils.h" #elif defined(USE_X11) #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" #endif namespace atom { namespace { const char kViewClassName[] = "ElectronMenuBar"; // Default color of the menu bar. const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233); #if defined(USE_X11) void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight, SkColor* hover, SkColor* background) { GtkWidget* menu_bar = gtk_menu_bar_new(); GtkStyle* style = gtk_rc_get_style(menu_bar); *enabled = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]); *disabled = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]); *highlight = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]); *hover = libgtkui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]); *background = libgtkui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]); gtk_widget_destroy(menu_bar); } #endif } // namespace MenuBar::MenuBar(NativeWindow* window) : background_color_(kDefaultColor), menu_model_(NULL), window_(window) { UpdateMenuBarColor(); SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal)); } MenuBar::~MenuBar() { } void MenuBar::SetMenu(AtomMenuModel* model) { menu_model_ = model; RemoveAllChildViews(true); for (int i = 0; i < model->GetItemCount(); ++i) { SubmenuButton* button = new SubmenuButton(model->GetLabelAt(i), this, background_color_); button->set_tag(i); #if defined(USE_X11) button->SetTextColor(views::Button::STATE_NORMAL, enabled_color_); button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_); button->SetTextColor(views::Button::STATE_PRESSED, highlight_color_); button->SetTextColor(views::Button::STATE_HOVERED, hover_color_); button->SetUnderlineColor(enabled_color_); #elif defined(OS_WIN) button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_GRAYTEXT)); #endif AddChildView(button); } } void MenuBar::SetAcceleratorVisibility(bool visible) { for (int i = 0; i < child_count(); ++i) static_cast(child_at(i))->SetAcceleratorVisibility(visible); } int MenuBar::GetAcceleratorIndex(base::char16 key) { for (int i = 0; i < child_count(); ++i) { SubmenuButton* button = static_cast(child_at(i)); if (button->accelerator() == key) return i; } return -1; } void MenuBar::ActivateAccelerator(base::char16 key) { int i = GetAcceleratorIndex(key); if (i != -1) static_cast(child_at(i))->Activate(nullptr); } int MenuBar::GetItemCount() const { return menu_model_->GetItemCount(); } bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point, AtomMenuModel** menu_model, views::MenuButton** button) { gfx::Point location(point); views::View::ConvertPointFromScreen(this, &location); if (location.x() < 0 || location.x() >= width() || location.y() < 0 || location.y() >= height()) return false; for (int i = 0; i < child_count(); ++i) { views::View* view = child_at(i); if (view->GetMirroredBounds().Contains(location) && (menu_model_->GetTypeAt(i) == AtomMenuModel::TYPE_SUBMENU)) { *menu_model = menu_model_->GetSubmenuModelAt(i); *button = static_cast(view); return true; } } return false; } const char* MenuBar::GetClassName() const { return kViewClassName; } void MenuBar::OnMenuButtonClicked(views::MenuButton* source, const gfx::Point& point, const ui::Event* event) { // Hide the accelerator when a submenu is activated. SetAcceleratorVisibility(false); if (!menu_model_) return; if (!window_->IsFocused()) window_->Focus(true); int id = source->tag(); AtomMenuModel::ItemType type = menu_model_->GetTypeAt(id); if (type != AtomMenuModel::TYPE_SUBMENU) { menu_model_->ActivatedAt(id, 0); return; } // Deleted in MenuDelegate::OnMenuClosed MenuDelegate* menu_delegate = new MenuDelegate(this); menu_delegate->RunMenu(menu_model_->GetSubmenuModelAt(id), source); } void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) { UpdateMenuBarColor(); } void MenuBar::UpdateMenuBarColor() { #if defined(OS_WIN) background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR); #elif defined(USE_X11) GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_, &hover_color_, &background_color_); #endif set_background(views::Background::CreateSolidBackground(background_color_)); } } // namespace atom