| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/views/controls/menu/chrome_menu.h" | 5 #include "chrome/views/controls/menu/chrome_menu.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <uxtheme.h> | 8 #include <uxtheme.h> |
| 9 #include <Vssym32.h> | 9 #include <Vssym32.h> |
| 10 | 10 |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 | 646 |
| 647 // MenuHost is the window responsible for showing a single menu. | 647 // MenuHost is the window responsible for showing a single menu. |
| 648 // | 648 // |
| 649 // Similar to MenuHostRootView, care must be taken such that when MenuHost is | 649 // Similar to MenuHostRootView, care must be taken such that when MenuHost is |
| 650 // deleted, it doesn't delete the menu items. MenuHost is closed via a | 650 // deleted, it doesn't delete the menu items. MenuHost is closed via a |
| 651 // DelayedClosed, which avoids timing issues with deleting the window while | 651 // DelayedClosed, which avoids timing issues with deleting the window while |
| 652 // capture or events are directed at it. | 652 // capture or events are directed at it. |
| 653 | 653 |
| 654 class MenuHost : public WidgetWin { | 654 class MenuHost : public WidgetWin { |
| 655 public: | 655 public: |
| 656 MenuHost(SubmenuView* submenu) | 656 explicit MenuHost(SubmenuView* submenu) |
| 657 : closed_(false), | 657 : closed_(false), |
| 658 submenu_(submenu), | 658 submenu_(submenu), |
| 659 owns_capture_(false) { | 659 owns_capture_(false) { |
| 660 set_window_style(WS_POPUP); | 660 set_window_style(WS_POPUP); |
| 661 set_initial_class_style( | 661 set_initial_class_style( |
| 662 (win_util::GetWinVersion() < win_util::WINVERSION_XP) ? | 662 (win_util::GetWinVersion() < win_util::WINVERSION_XP) ? |
| 663 0 : CS_DROPSHADOW); | 663 0 : CS_DROPSHADOW); |
| 664 is_mouse_down_ = | 664 is_mouse_down_ = |
| 665 ((GetKeyState(VK_LBUTTON) & 0x80) || | 665 ((GetKeyState(VK_LBUTTON) & 0x80) || |
| 666 (GetKeyState(VK_RBUTTON) & 0x80) || | 666 (GetKeyState(VK_RBUTTON) & 0x80) || |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 | 767 |
| 768 // EmptyMenuMenuItem is used when a menu has no menu items. EmptyMenuMenuItem | 768 // EmptyMenuMenuItem is used when a menu has no menu items. EmptyMenuMenuItem |
| 769 // is itself a MenuItemView, but it uses a different ID so that it isn't | 769 // is itself a MenuItemView, but it uses a different ID so that it isn't |
| 770 // identified as a MenuItemView. | 770 // identified as a MenuItemView. |
| 771 | 771 |
| 772 class EmptyMenuMenuItem : public MenuItemView { | 772 class EmptyMenuMenuItem : public MenuItemView { |
| 773 public: | 773 public: |
| 774 // ID used for EmptyMenuMenuItem. | 774 // ID used for EmptyMenuMenuItem. |
| 775 static const int kEmptyMenuItemViewID; | 775 static const int kEmptyMenuItemViewID; |
| 776 | 776 |
| 777 EmptyMenuMenuItem(MenuItemView* parent) : MenuItemView(parent, 0, NORMAL) { | 777 explicit EmptyMenuMenuItem(MenuItemView* parent) : |
| 778 MenuItemView(parent, 0, NORMAL) { |
| 778 SetTitle(l10n_util::GetString(IDS_MENU_EMPTY_SUBMENU)); | 779 SetTitle(l10n_util::GetString(IDS_MENU_EMPTY_SUBMENU)); |
| 779 // Set this so that we're not identified as a normal menu item. | 780 // Set this so that we're not identified as a normal menu item. |
| 780 SetID(kEmptyMenuItemViewID); | 781 SetID(kEmptyMenuItemViewID); |
| 781 SetEnabled(false); | 782 SetEnabled(false); |
| 782 } | 783 } |
| 783 | 784 |
| 784 private: | 785 private: |
| 785 DISALLOW_COPY_AND_ASSIGN(EmptyMenuMenuItem); | 786 DISALLOW_COPY_AND_ASSIGN(EmptyMenuMenuItem); |
| 786 }; | 787 }; |
| 787 | 788 |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 POINT initial_loc = { bounds.x(), bounds.y() }; | 1615 POINT initial_loc = { bounds.x(), bounds.y() }; |
| 1615 HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); | 1616 HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); |
| 1616 if (monitor) { | 1617 if (monitor) { |
| 1617 MONITORINFO mi = {0}; | 1618 MONITORINFO mi = {0}; |
| 1618 mi.cbSize = sizeof(mi); | 1619 mi.cbSize = sizeof(mi); |
| 1619 GetMonitorInfo(monitor, &mi); | 1620 GetMonitorInfo(monitor, &mi); |
| 1620 // Menus appear over the taskbar. | 1621 // Menus appear over the taskbar. |
| 1621 pending_state_.monitor_bounds = gfx::Rect(mi.rcMonitor); | 1622 pending_state_.monitor_bounds = gfx::Rect(mi.rcMonitor); |
| 1622 } | 1623 } |
| 1623 | 1624 |
| 1624 any_menu_contains_mouse_ = false; | |
| 1625 | |
| 1626 // Set the selection, which opens the initial menu. | 1625 // Set the selection, which opens the initial menu. |
| 1627 SetSelection(root, true, true); | 1626 SetSelection(root, true, true); |
| 1628 | 1627 |
| 1629 if (!blocking_run_) { | 1628 if (!blocking_run_) { |
| 1630 // Start the timer to hide the menu. This is needed as we get no | 1629 // Start the timer to hide the menu. This is needed as we get no |
| 1631 // notification when the drag has finished. | 1630 // notification when the drag has finished. |
| 1632 StartCancelAllTimer(); | 1631 StartCancelAllTimer(); |
| 1633 return NULL; | 1632 return NULL; |
| 1634 } | 1633 } |
| 1635 | 1634 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 // We're going to close and we own the mouse capture. We need to repost the | 1769 // We're going to close and we own the mouse capture. We need to repost the |
| 1771 // mouse down, otherwise the window the user clicked on won't get the | 1770 // mouse down, otherwise the window the user clicked on won't get the |
| 1772 // event. | 1771 // event. |
| 1773 RepostEvent(source, event); | 1772 RepostEvent(source, event); |
| 1774 | 1773 |
| 1775 // And close. | 1774 // And close. |
| 1776 Cancel(true); | 1775 Cancel(true); |
| 1777 return; | 1776 return; |
| 1778 } | 1777 } |
| 1779 | 1778 |
| 1780 any_menu_contains_mouse_ = true; | |
| 1781 | |
| 1782 bool open_submenu = false; | 1779 bool open_submenu = false; |
| 1783 if (!part.menu) { | 1780 if (!part.menu) { |
| 1784 part.menu = source->GetMenuItem(); | 1781 part.menu = source->GetMenuItem(); |
| 1785 open_submenu = true; | 1782 open_submenu = true; |
| 1786 } else { | 1783 } else { |
| 1787 if (part.menu->GetDelegate()->CanDrag(part.menu)) { | 1784 if (part.menu->GetDelegate()->CanDrag(part.menu)) { |
| 1788 possible_drag_ = true; | 1785 possible_drag_ = true; |
| 1789 press_x_ = event.x(); | 1786 press_x_ = event.x(); |
| 1790 press_y_ = event.y(); | 1787 press_y_ = event.y(); |
| 1791 } | 1788 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1847 } // else case, drop was on us. | 1844 } // else case, drop was on us. |
| 1848 } // else case, someone canceled us, don't do anything | 1845 } // else case, someone canceled us, don't do anything |
| 1849 } | 1846 } |
| 1850 return; | 1847 return; |
| 1851 } | 1848 } |
| 1852 if (part.type == MenuPart::MENU_ITEM) { | 1849 if (part.type == MenuPart::MENU_ITEM) { |
| 1853 if (!part.menu) | 1850 if (!part.menu) |
| 1854 part.menu = source->GetMenuItem(); | 1851 part.menu = source->GetMenuItem(); |
| 1855 SetSelection(part.menu ? part.menu : state_.item, true, false); | 1852 SetSelection(part.menu ? part.menu : state_.item, true, false); |
| 1856 } | 1853 } |
| 1857 any_menu_contains_mouse_ = (part.type == MenuPart::MENU_ITEM); | |
| 1858 } | 1854 } |
| 1859 | 1855 |
| 1860 void MenuController::OnMouseReleased(SubmenuView* source, | 1856 void MenuController::OnMouseReleased(SubmenuView* source, |
| 1861 const MouseEvent& event) { | 1857 const MouseEvent& event) { |
| 1862 #ifdef DEBUG_MENU | 1858 #ifdef DEBUG_MENU |
| 1863 DLOG(INFO) << "OnMouseReleased source=" << source; | 1859 DLOG(INFO) << "OnMouseReleased source=" << source; |
| 1864 #endif | 1860 #endif |
| 1865 if (!blocking_run_) | 1861 if (!blocking_run_) |
| 1866 return; | 1862 return; |
| 1867 | 1863 |
| 1868 DCHECK(state_.item); | 1864 DCHECK(state_.item); |
| 1869 possible_drag_ = false; | 1865 possible_drag_ = false; |
| 1870 DCHECK(blocking_run_); | 1866 DCHECK(blocking_run_); |
| 1871 MenuPart part = | 1867 MenuPart part = |
| 1872 GetMenuPartByScreenCoordinate(source, event.x(), event.y()); | 1868 GetMenuPartByScreenCoordinate(source, event.x(), event.y()); |
| 1873 any_menu_contains_mouse_ = (part.type == MenuPart::MENU_ITEM); | |
| 1874 if (event.IsRightMouseButton() && (part.type == MenuPart::MENU_ITEM && | 1869 if (event.IsRightMouseButton() && (part.type == MenuPart::MENU_ITEM && |
| 1875 part.menu)) { | 1870 part.menu)) { |
| 1876 // Set the selection immediately, making sure the submenu is only open | 1871 // Set the selection immediately, making sure the submenu is only open |
| 1877 // if it already was. | 1872 // if it already was. |
| 1878 bool open_submenu = (state_.item == pending_state_.item && | 1873 bool open_submenu = (state_.item == pending_state_.item && |
| 1879 state_.submenu_open); | 1874 state_.submenu_open); |
| 1880 SetSelection(pending_state_.item, open_submenu, true); | 1875 SetSelection(pending_state_.item, open_submenu, true); |
| 1881 gfx::Point loc(event.location()); | 1876 gfx::Point loc(event.location()); |
| 1882 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); | 1877 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); |
| 1883 | 1878 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1907 return; | 1902 return; |
| 1908 | 1903 |
| 1909 MenuPart part = | 1904 MenuPart part = |
| 1910 GetMenuPartByScreenCoordinate(source, event.x(), event.y()); | 1905 GetMenuPartByScreenCoordinate(source, event.x(), event.y()); |
| 1911 | 1906 |
| 1912 UpdateScrolling(part); | 1907 UpdateScrolling(part); |
| 1913 | 1908 |
| 1914 if (!blocking_run_) | 1909 if (!blocking_run_) |
| 1915 return; | 1910 return; |
| 1916 | 1911 |
| 1917 any_menu_contains_mouse_ = (part.type == MenuPart::MENU_ITEM); | |
| 1918 if (part.type == MenuPart::MENU_ITEM && part.menu) { | 1912 if (part.type == MenuPart::MENU_ITEM && part.menu) { |
| 1919 SetSelection(part.menu, true, false); | 1913 SetSelection(part.menu, true, false); |
| 1920 } else if (!part.is_scroll() && any_menu_contains_mouse_ && | 1914 } else if (!part.is_scroll() && pending_state_.item && |
| 1921 pending_state_.item && | |
| 1922 (!pending_state_.item->HasSubmenu() || | 1915 (!pending_state_.item->HasSubmenu() || |
| 1923 !pending_state_.item->GetSubmenu()->IsShowing())) { | 1916 !pending_state_.item->GetSubmenu()->IsShowing())) { |
| 1924 // On exit if the user hasn't selected an item with a submenu, move the | 1917 // On exit if the user hasn't selected an item with a submenu, move the |
| 1925 // selection back to the parent menu item. | 1918 // selection back to the parent menu item. |
| 1926 SetSelection(pending_state_.item->GetParentMenuItem(), true, false); | 1919 SetSelection(pending_state_.item->GetParentMenuItem(), true, false); |
| 1927 any_menu_contains_mouse_ = false; | |
| 1928 } | 1920 } |
| 1929 } | 1921 } |
| 1930 | 1922 |
| 1931 void MenuController::OnMouseEntered(SubmenuView* source, | 1923 void MenuController::OnMouseEntered(SubmenuView* source, |
| 1932 const MouseEvent& event) { | 1924 const MouseEvent& event) { |
| 1933 // MouseEntered is always followed by a mouse moved, so don't need to | 1925 // MouseEntered is always followed by a mouse moved, so don't need to |
| 1934 // do anything here. | 1926 // do anything here. |
| 1935 } | 1927 } |
| 1936 | 1928 |
| 1937 bool MenuController::CanDrop(SubmenuView* source, const OSExchangeData& data) { | 1929 bool MenuController::CanDrop(SubmenuView* source, const OSExchangeData& data) { |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2202 MenuController::MenuController(bool blocking) | 2194 MenuController::MenuController(bool blocking) |
| 2203 : blocking_run_(blocking), | 2195 : blocking_run_(blocking), |
| 2204 showing_(false), | 2196 showing_(false), |
| 2205 exit_all_(false), | 2197 exit_all_(false), |
| 2206 did_capture_(false), | 2198 did_capture_(false), |
| 2207 result_(NULL), | 2199 result_(NULL), |
| 2208 drop_target_(NULL), | 2200 drop_target_(NULL), |
| 2209 owner_(NULL), | 2201 owner_(NULL), |
| 2210 possible_drag_(false), | 2202 possible_drag_(false), |
| 2211 valid_drop_coordinates_(false), | 2203 valid_drop_coordinates_(false), |
| 2212 any_menu_contains_mouse_(false), | |
| 2213 showing_submenu_(false), | 2204 showing_submenu_(false), |
| 2214 result_mouse_event_flags_(0) { | 2205 result_mouse_event_flags_(0) { |
| 2215 #ifdef DEBUG_MENU | 2206 #ifdef DEBUG_MENU |
| 2216 instance_count++; | 2207 instance_count++; |
| 2217 DLOG(INFO) << "created MC, count=" << instance_count; | 2208 DLOG(INFO) << "created MC, count=" << instance_count; |
| 2218 #endif | 2209 #endif |
| 2219 } | 2210 } |
| 2220 | 2211 |
| 2221 MenuController::~MenuController() { | 2212 MenuController::~MenuController() { |
| 2222 DCHECK(!showing_); | 2213 DCHECK(!showing_); |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2816 if (!scroll_task_.get()) | 2807 if (!scroll_task_.get()) |
| 2817 scroll_task_.reset(new MenuScrollTask()); | 2808 scroll_task_.reset(new MenuScrollTask()); |
| 2818 scroll_task_->Update(part); | 2809 scroll_task_->Update(part); |
| 2819 } | 2810 } |
| 2820 | 2811 |
| 2821 void MenuController::StopScrolling() { | 2812 void MenuController::StopScrolling() { |
| 2822 scroll_task_.reset(NULL); | 2813 scroll_task_.reset(NULL); |
| 2823 } | 2814 } |
| 2824 | 2815 |
| 2825 } // namespace views | 2816 } // namespace views |
| OLD | NEW |