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

Side by Side Diff: ui/views/controls/button/menu_button.cc

Issue 547303003: Keep reference view pressed while extension actions have a popup (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: MenuButton::PressedLock Created 6 years, 3 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
OLDNEW
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/button/menu_button.h" 5 #include "ui/views/controls/button/menu_button.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/accessibility/ax_view_state.h" 8 #include "ui/accessibility/ax_view_state.h"
9 #include "ui/base/dragdrop/drag_drop_types.h" 9 #include "ui/base/dragdrop/drag_drop_types.h"
10 #include "ui/base/l10n/l10n_util.h" 10 #include "ui/base/l10n/l10n_util.h"
(...skipping 21 matching lines...) Expand all
32 static const int kDefaultMenuOffsetX = -2; 32 static const int kDefaultMenuOffsetX = -2;
33 static const int kDefaultMenuOffsetY = -4; 33 static const int kDefaultMenuOffsetY = -4;
34 34
35 // static 35 // static
36 const char MenuButton::kViewClassName[] = "MenuButton"; 36 const char MenuButton::kViewClassName[] = "MenuButton";
37 const int MenuButton::kMenuMarkerPaddingLeft = 3; 37 const int MenuButton::kMenuMarkerPaddingLeft = 3;
38 const int MenuButton::kMenuMarkerPaddingRight = -1; 38 const int MenuButton::kMenuMarkerPaddingRight = -1;
39 39
40 //////////////////////////////////////////////////////////////////////////////// 40 ////////////////////////////////////////////////////////////////////////////////
41 // 41 //
42 // MenuButton::PressedLock
43 //
44 ////////////////////////////////////////////////////////////////////////////////
45
46 MenuButton::PressedLock::PressedLock(MenuButton* menu_button)
47 : menu_button_(menu_button->weak_factory_.GetWeakPtr()) {
48 menu_button_->PressedLocked();
49 }
50
51 MenuButton::PressedLock::~PressedLock() {
52 if (menu_button_.get())
53 menu_button_->PressedUnlocked();
54 }
55
56 ////////////////////////////////////////////////////////////////////////////////
57 //
42 // MenuButton - constructors, destructors, initialization 58 // MenuButton - constructors, destructors, initialization
43 // 59 //
44 //////////////////////////////////////////////////////////////////////////////// 60 ////////////////////////////////////////////////////////////////////////////////
45 61
46 MenuButton::MenuButton(ButtonListener* listener, 62 MenuButton::MenuButton(ButtonListener* listener,
47 const base::string16& text, 63 const base::string16& text,
48 MenuButtonListener* menu_button_listener, 64 MenuButtonListener* menu_button_listener,
49 bool show_menu_marker) 65 bool show_menu_marker)
50 : LabelButton(listener, text), 66 : LabelButton(listener, text),
51 menu_visible_(false),
52 menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY), 67 menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY),
53 listener_(menu_button_listener), 68 listener_(menu_button_listener),
54 show_menu_marker_(show_menu_marker), 69 show_menu_marker_(show_menu_marker),
55 menu_marker_(ui::ResourceBundle::GetSharedInstance().GetImageNamed( 70 menu_marker_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
56 IDR_MENU_DROPARROW).ToImageSkia()), 71 IDR_MENU_DROPARROW).ToImageSkia()),
57 destroyed_flag_(NULL) { 72 destroyed_flag_(NULL),
73 pressed_lock_count_(0),
74 weak_factory_(this) {
58 SetHorizontalAlignment(gfx::ALIGN_LEFT); 75 SetHorizontalAlignment(gfx::ALIGN_LEFT);
59 } 76 }
60 77
61 MenuButton::~MenuButton() { 78 MenuButton::~MenuButton() {
62 if (destroyed_flag_) 79 if (destroyed_flag_)
63 *destroyed_flag_ = true; 80 *destroyed_flag_ = true;
64 } 81 }
65 82
66 //////////////////////////////////////////////////////////////////////////////// 83 ////////////////////////////////////////////////////////////////////////////////
67 // 84 //
(...skipping 25 matching lines...) Expand all
93 // We're about to show the menu from a mouse press. By showing from the 110 // We're about to show the menu from a mouse press. By showing from the
94 // mouse press event we block RootView in mouse dispatching. This also 111 // mouse press event we block RootView in mouse dispatching. This also
95 // appears to cause RootView to get a mouse pressed BEFORE the mouse 112 // appears to cause RootView to get a mouse pressed BEFORE the mouse
96 // release is seen, which means RootView sends us another mouse press no 113 // release is seen, which means RootView sends us another mouse press no
97 // matter where the user pressed. To force RootView to recalculate the 114 // matter where the user pressed. To force RootView to recalculate the
98 // mouse target during the mouse press we explicitly set the mouse handler 115 // mouse target during the mouse press we explicitly set the mouse handler
99 // to NULL. 116 // to NULL.
100 static_cast<internal::RootView*>(GetWidget()->GetRootView())-> 117 static_cast<internal::RootView*>(GetWidget()->GetRootView())->
101 SetMouseHandler(NULL); 118 SetMouseHandler(NULL);
102 119
103 menu_visible_ = true;
104
105 bool destroyed = false; 120 bool destroyed = false;
106 destroyed_flag_ = &destroyed; 121 destroyed_flag_ = &destroyed;
107 122
123 // We don't set our state here. It's handled in the MenuController code or
124 // by our click listener.
125
108 listener_->OnMenuButtonClicked(this, menu_position); 126 listener_->OnMenuButtonClicked(this, menu_position);
109 127
110 if (destroyed) { 128 if (destroyed) {
111 // The menu was deleted while showing. Don't attempt any processing. 129 // The menu was deleted while showing. Don't attempt any processing.
112 return false; 130 return false;
113 } 131 }
114 132
115 destroyed_flag_ = NULL; 133 destroyed_flag_ = NULL;
116 134
117 menu_visible_ = false;
118 menu_closed_time_ = TimeTicks::Now(); 135 menu_closed_time_ = TimeTicks::Now();
119 136
120 // Now that the menu has closed, we need to manually reset state to 137 //SetState(STATE_NORMAL);
sky 2014/09/19 21:21:59 Fix these.
Devlin 2014/09/19 22:37:48 Done.
121 // "normal" since the menu modal loop will have prevented normal 138 //if (!pressed_lock_count_)
122 // mouse move messages from getting to this View. We set "normal" 139 // SetState(STATE_NORMAL);
123 // and not "hot" because the likelihood is that the mouse is now
124 // somewhere else (user clicked elsewhere on screen to close the menu
125 // or selected an item) and we will inevitably refresh the hot state
126 // in the event the mouse _is_ over the view.
127 SetState(STATE_NORMAL);
128 140
129 // We must return false here so that the RootView does not get stuck 141 // We must return false here so that the RootView does not get stuck
130 // sending all mouse pressed events to us instead of the appropriate 142 // sending all mouse pressed events to us instead of the appropriate
131 // target. 143 // target.
132 return false; 144 return false;
133 } 145 }
134 return true; 146 return true;
135 } 147 }
136 148
137 void MenuButton::OnPaint(gfx::Canvas* canvas) { 149 void MenuButton::OnPaint(gfx::Canvas* canvas) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // triggerable and there's a context menu). 196 // triggerable and there's a context menu).
185 if (GetDragOperations(event.location()) != ui::DragDropTypes::DRAG_NONE && 197 if (GetDragOperations(event.location()) != ui::DragDropTypes::DRAG_NONE &&
186 state() != STATE_DISABLED && !InDrag() && event.IsOnlyLeftMouseButton() && 198 state() != STATE_DISABLED && !InDrag() && event.IsOnlyLeftMouseButton() &&
187 HitTestPoint(event.location())) { 199 HitTestPoint(event.location())) {
188 Activate(); 200 Activate();
189 } else { 201 } else {
190 LabelButton::OnMouseReleased(event); 202 LabelButton::OnMouseReleased(event);
191 } 203 }
192 } 204 }
193 205
194 // The reason we override View::OnMouseExited is because we get this event when 206 void MenuButton::OnMouseEntered(const ui::MouseEvent& event) {
195 // we display the menu. If we don't override this method then 207 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked.
196 // BaseButton::OnMouseExited will get the event and will set the button's state 208 CustomButton::OnMouseEntered(event);
197 // to STATE_NORMAL instead of keeping the state BM_PUSHED. This, in turn, will 209 }
198 // cause the button to appear depressed while the menu is displayed. 210
199 void MenuButton::OnMouseExited(const ui::MouseEvent& event) { 211 void MenuButton::OnMouseExited(const ui::MouseEvent& event) {
200 if ((state_ != STATE_DISABLED) && (!menu_visible_) && (!InDrag())) { 212 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked.
201 SetState(STATE_NORMAL); 213 CustomButton::OnMouseExited(event);
202 } 214 }
215
216 void MenuButton::OnMouseMoved(const ui::MouseEvent& event) {
217 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked.
218 CustomButton::OnMouseMoved(event);
203 } 219 }
204 220
205 void MenuButton::OnGestureEvent(ui::GestureEvent* event) { 221 void MenuButton::OnGestureEvent(ui::GestureEvent* event) {
206 if (state() != STATE_DISABLED && event->type() == ui::ET_GESTURE_TAP && 222 if (state() != STATE_DISABLED && event->type() == ui::ET_GESTURE_TAP &&
207 !Activate()) { 223 !Activate()) {
208 // When |Activate()| returns |false|, it means that a menu is shown and 224 // When |Activate()| returns |false|, it means that a menu is shown and
209 // has handled the gesture event. So, there is no need to further process 225 // has handled the gesture event. So, there is no need to further process
210 // the gesture event here. 226 // the gesture event here.
211 return; 227 return;
212 } 228 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 gfx::Size s = size(); 284 gfx::Size s = size();
269 285
270 if (show_menu_marker_) { 286 if (show_menu_marker_) {
271 s.set_width(s.width() - menu_marker_->width() - kMenuMarkerPaddingLeft - 287 s.set_width(s.width() - menu_marker_->width() - kMenuMarkerPaddingLeft -
272 kMenuMarkerPaddingRight); 288 kMenuMarkerPaddingRight);
273 } 289 }
274 290
275 return gfx::Rect(s); 291 return gfx::Rect(s);
276 } 292 }
277 293
294 void MenuButton::PressedLocked() {
295 ++pressed_lock_count_;
296 SetState(STATE_PRESSED);
297 }
298
299 void MenuButton::PressedUnlocked() {
300 --pressed_lock_count_;
301 DCHECK_GE(pressed_lock_count_, 0);
302
303 // If this was the last lock, manually reset state to "normal". We set
304 // "normal" and not "hot" because the likelihood is that the mouse is now
305 // somewhere else (user clicked elsewhere on screen to close the menu or
306 // selected an item) and we will inevitably refresh the hot state in the event
307 // the mouse _is_ over the view.
308 if (pressed_lock_count_ == 0)
309 SetState(STATE_NORMAL);
310 }
311
278 int MenuButton::GetMaximumScreenXCoordinate() { 312 int MenuButton::GetMaximumScreenXCoordinate() {
279 if (!GetWidget()) { 313 if (!GetWidget()) {
280 NOTREACHED(); 314 NOTREACHED();
281 return 0; 315 return 0;
282 } 316 }
283 317
284 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); 318 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen();
285 return monitor_bounds.right() - 1; 319 return monitor_bounds.right() - 1;
286 } 320 }
287 321
288 } // namespace views 322 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698