| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/controls/menu/menu_controller.h" | 5 #include "views/controls/menu/menu_controller.h" |
| 6 | 6 |
| 7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
| 8 #include "base/time.h" | 8 #include "base/time.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "ui/base/dragdrop/os_exchange_data.h" | 10 #include "ui/base/dragdrop/os_exchange_data.h" |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 void MenuController::Cancel(ExitType type) { | 370 void MenuController::Cancel(ExitType type) { |
| 371 if (!showing_) { | 371 if (!showing_) { |
| 372 // This occurs if we're in the process of notifying the delegate for a drop | 372 // This occurs if we're in the process of notifying the delegate for a drop |
| 373 // and the delegate cancels us. | 373 // and the delegate cancels us. |
| 374 return; | 374 return; |
| 375 } | 375 } |
| 376 | 376 |
| 377 MenuItemView* selected = state_.item; | 377 MenuItemView* selected = state_.item; |
| 378 exit_type_ = type; | 378 exit_type_ = type; |
| 379 | 379 |
| 380 SendMouseReleaseToActiveView(); | 380 SendMouseCaptureLostToActiveView(); |
| 381 | 381 |
| 382 // Hide windows immediately. | 382 // Hide windows immediately. |
| 383 SetSelection(NULL, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); | 383 SetSelection(NULL, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); |
| 384 | 384 |
| 385 if (!blocking_run_) { | 385 if (!blocking_run_) { |
| 386 // If we didn't block the caller we need to notify the menu, which | 386 // If we didn't block the caller we need to notify the menu, which |
| 387 // triggers deleting us. | 387 // triggers deleting us. |
| 388 DCHECK(selected); | 388 DCHECK(selected); |
| 389 showing_ = false; | 389 showing_ = false; |
| 390 selected->GetRootMenuItem()->DropMenuClosed(true); | 390 selected->GetRootMenuItem()->DropMenuClosed(true); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 int selection_types = SELECTION_UPDATE_IMMEDIATELY; | 511 int selection_types = SELECTION_UPDATE_IMMEDIATELY; |
| 512 if (state_.item == pending_state_.item && state_.submenu_open) | 512 if (state_.item == pending_state_.item && state_.submenu_open) |
| 513 selection_types |= SELECTION_OPEN_SUBMENU; | 513 selection_types |= SELECTION_OPEN_SUBMENU; |
| 514 SetSelection(pending_state_.item, selection_types); | 514 SetSelection(pending_state_.item, selection_types); |
| 515 gfx::Point loc(event.location()); | 515 gfx::Point loc(event.location()); |
| 516 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); | 516 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); |
| 517 | 517 |
| 518 // If we open a context menu just return now | 518 // If we open a context menu just return now |
| 519 if (part.menu->GetDelegate()->ShowContextMenu( | 519 if (part.menu->GetDelegate()->ShowContextMenu( |
| 520 part.menu, part.menu->GetCommand(), loc, true)) { | 520 part.menu, part.menu->GetCommand(), loc, true)) { |
| 521 SendMouseReleaseToActiveView(source, event, true); | 521 SendMouseCaptureLostToActiveView(); |
| 522 return; | 522 return; |
| 523 } | 523 } |
| 524 } | 524 } |
| 525 | 525 |
| 526 // We can use Ctrl+click or the middle mouse button to recursively open urls | 526 // We can use Ctrl+click or the middle mouse button to recursively open urls |
| 527 // for selected folder menu items. If it's only a left click, show the | 527 // for selected folder menu items. If it's only a left click, show the |
| 528 // contents of the folder. | 528 // contents of the folder. |
| 529 if (!part.is_scroll() && part.menu && | 529 if (!part.is_scroll() && part.menu && |
| 530 !(part.menu->HasSubmenu() && | 530 !(part.menu->HasSubmenu() && |
| 531 (event.flags() == ui::EF_LEFT_BUTTON_DOWN))) { | 531 (event.flags() == ui::EF_LEFT_BUTTON_DOWN))) { |
| 532 if (active_mouse_view_) { | 532 if (active_mouse_view_) { |
| 533 SendMouseReleaseToActiveView(source, event, false); | 533 SendMouseReleaseToActiveView(source, event); |
| 534 return; | 534 return; |
| 535 } | 535 } |
| 536 if (part.menu->GetDelegate()->IsTriggerableEvent(event)) { | 536 if (part.menu->GetDelegate()->IsTriggerableEvent(event)) { |
| 537 Accept(part.menu, event.flags()); | 537 Accept(part.menu, event.flags()); |
| 538 return; | 538 return; |
| 539 } | 539 } |
| 540 } else if (part.type == MenuPart::MENU_ITEM) { | 540 } else if (part.type == MenuPart::MENU_ITEM) { |
| 541 // User either clicked on empty space, or a menu that has children. | 541 // User either clicked on empty space, or a menu that has children. |
| 542 SetSelection(part.menu ? part.menu : state_.item, | 542 SetSelection(part.menu ? part.menu : state_.item, |
| 543 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); | 543 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); |
| 544 } | 544 } |
| 545 SendMouseReleaseToActiveView(source, event, true); | 545 SendMouseCaptureLostToActiveView(); |
| 546 } | 546 } |
| 547 | 547 |
| 548 void MenuController::OnMouseMoved(SubmenuView* source, | 548 void MenuController::OnMouseMoved(SubmenuView* source, |
| 549 const MouseEvent& event) { | 549 const MouseEvent& event) { |
| 550 if (showing_submenu_) | 550 if (showing_submenu_) |
| 551 return; | 551 return; |
| 552 | 552 |
| 553 MenuPart part = GetMenuPartByScreenCoordinate(source, event.x(), event.y()); | 553 MenuPart part = GetMenuPartByScreenCoordinate(source, event.x(), event.y()); |
| 554 | 554 |
| 555 UpdateScrolling(part); | 555 UpdateScrolling(part); |
| (...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 // is currently true for the cases we are embedding views, but if we embed | 1780 // is currently true for the cases we are embedding views, but if we embed |
| 1781 // more complex hierarchies it'll need to change. | 1781 // more complex hierarchies it'll need to change. |
| 1782 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), | 1782 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), |
| 1783 &target_menu_loc); | 1783 &target_menu_loc); |
| 1784 View::ConvertPointToView(NULL, target_menu, &target_menu_loc); | 1784 View::ConvertPointToView(NULL, target_menu, &target_menu_loc); |
| 1785 target = target_menu->GetEventHandlerForPoint(target_menu_loc); | 1785 target = target_menu->GetEventHandlerForPoint(target_menu_loc); |
| 1786 if (target == target_menu || !target->IsEnabled()) | 1786 if (target == target_menu || !target->IsEnabled()) |
| 1787 target = NULL; | 1787 target = NULL; |
| 1788 } | 1788 } |
| 1789 if (target != active_mouse_view_) { | 1789 if (target != active_mouse_view_) { |
| 1790 if (active_mouse_view_) { | 1790 SendMouseCaptureLostToActiveView(); |
| 1791 // TODO(msw): Revise api and uses with OnMouseCaptureLost (like ui/views). | |
| 1792 // Send a mouse release with cancel set to true. | |
| 1793 active_mouse_view_->OnMouseReleased(event, true); | |
| 1794 active_mouse_view_ = NULL; | |
| 1795 } | |
| 1796 active_mouse_view_ = target; | 1791 active_mouse_view_ = target; |
| 1797 if (active_mouse_view_) { | 1792 if (active_mouse_view_) { |
| 1798 gfx::Point target_point(target_menu_loc); | 1793 gfx::Point target_point(target_menu_loc); |
| 1799 View::ConvertPointToView(target_menu, active_mouse_view_, &target_point); | 1794 View::ConvertPointToView(target_menu, active_mouse_view_, &target_point); |
| 1800 MouseEvent mouse_entered_event(ui::ET_MOUSE_ENTERED, | 1795 MouseEvent mouse_entered_event(ui::ET_MOUSE_ENTERED, |
| 1801 target_point.x(), target_point.y(), 0); | 1796 target_point.x(), target_point.y(), 0); |
| 1802 active_mouse_view_->OnMouseEntered(mouse_entered_event); | 1797 active_mouse_view_->OnMouseEntered(mouse_entered_event); |
| 1803 | 1798 |
| 1804 MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, | 1799 MouseEvent mouse_pressed_event(ui::ET_MOUSE_PRESSED, |
| 1805 target_point.x(), target_point.y(), | 1800 target_point.x(), target_point.y(), |
| 1806 event.flags()); | 1801 event.flags()); |
| 1807 active_mouse_view_->OnMousePressed(mouse_pressed_event); | 1802 active_mouse_view_->OnMousePressed(mouse_pressed_event); |
| 1808 } | 1803 } |
| 1809 } | 1804 } |
| 1810 | 1805 |
| 1811 if (active_mouse_view_) { | 1806 if (active_mouse_view_) { |
| 1812 gfx::Point target_point(target_menu_loc); | 1807 gfx::Point target_point(target_menu_loc); |
| 1813 View::ConvertPointToView(target_menu, active_mouse_view_, &target_point); | 1808 View::ConvertPointToView(target_menu, active_mouse_view_, &target_point); |
| 1814 MouseEvent mouse_dragged_event(ui::ET_MOUSE_DRAGGED, | 1809 MouseEvent mouse_dragged_event(ui::ET_MOUSE_DRAGGED, |
| 1815 target_point.x(), target_point.y(), | 1810 target_point.x(), target_point.y(), |
| 1816 event.flags()); | 1811 event.flags()); |
| 1817 active_mouse_view_->OnMouseDragged(mouse_dragged_event); | 1812 active_mouse_view_->OnMouseDragged(mouse_dragged_event); |
| 1818 } | 1813 } |
| 1819 } | 1814 } |
| 1820 | 1815 |
| 1821 void MenuController::SendMouseReleaseToActiveView(SubmenuView* event_source, | 1816 void MenuController::SendMouseReleaseToActiveView(SubmenuView* event_source, |
| 1822 const MouseEvent& event, | 1817 const MouseEvent& event) { |
| 1823 bool cancel) { | |
| 1824 if (!active_mouse_view_) | 1818 if (!active_mouse_view_) |
| 1825 return; | 1819 return; |
| 1826 | 1820 |
| 1827 gfx::Point target_loc(event.location()); | 1821 gfx::Point target_loc(event.location()); |
| 1828 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), | 1822 View::ConvertPointToScreen(event_source->GetScrollViewContainer(), |
| 1829 &target_loc); | 1823 &target_loc); |
| 1830 View::ConvertPointToView(NULL, active_mouse_view_, &target_loc); | 1824 View::ConvertPointToView(NULL, active_mouse_view_, &target_loc); |
| 1825 |
| 1831 MouseEvent release_event(ui::ET_MOUSE_RELEASED, target_loc.x(), | 1826 MouseEvent release_event(ui::ET_MOUSE_RELEASED, target_loc.x(), |
| 1832 target_loc.y(), event.flags()); | 1827 target_loc.y(), event.flags()); |
| 1833 // Reset the active_mouse_view_ before sending mouse released. That way if if | 1828 // Reset the active_mouse_view_ before sending mouse released. That way if it |
| 1834 // calls back to use we aren't in a weird state. | 1829 // calls back to us, we aren't in a weird state. |
| 1835 View* active_view = active_mouse_view_; | 1830 View* active_view = active_mouse_view_; |
| 1836 active_mouse_view_ = NULL; | 1831 active_mouse_view_ = NULL; |
| 1837 active_view->OnMouseReleased(release_event, cancel); | 1832 active_view->OnMouseReleased(release_event); |
| 1838 } | 1833 } |
| 1839 | 1834 |
| 1840 void MenuController::SendMouseReleaseToActiveView() { | 1835 void MenuController::SendMouseCaptureLostToActiveView() { |
| 1841 if (!active_mouse_view_) | 1836 if (!active_mouse_view_) |
| 1842 return; | 1837 return; |
| 1843 | 1838 |
| 1844 MouseEvent release_event(ui::ET_MOUSE_RELEASED, -1, -1, 0); | 1839 // Reset the active_mouse_view_ before sending mouse capture lost. That way if |
| 1845 // Reset the active_mouse_view_ before sending mouse released. That way if if | 1840 // it calls back to us, we aren't in a weird state. |
| 1846 // calls back to use we aren't in a weird state. | |
| 1847 View* active_view = active_mouse_view_; | 1841 View* active_view = active_mouse_view_; |
| 1848 active_mouse_view_ = NULL; | 1842 active_mouse_view_ = NULL; |
| 1849 active_view->OnMouseReleased(release_event, true); | 1843 active_view->OnMouseCaptureLost(); |
| 1850 } | 1844 } |
| 1851 | 1845 |
| 1852 } // namespace views | 1846 } // namespace views |
| OLD | NEW |