Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: ui/views/controls/menu/submenu_view.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/controls/menu/submenu_view.h ('k') | ui/views/controls/message_box_view.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/controls/menu/submenu_view.cc
diff --git a/ui/views/controls/menu/submenu_view.cc b/ui/views/controls/menu/submenu_view.cc
deleted file mode 100644
index e3687403cfae51e17ce12f5243f309af8e52b4c6..0000000000000000000000000000000000000000
--- a/ui/views/controls/menu/submenu_view.cc
+++ /dev/null
@@ -1,511 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/controls/menu/submenu_view.h"
-
-#include <algorithm>
-
-#include "base/compiler_specific.h"
-#include "ui/accessibility/ax_view_state.h"
-#include "ui/events/event.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/geometry/safe_integer_conversions.h"
-#include "ui/views/controls/menu/menu_config.h"
-#include "ui/views/controls/menu/menu_controller.h"
-#include "ui/views/controls/menu/menu_host.h"
-#include "ui/views/controls/menu/menu_item_view.h"
-#include "ui/views/controls/menu/menu_scroll_view_container.h"
-#include "ui/views/widget/root_view.h"
-#include "ui/views/widget/widget.h"
-
-namespace {
-
-// Height of the drop indicator. This should be an even number.
-const int kDropIndicatorHeight = 2;
-
-// Color of the drop indicator.
-const SkColor kDropIndicatorColor = SK_ColorBLACK;
-
-} // namespace
-
-namespace views {
-
-// static
-const char SubmenuView::kViewClassName[] = "SubmenuView";
-
-SubmenuView::SubmenuView(MenuItemView* parent)
- : parent_menu_item_(parent),
- host_(NULL),
- drop_item_(NULL),
- drop_position_(MenuDelegate::DROP_NONE),
- scroll_view_container_(NULL),
- max_minor_text_width_(0),
- minimum_preferred_width_(0),
- resize_open_menu_(false),
- scroll_animator_(new ScrollAnimator(this)),
- roundoff_error_(0),
- prefix_selector_(this) {
- DCHECK(parent);
- // We'll delete ourselves, otherwise the ScrollView would delete us on close.
- set_owned_by_client();
-}
-
-SubmenuView::~SubmenuView() {
- // The menu may not have been closed yet (it will be hidden, but not
- // necessarily closed).
- Close();
-
- delete scroll_view_container_;
-}
-
-int SubmenuView::GetMenuItemCount() {
- int count = 0;
- for (int i = 0; i < child_count(); ++i) {
- if (child_at(i)->id() == MenuItemView::kMenuItemViewID)
- count++;
- }
- return count;
-}
-
-MenuItemView* SubmenuView::GetMenuItemAt(int index) {
- for (int i = 0, count = 0; i < child_count(); ++i) {
- if (child_at(i)->id() == MenuItemView::kMenuItemViewID &&
- count++ == index) {
- return static_cast<MenuItemView*>(child_at(i));
- }
- }
- NOTREACHED();
- return NULL;
-}
-
-void SubmenuView::ChildPreferredSizeChanged(View* child) {
- if (!resize_open_menu_)
- return;
-
- MenuItemView *item = GetMenuItem();
- MenuController* controller = item->GetMenuController();
-
- if (controller) {
- bool dir;
- gfx::Rect bounds = controller->CalculateMenuBounds(item, false, &dir);
- Reposition(bounds);
- }
-}
-
-void SubmenuView::Layout() {
- // We're in a ScrollView, and need to set our width/height ourselves.
- if (!parent())
- return;
-
- // Use our current y, unless it means part of the menu isn't visible anymore.
- int pref_height = GetPreferredSize().height();
- int new_y;
- if (pref_height > parent()->height())
- new_y = std::max(parent()->height() - pref_height, y());
- else
- new_y = 0;
- SetBounds(x(), new_y, parent()->width(), pref_height);
-
- gfx::Insets insets = GetInsets();
- int x = insets.left();
- int y = insets.top();
- int menu_item_width = width() - insets.width();
- for (int i = 0; i < child_count(); ++i) {
- View* child = child_at(i);
- if (child->visible()) {
- int child_height = child->GetHeightForWidth(menu_item_width);
- child->SetBounds(x, y, menu_item_width, child_height);
- y += child_height;
- }
- }
-}
-
-gfx::Size SubmenuView::GetPreferredSize() const {
- if (!has_children())
- return gfx::Size();
-
- max_minor_text_width_ = 0;
- // The maximum width of items which contain maybe a label and multiple views.
- int max_complex_width = 0;
- // The max. width of items which contain a label and maybe an accelerator.
- int max_simple_width = 0;
-
- // We perform the size calculation in two passes. In the first pass, we
- // calculate the width of the menu. In the second, we calculate the height
- // using that width. This allows views that have flexible widths to adjust
- // accordingly.
- for (int i = 0; i < child_count(); ++i) {
- const View* child = child_at(i);
- if (!child->visible())
- continue;
- if (child->id() == MenuItemView::kMenuItemViewID) {
- const MenuItemView* menu = static_cast<const MenuItemView*>(child);
- const MenuItemView::MenuItemDimensions& dimensions =
- menu->GetDimensions();
- max_simple_width = std::max(
- max_simple_width, dimensions.standard_width);
- max_minor_text_width_ =
- std::max(max_minor_text_width_, dimensions.minor_text_width);
- max_complex_width = std::max(max_complex_width,
- dimensions.standard_width + dimensions.children_width);
- } else {
- max_complex_width = std::max(max_complex_width,
- child->GetPreferredSize().width());
- }
- }
- if (max_minor_text_width_ > 0) {
- max_minor_text_width_ +=
- GetMenuItem()->GetMenuConfig().label_to_minor_text_padding;
- }
- // Finish calculating our optimum width.
- gfx::Insets insets = GetInsets();
- int width = std::max(max_complex_width,
- std::max(max_simple_width + max_minor_text_width_ +
- insets.width(),
- minimum_preferred_width_ - 2 * insets.width()));
-
- // Then, the height for that width.
- int height = 0;
- int menu_item_width = width - insets.width();
- for (int i = 0; i < child_count(); ++i) {
- const View* child = child_at(i);
- height += child->visible() ? child->GetHeightForWidth(menu_item_width) : 0;
- }
-
- return gfx::Size(width, height + insets.height());
-}
-
-void SubmenuView::GetAccessibleState(ui::AXViewState* state) {
- // Inherit most of the state from the parent menu item, except the role.
- if (GetMenuItem())
- GetMenuItem()->GetAccessibleState(state);
- state->role = ui::AX_ROLE_MENU_LIST_POPUP;
-}
-
-ui::TextInputClient* SubmenuView::GetTextInputClient() {
- return &prefix_selector_;
-}
-
-void SubmenuView::PaintChildren(gfx::Canvas* canvas,
- const views::CullSet& cull_set) {
- View::PaintChildren(canvas, cull_set);
-
- if (drop_item_ && drop_position_ != MenuDelegate::DROP_ON)
- PaintDropIndicator(canvas, drop_item_, drop_position_);
-}
-
-bool SubmenuView::GetDropFormats(
- int* formats,
- std::set<OSExchangeData::CustomFormat>* custom_formats) {
- DCHECK(GetMenuItem()->GetMenuController());
- return GetMenuItem()->GetMenuController()->GetDropFormats(this, formats,
- custom_formats);
-}
-
-bool SubmenuView::AreDropTypesRequired() {
- DCHECK(GetMenuItem()->GetMenuController());
- return GetMenuItem()->GetMenuController()->AreDropTypesRequired(this);
-}
-
-bool SubmenuView::CanDrop(const OSExchangeData& data) {
- DCHECK(GetMenuItem()->GetMenuController());
- return GetMenuItem()->GetMenuController()->CanDrop(this, data);
-}
-
-void SubmenuView::OnDragEntered(const ui::DropTargetEvent& event) {
- DCHECK(GetMenuItem()->GetMenuController());
- GetMenuItem()->GetMenuController()->OnDragEntered(this, event);
-}
-
-int SubmenuView::OnDragUpdated(const ui::DropTargetEvent& event) {
- DCHECK(GetMenuItem()->GetMenuController());
- return GetMenuItem()->GetMenuController()->OnDragUpdated(this, event);
-}
-
-void SubmenuView::OnDragExited() {
- DCHECK(GetMenuItem()->GetMenuController());
- GetMenuItem()->GetMenuController()->OnDragExited(this);
-}
-
-int SubmenuView::OnPerformDrop(const ui::DropTargetEvent& event) {
- DCHECK(GetMenuItem()->GetMenuController());
- return GetMenuItem()->GetMenuController()->OnPerformDrop(this, event);
-}
-
-bool SubmenuView::OnMouseWheel(const ui::MouseWheelEvent& e) {
- gfx::Rect vis_bounds = GetVisibleBounds();
- int menu_item_count = GetMenuItemCount();
- if (vis_bounds.height() == height() || !menu_item_count) {
- // All menu items are visible, nothing to scroll.
- return true;
- }
-
- // Find the index of the first menu item whose y-coordinate is >= visible
- // y-coordinate.
- int i = 0;
- while ((i < menu_item_count) && (GetMenuItemAt(i)->y() < vis_bounds.y()))
- ++i;
- if (i == menu_item_count)
- return true;
- int first_vis_index = std::max(0,
- (GetMenuItemAt(i)->y() == vis_bounds.y()) ? i : i - 1);
-
- // If the first item isn't entirely visible, make it visible, otherwise make
- // the next/previous one entirely visible. If enough wasn't scrolled to show
- // any new rows, then just scroll the amount so that smooth scrolling using
- // the trackpad is possible.
- int delta = abs(e.y_offset() / ui::MouseWheelEvent::kWheelDelta);
- if (delta == 0)
- return OnScroll(0, e.y_offset());
- for (bool scroll_up = (e.y_offset() > 0); delta != 0; --delta) {
- int scroll_target;
- if (scroll_up) {
- if (GetMenuItemAt(first_vis_index)->y() == vis_bounds.y()) {
- if (first_vis_index == 0)
- break;
- first_vis_index--;
- }
- scroll_target = GetMenuItemAt(first_vis_index)->y();
- } else {
- if (first_vis_index + 1 == menu_item_count)
- break;
- scroll_target = GetMenuItemAt(first_vis_index + 1)->y();
- if (GetMenuItemAt(first_vis_index)->y() == vis_bounds.y())
- first_vis_index++;
- }
- ScrollRectToVisible(gfx::Rect(gfx::Point(0, scroll_target),
- vis_bounds.size()));
- vis_bounds = GetVisibleBounds();
- }
-
- return true;
-}
-
-void SubmenuView::OnGestureEvent(ui::GestureEvent* event) {
- bool handled = true;
- switch (event->type()) {
- case ui::ET_GESTURE_SCROLL_BEGIN:
- scroll_animator_->Stop();
- break;
- case ui::ET_GESTURE_SCROLL_UPDATE:
- handled = OnScroll(0, event->details().scroll_y());
- break;
- case ui::ET_GESTURE_SCROLL_END:
- break;
- case ui::ET_SCROLL_FLING_START:
- if (event->details().velocity_y() != 0.0f)
- scroll_animator_->Start(0, event->details().velocity_y());
- break;
- case ui::ET_GESTURE_TAP_DOWN:
- case ui::ET_SCROLL_FLING_CANCEL:
- if (scroll_animator_->is_scrolling())
- scroll_animator_->Stop();
- else
- handled = false;
- break;
- default:
- handled = false;
- break;
- }
- if (handled)
- event->SetHandled();
-}
-
-int SubmenuView::GetRowCount() {
- return GetMenuItemCount();
-}
-
-int SubmenuView::GetSelectedRow() {
- int row = 0;
- for (int i = 0; i < child_count(); ++i) {
- if (child_at(i)->id() != MenuItemView::kMenuItemViewID)
- continue;
-
- if (static_cast<MenuItemView*>(child_at(i))->IsSelected())
- return row;
-
- row++;
- }
-
- return -1;
-}
-
-void SubmenuView::SetSelectedRow(int row) {
- GetMenuItem()->GetMenuController()->SetSelection(
- GetMenuItemAt(row),
- MenuController::SELECTION_DEFAULT);
-}
-
-base::string16 SubmenuView::GetTextForRow(int row) {
- return GetMenuItemAt(row)->title();
-}
-
-bool SubmenuView::IsShowing() {
- return host_ && host_->IsMenuHostVisible();
-}
-
-void SubmenuView::ShowAt(Widget* parent,
- const gfx::Rect& bounds,
- bool do_capture) {
- if (host_) {
- host_->ShowMenuHost(do_capture);
- } else {
- host_ = new MenuHost(this);
- // Force construction of the scroll view container.
- GetScrollViewContainer();
- // Force a layout since our preferred size may not have changed but our
- // content may have.
- InvalidateLayout();
- host_->InitMenuHost(parent, bounds, scroll_view_container_, do_capture);
- }
-
- GetScrollViewContainer()->NotifyAccessibilityEvent(
- ui::AX_EVENT_MENU_START,
- true);
- NotifyAccessibilityEvent(
- ui::AX_EVENT_MENU_POPUP_START,
- true);
-}
-
-void SubmenuView::Reposition(const gfx::Rect& bounds) {
- if (host_)
- host_->SetMenuHostBounds(bounds);
-}
-
-void SubmenuView::Close() {
- if (host_) {
- NotifyAccessibilityEvent(ui::AX_EVENT_MENU_POPUP_END, true);
- GetScrollViewContainer()->NotifyAccessibilityEvent(
- ui::AX_EVENT_MENU_END, true);
-
- host_->DestroyMenuHost();
- host_ = NULL;
- }
-}
-
-void SubmenuView::Hide() {
- if (host_)
- host_->HideMenuHost();
- if (scroll_animator_->is_scrolling())
- scroll_animator_->Stop();
-}
-
-void SubmenuView::ReleaseCapture() {
- if (host_)
- host_->ReleaseMenuHostCapture();
-}
-
-bool SubmenuView::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) {
- return views::FocusManager::IsTabTraversalKeyEvent(e);
-}
-
-MenuItemView* SubmenuView::GetMenuItem() const {
- return parent_menu_item_;
-}
-
-void SubmenuView::SetDropMenuItem(MenuItemView* item,
- MenuDelegate::DropPosition position) {
- if (drop_item_ == item && drop_position_ == position)
- return;
- SchedulePaintForDropIndicator(drop_item_, drop_position_);
- drop_item_ = item;
- drop_position_ = position;
- SchedulePaintForDropIndicator(drop_item_, drop_position_);
-}
-
-bool SubmenuView::GetShowSelection(MenuItemView* item) {
- if (drop_item_ == NULL)
- return true;
- // Something is being dropped on one of this menus items. Show the
- // selection if the drop is on the passed in item and the drop position is
- // ON.
- return (drop_item_ == item && drop_position_ == MenuDelegate::DROP_ON);
-}
-
-MenuScrollViewContainer* SubmenuView::GetScrollViewContainer() {
- if (!scroll_view_container_) {
- scroll_view_container_ = new MenuScrollViewContainer(this);
- // Otherwise MenuHost would delete us.
- scroll_view_container_->set_owned_by_client();
- }
- return scroll_view_container_;
-}
-
-void SubmenuView::MenuHostDestroyed() {
- host_ = NULL;
- GetMenuItem()->GetMenuController()->Cancel(MenuController::EXIT_DESTROYED);
-}
-
-const char* SubmenuView::GetClassName() const {
- return kViewClassName;
-}
-
-void SubmenuView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
- SchedulePaint();
-}
-
-void SubmenuView::PaintDropIndicator(gfx::Canvas* canvas,
- MenuItemView* item,
- MenuDelegate::DropPosition position) {
- if (position == MenuDelegate::DROP_NONE)
- return;
-
- gfx::Rect bounds = CalculateDropIndicatorBounds(item, position);
- canvas->FillRect(bounds, kDropIndicatorColor);
-}
-
-void SubmenuView::SchedulePaintForDropIndicator(
- MenuItemView* item,
- MenuDelegate::DropPosition position) {
- if (item == NULL)
- return;
-
- if (position == MenuDelegate::DROP_ON) {
- item->SchedulePaint();
- } else if (position != MenuDelegate::DROP_NONE) {
- SchedulePaintInRect(CalculateDropIndicatorBounds(item, position));
- }
-}
-
-gfx::Rect SubmenuView::CalculateDropIndicatorBounds(
- MenuItemView* item,
- MenuDelegate::DropPosition position) {
- DCHECK(position != MenuDelegate::DROP_NONE);
- gfx::Rect item_bounds = item->bounds();
- switch (position) {
- case MenuDelegate::DROP_BEFORE:
- item_bounds.Offset(0, -kDropIndicatorHeight / 2);
- item_bounds.set_height(kDropIndicatorHeight);
- return item_bounds;
-
- case MenuDelegate::DROP_AFTER:
- item_bounds.Offset(0, item_bounds.height() - kDropIndicatorHeight / 2);
- item_bounds.set_height(kDropIndicatorHeight);
- return item_bounds;
-
- default:
- // Don't render anything for on.
- return gfx::Rect();
- }
-}
-
-bool SubmenuView::OnScroll(float dx, float dy) {
- const gfx::Rect& vis_bounds = GetVisibleBounds();
- const gfx::Rect& full_bounds = bounds();
- int x = vis_bounds.x();
- float y_f = vis_bounds.y() - dy - roundoff_error_;
- int y = gfx::ToRoundedInt(y_f);
- roundoff_error_ = y - y_f;
- // clamp y to [0, full_height - vis_height)
- y = std::min(y, full_bounds.height() - vis_bounds.height() - 1);
- y = std::max(y, 0);
- gfx::Rect new_vis_bounds(x, y, vis_bounds.width(), vis_bounds.height());
- if (new_vis_bounds != vis_bounds) {
- ScrollRectToVisible(new_vis_bounds);
- return true;
- }
- return false;
-}
-
-} // namespace views
« no previous file with comments | « ui/views/controls/menu/submenu_view.h ('k') | ui/views/controls/message_box_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698