OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/controls/menu/menu_controller.h" | 5 #include "ui/views/controls/menu/menu_controller.h" |
6 | 6 |
7 #include "base/i18n/case_conversion.h" | 7 #include "base/i18n/case_conversion.h" |
8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 if (!menu_item) { | 606 if (!menu_item) { |
607 // See if we're over an empty menu. | 607 // See if we're over an empty menu. |
608 menu_item = GetEmptyMenuItemAt(source, event.x(), event.y()); | 608 menu_item = GetEmptyMenuItemAt(source, event.x(), event.y()); |
609 if (menu_item) | 609 if (menu_item) |
610 over_empty_menu = true; | 610 over_empty_menu = true; |
611 } | 611 } |
612 MenuDelegate::DropPosition drop_position = MenuDelegate::DROP_NONE; | 612 MenuDelegate::DropPosition drop_position = MenuDelegate::DROP_NONE; |
613 int drop_operation = ui::DragDropTypes::DRAG_NONE; | 613 int drop_operation = ui::DragDropTypes::DRAG_NONE; |
614 if (menu_item) { | 614 if (menu_item) { |
615 gfx::Point menu_item_loc(event.location()); | 615 gfx::Point menu_item_loc(event.location()); |
616 View::ConvertPointToView(source, menu_item, &menu_item_loc); | 616 View::ConvertPointToTarget(source, menu_item, &menu_item_loc); |
617 MenuItemView* query_menu_item; | 617 MenuItemView* query_menu_item; |
618 if (!over_empty_menu) { | 618 if (!over_empty_menu) { |
619 int menu_item_height = menu_item->height(); | 619 int menu_item_height = menu_item->height(); |
620 if (menu_item->HasSubmenu() && | 620 if (menu_item->HasSubmenu() && |
621 (menu_item_loc.y() > kDropBetweenPixels && | 621 (menu_item_loc.y() > kDropBetweenPixels && |
622 menu_item_loc.y() < (menu_item_height - kDropBetweenPixels))) { | 622 menu_item_loc.y() < (menu_item_height - kDropBetweenPixels))) { |
623 drop_position = MenuDelegate::DROP_ON; | 623 drop_position = MenuDelegate::DROP_ON; |
624 } else { | 624 } else { |
625 drop_position = (menu_item_loc.y() < menu_item_height / 2) ? | 625 drop_position = (menu_item_loc.y() < menu_item_height / 2) ? |
626 MenuDelegate::DROP_BEFORE : MenuDelegate::DROP_AFTER; | 626 MenuDelegate::DROP_BEFORE : MenuDelegate::DROP_AFTER; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 // Notify an accessibility focus event on all menu items except for the root. | 782 // Notify an accessibility focus event on all menu items except for the root. |
783 if (menu_item && | 783 if (menu_item && |
784 (MenuDepth(menu_item) != 1 || | 784 (MenuDepth(menu_item) != 1 || |
785 menu_item->GetType() != MenuItemView::SUBMENU)) { | 785 menu_item->GetType() != MenuItemView::SUBMENU)) { |
786 menu_item->GetWidget()->NotifyAccessibilityEvent( | 786 menu_item->GetWidget()->NotifyAccessibilityEvent( |
787 menu_item, ui::AccessibilityTypes::EVENT_FOCUS, true); | 787 menu_item, ui::AccessibilityTypes::EVENT_FOCUS, true); |
788 } | 788 } |
789 } | 789 } |
790 | 790 |
791 void MenuController::SetSelectionOnPointerDown(SubmenuView* source, | 791 void MenuController::SetSelectionOnPointerDown(SubmenuView* source, |
792 const LocatedEvent& event) { | 792 const ui::LocatedEvent& event) { |
793 if (!blocking_run_) | 793 if (!blocking_run_) |
794 return; | 794 return; |
795 drop_first_release_event_ = false; | 795 drop_first_release_event_ = false; |
796 | 796 |
797 DCHECK(!active_mouse_view_); | 797 DCHECK(!active_mouse_view_); |
798 | 798 |
799 MenuPart part = GetMenuPart(source, event.location()); | 799 MenuPart part = GetMenuPart(source, event.location()); |
800 if (part.is_scroll()) | 800 if (part.is_scroll()) |
801 return; // Ignore presses on scroll buttons. | 801 return; // Ignore presses on scroll buttons. |
802 | 802 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 | 854 |
855 void MenuController::StartDrag(SubmenuView* source, | 855 void MenuController::StartDrag(SubmenuView* source, |
856 const gfx::Point& location) { | 856 const gfx::Point& location) { |
857 MenuItemView* item = state_.item; | 857 MenuItemView* item = state_.item; |
858 DCHECK(item); | 858 DCHECK(item); |
859 // Points are in the coordinates of the submenu, need to map to that of | 859 // Points are in the coordinates of the submenu, need to map to that of |
860 // the selected item. Additionally source may not be the parent of | 860 // the selected item. Additionally source may not be the parent of |
861 // the selected item, so need to map to screen first then to item. | 861 // the selected item, so need to map to screen first then to item. |
862 gfx::Point press_loc(location); | 862 gfx::Point press_loc(location); |
863 View::ConvertPointToScreen(source->GetScrollViewContainer(), &press_loc); | 863 View::ConvertPointToScreen(source->GetScrollViewContainer(), &press_loc); |
864 View::ConvertPointToView(NULL, item, &press_loc); | 864 View::ConvertPointToTarget(NULL, item, &press_loc); |
865 gfx::Point widget_loc(press_loc); | 865 gfx::Point widget_loc(press_loc); |
866 View::ConvertPointToWidget(item, &widget_loc); | 866 View::ConvertPointToWidget(item, &widget_loc); |
867 scoped_ptr<gfx::Canvas> canvas(views::GetCanvasForDragImage( | 867 scoped_ptr<gfx::Canvas> canvas(views::GetCanvasForDragImage( |
868 source->GetWidget(), gfx::Size(item->width(), item->height()))); | 868 source->GetWidget(), gfx::Size(item->width(), item->height()))); |
869 item->PaintButton(canvas.get(), MenuItemView::PB_FOR_DRAG); | 869 item->PaintButton(canvas.get(), MenuItemView::PB_FOR_DRAG); |
870 | 870 |
871 OSExchangeData data; | 871 OSExchangeData data; |
872 item->GetDelegate()->WriteDragData(item, &data); | 872 item->GetDelegate()->WriteDragData(item, &data); |
873 drag_utils::SetDragImageOnDataObject(*canvas, item->size(), press_loc, | 873 drag_utils::SetDragImageOnDataObject(*canvas, item->size(), press_loc, |
874 &data); | 874 &data); |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 alt_menu->PrepareForRun( | 1203 alt_menu->PrepareForRun( |
1204 has_mnemonics, | 1204 has_mnemonics, |
1205 source->GetMenuItem()->GetRootMenuItem()->show_mnemonics_); | 1205 source->GetMenuItem()->GetRootMenuItem()->show_mnemonics_); |
1206 alt_menu->controller_ = this; | 1206 alt_menu->controller_ = this; |
1207 SetSelection(alt_menu, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); | 1207 SetSelection(alt_menu, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); |
1208 return true; | 1208 return true; |
1209 } | 1209 } |
1210 | 1210 |
1211 bool MenuController::ShowContextMenu(MenuItemView* menu_item, | 1211 bool MenuController::ShowContextMenu(MenuItemView* menu_item, |
1212 SubmenuView* source, | 1212 SubmenuView* source, |
1213 const LocatedEvent& event) { | 1213 const ui::LocatedEvent& event) { |
1214 // Set the selection immediately, making sure the submenu is only open | 1214 // Set the selection immediately, making sure the submenu is only open |
1215 // if it already was. | 1215 // if it already was. |
1216 int selection_types = SELECTION_UPDATE_IMMEDIATELY; | 1216 int selection_types = SELECTION_UPDATE_IMMEDIATELY; |
1217 if (state_.item == pending_state_.item && state_.submenu_open) | 1217 if (state_.item == pending_state_.item && state_.submenu_open) |
1218 selection_types |= SELECTION_OPEN_SUBMENU; | 1218 selection_types |= SELECTION_OPEN_SUBMENU; |
1219 SetSelection(pending_state_.item, selection_types); | 1219 SetSelection(pending_state_.item, selection_types); |
1220 gfx::Point loc(event.location()); | 1220 gfx::Point loc(event.location()); |
1221 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); | 1221 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); |
1222 | 1222 |
1223 if (menu_item->GetDelegate()->ShowContextMenu( | 1223 if (menu_item->GetDelegate()->ShowContextMenu( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 return part; | 1307 return part; |
1308 } | 1308 } |
1309 | 1309 |
1310 bool MenuController::GetMenuPartByScreenCoordinateImpl( | 1310 bool MenuController::GetMenuPartByScreenCoordinateImpl( |
1311 SubmenuView* menu, | 1311 SubmenuView* menu, |
1312 const gfx::Point& screen_loc, | 1312 const gfx::Point& screen_loc, |
1313 MenuPart* part) { | 1313 MenuPart* part) { |
1314 // Is the mouse over the scroll buttons? | 1314 // Is the mouse over the scroll buttons? |
1315 gfx::Point scroll_view_loc = screen_loc; | 1315 gfx::Point scroll_view_loc = screen_loc; |
1316 View* scroll_view_container = menu->GetScrollViewContainer(); | 1316 View* scroll_view_container = menu->GetScrollViewContainer(); |
1317 View::ConvertPointToView(NULL, scroll_view_container, &scroll_view_loc); | 1317 View::ConvertPointToTarget(NULL, scroll_view_container, &scroll_view_loc); |
1318 if (scroll_view_loc.x() < 0 || | 1318 if (scroll_view_loc.x() < 0 || |
1319 scroll_view_loc.x() >= scroll_view_container->width() || | 1319 scroll_view_loc.x() >= scroll_view_container->width() || |
1320 scroll_view_loc.y() < 0 || | 1320 scroll_view_loc.y() < 0 || |
1321 scroll_view_loc.y() >= scroll_view_container->height()) { | 1321 scroll_view_loc.y() >= scroll_view_container->height()) { |
1322 // Point isn't contained in menu. | 1322 // Point isn't contained in menu. |
1323 return false; | 1323 return false; |
1324 } | 1324 } |
1325 if (IsScrollButtonAt(menu, scroll_view_loc.x(), scroll_view_loc.y(), | 1325 if (IsScrollButtonAt(menu, scroll_view_loc.x(), scroll_view_loc.y(), |
1326 &(part->type))) { | 1326 &(part->type))) { |
1327 part->submenu = menu; | 1327 part->submenu = menu; |
1328 return true; | 1328 return true; |
1329 } | 1329 } |
1330 | 1330 |
1331 // Not over the scroll button. Check the actual menu. | 1331 // Not over the scroll button. Check the actual menu. |
1332 if (DoesSubmenuContainLocation(menu, screen_loc)) { | 1332 if (DoesSubmenuContainLocation(menu, screen_loc)) { |
1333 gfx::Point menu_loc = screen_loc; | 1333 gfx::Point menu_loc = screen_loc; |
1334 View::ConvertPointToView(NULL, menu, &menu_loc); | 1334 View::ConvertPointToTarget(NULL, menu, &menu_loc); |
1335 part->menu = GetMenuItemAt(menu, menu_loc.x(), menu_loc.y()); | 1335 part->menu = GetMenuItemAt(menu, menu_loc.x(), menu_loc.y()); |
1336 part->type = MenuPart::MENU_ITEM; | 1336 part->type = MenuPart::MENU_ITEM; |
1337 part->submenu = menu; | 1337 part->submenu = menu; |
1338 if (!part->menu) | 1338 if (!part->menu) |
1339 part->parent = menu->GetMenuItem(); | 1339 part->parent = menu->GetMenuItem(); |
1340 return true; | 1340 return true; |
1341 } | 1341 } |
1342 | 1342 |
1343 // While the mouse isn't over a menu item or the scroll buttons of menu, it | 1343 // While the mouse isn't over a menu item or the scroll buttons of menu, it |
1344 // is contained by menu and so we return true. If we didn't return true other | 1344 // is contained by menu and so we return true. If we didn't return true other |
1345 // menus would be searched, even though they are likely obscured by us. | 1345 // menus would be searched, even though they are likely obscured by us. |
1346 return true; | 1346 return true; |
1347 } | 1347 } |
1348 | 1348 |
1349 bool MenuController::DoesSubmenuContainLocation(SubmenuView* submenu, | 1349 bool MenuController::DoesSubmenuContainLocation(SubmenuView* submenu, |
1350 const gfx::Point& screen_loc) { | 1350 const gfx::Point& screen_loc) { |
1351 gfx::Point view_loc = screen_loc; | 1351 gfx::Point view_loc = screen_loc; |
1352 View::ConvertPointToView(NULL, submenu, &view_loc); | 1352 View::ConvertPointToTarget(NULL, submenu, &view_loc); |
1353 gfx::Rect vis_rect = submenu->GetVisibleBounds(); | 1353 gfx::Rect vis_rect = submenu->GetVisibleBounds(); |
1354 return vis_rect.Contains(view_loc.x(), view_loc.y()); | 1354 return vis_rect.Contains(view_loc.x(), view_loc.y()); |
1355 } | 1355 } |
1356 | 1356 |
1357 void MenuController::CommitPendingSelection() { | 1357 void MenuController::CommitPendingSelection() { |
1358 StopShowTimer(); | 1358 StopShowTimer(); |
1359 | 1359 |
1360 size_t paths_differ_at = 0; | 1360 size_t paths_differ_at = 0; |
1361 std::vector<MenuItemView*> current_path; | 1361 std::vector<MenuItemView*> current_path; |
1362 std::vector<MenuItemView*> new_path; | 1362 std::vector<MenuItemView*> new_path; |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1904 // If no mnemonics found, look at first character of titles. | 1904 // If no mnemonics found, look at first character of titles. |
1905 details = FindChildForMnemonic(item, key, &TitleMatchesMnemonic); | 1905 details = FindChildForMnemonic(item, key, &TitleMatchesMnemonic); |
1906 if (details.first_match != -1) | 1906 if (details.first_match != -1) |
1907 return AcceptOrSelect(item, details); | 1907 return AcceptOrSelect(item, details); |
1908 | 1908 |
1909 return false; | 1909 return false; |
1910 } | 1910 } |
1911 | 1911 |
1912 #if defined(OS_WIN) && !defined(USE_AURA) | 1912 #if defined(OS_WIN) && !defined(USE_AURA) |
1913 void MenuController::RepostEvent(SubmenuView* source, | 1913 void MenuController::RepostEvent(SubmenuView* source, |
1914 const LocatedEvent& event) { | 1914 const ui::LocatedEvent& event) { |
1915 if (!state_.item) { | 1915 if (!state_.item) { |
1916 // We some times get an event after closing all the menus. Ignore it. | 1916 // We some times get an event after closing all the menus. Ignore it. |
1917 // Make sure the menu is in fact not visible. If the menu is visible, then | 1917 // Make sure the menu is in fact not visible. If the menu is visible, then |
1918 // we're in a bad state where we think the menu isn't visibile but it is. | 1918 // we're in a bad state where we think the menu isn't visibile but it is. |
1919 DCHECK(!source->GetWidget()->IsVisible()); | 1919 DCHECK(!source->GetWidget()->IsVisible()); |
1920 return; | 1920 return; |
1921 } | 1921 } |
1922 | 1922 |
1923 gfx::Point screen_loc(event.location()); | 1923 gfx::Point screen_loc(event.location()); |
1924 View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc); | 1924 View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 View* target_menu) { | 2015 View* target_menu) { |
2016 View* target = NULL; | 2016 View* target = NULL; |
2017 gfx::Point target_menu_loc(event.location()); | 2017 gfx::Point target_menu_loc(event.location()); |
2018 if (target_menu && target_menu->has_children()) { | 2018 if (target_menu && target_menu->has_children()) { |
2019 // Locate the deepest child view to send events to. This code assumes we | 2019 // Locate the deepest child view to send events to. This code assumes we |
2020 // don't have to walk up the tree to find a view interested in events. This | 2020 // don't have to walk up the tree to find a view interested in events. This |
2021 // is currently true for the cases we are embedding views, but if we embed | 2021 // is currently true for the cases we are embedding views, but if we embed |
2022 // more complex hierarchies it'll need to change. | 2022 // more complex hierarchies it'll need to change. |
2023 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), | 2023 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), |
2024 &target_menu_loc); | 2024 &target_menu_loc); |
2025 View::ConvertPointToView(NULL, target_menu, &target_menu_loc); | 2025 View::ConvertPointToTarget(NULL, target_menu, &target_menu_loc); |
2026 target = target_menu->GetEventHandlerForPoint(target_menu_loc); | 2026 target = target_menu->GetEventHandlerForPoint(target_menu_loc); |
2027 if (target == target_menu || !target->enabled()) | 2027 if (target == target_menu || !target->enabled()) |
2028 target = NULL; | 2028 target = NULL; |
2029 } | 2029 } |
2030 if (target != active_mouse_view_) { | 2030 if (target != active_mouse_view_) { |
2031 SendMouseCaptureLostToActiveView(); | 2031 SendMouseCaptureLostToActiveView(); |
2032 active_mouse_view_ = target; | 2032 active_mouse_view_ = target; |
2033 if (active_mouse_view_) { | 2033 if (active_mouse_view_) { |
2034 gfx::Point target_point(target_menu_loc); | 2034 gfx::Point target_point(target_menu_loc); |
2035 View::ConvertPointToView(target_menu, active_mouse_view_, &target_point); | 2035 View::ConvertPointToTarget( |
| 2036 target_menu, active_mouse_view_, &target_point); |
2036 MouseEvent mouse_entered_event(ui::ET_MOUSE_ENTERED, | 2037 MouseEvent mouse_entered_event(ui::ET_MOUSE_ENTERED, |
2037 target_point.x(), target_point.y(), 0); | 2038 target_point.x(), target_point.y(), 0); |
2038 active_mouse_view_->OnMouseEntered(mouse_entered_event); | 2039 active_mouse_view_->OnMouseEntered(mouse_entered_event); |
2039 | 2040 |
2040 MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, | 2041 MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, |
2041 target_point.x(), target_point.y(), | 2042 target_point.x(), target_point.y(), |
2042 event.flags()); | 2043 event.flags()); |
2043 active_mouse_view_->OnMousePressed(mouse_pressed_event); | 2044 active_mouse_view_->OnMousePressed(mouse_pressed_event); |
2044 } | 2045 } |
2045 } | 2046 } |
2046 | 2047 |
2047 if (active_mouse_view_) { | 2048 if (active_mouse_view_) { |
2048 gfx::Point target_point(target_menu_loc); | 2049 gfx::Point target_point(target_menu_loc); |
2049 View::ConvertPointToView(target_menu, active_mouse_view_, &target_point); | 2050 View::ConvertPointToTarget(target_menu, active_mouse_view_, &target_point); |
2050 MouseEvent mouse_dragged_event(ui::ET_MOUSE_DRAGGED, | 2051 MouseEvent mouse_dragged_event(ui::ET_MOUSE_DRAGGED, |
2051 target_point.x(), target_point.y(), | 2052 target_point.x(), target_point.y(), |
2052 event.flags()); | 2053 event.flags()); |
2053 active_mouse_view_->OnMouseDragged(mouse_dragged_event); | 2054 active_mouse_view_->OnMouseDragged(mouse_dragged_event); |
2054 } | 2055 } |
2055 } | 2056 } |
2056 | 2057 |
2057 void MenuController::SendMouseReleaseToActiveView(SubmenuView* event_source, | 2058 void MenuController::SendMouseReleaseToActiveView(SubmenuView* event_source, |
2058 const MouseEvent& event) { | 2059 const MouseEvent& event) { |
2059 if (!active_mouse_view_) | 2060 if (!active_mouse_view_) |
2060 return; | 2061 return; |
2061 | 2062 |
2062 gfx::Point target_loc(event.location()); | 2063 gfx::Point target_loc(event.location()); |
2063 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), | 2064 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), |
2064 &target_loc); | 2065 &target_loc); |
2065 View::ConvertPointToView(NULL, active_mouse_view_, &target_loc); | 2066 View::ConvertPointToTarget(NULL, active_mouse_view_, &target_loc); |
2066 MouseEvent release_event(ui::ET_MOUSE_RELEASED, target_loc.x(), | 2067 MouseEvent release_event(ui::ET_MOUSE_RELEASED, target_loc.x(), |
2067 target_loc.y(), event.flags()); | 2068 target_loc.y(), event.flags()); |
2068 // Reset the active_mouse_view_ before sending mouse released. That way if it | 2069 // Reset the active_mouse_view_ before sending mouse released. That way if it |
2069 // calls back to us, we aren't in a weird state. | 2070 // calls back to us, we aren't in a weird state. |
2070 View* active_view = active_mouse_view_; | 2071 View* active_view = active_mouse_view_; |
2071 active_mouse_view_ = NULL; | 2072 active_mouse_view_ = NULL; |
2072 active_view->OnMouseReleased(release_event); | 2073 active_view->OnMouseReleased(release_event); |
2073 } | 2074 } |
2074 | 2075 |
2075 void MenuController::SendMouseCaptureLostToActiveView() { | 2076 void MenuController::SendMouseCaptureLostToActiveView() { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2140 | 2141 |
2141 #if defined(USE_AURA) | 2142 #if defined(USE_AURA) |
2142 void MenuController::OnWindowActivated(aura::Window* active, | 2143 void MenuController::OnWindowActivated(aura::Window* active, |
2143 aura::Window* old_active) { | 2144 aura::Window* old_active) { |
2144 if (!drag_in_progress_) | 2145 if (!drag_in_progress_) |
2145 Cancel(EXIT_ALL); | 2146 Cancel(EXIT_ALL); |
2146 } | 2147 } |
2147 #endif | 2148 #endif |
2148 | 2149 |
2149 } // namespace views | 2150 } // namespace views |
OLD | NEW |