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

Side by Side Diff: chrome/views/controls/menu/chrome_menu.cc

Issue 100022: Mouse hover out of context menu should un-select menu item.... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/views/controls/menu/chrome_menu.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/views/controls/menu/chrome_menu.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698