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/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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 } | 164 } |
165 return prefsize; | 165 return prefsize; |
166 } | 166 } |
167 | 167 |
168 const char* MenuButton::GetClassName() const { | 168 const char* MenuButton::GetClassName() const { |
169 return kViewClassName; | 169 return kViewClassName; |
170 } | 170 } |
171 | 171 |
172 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) { | 172 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) { |
173 RequestFocus(); | 173 RequestFocus(); |
174 if (state() != STATE_DISABLED) { | 174 if (ShouldEnterPushedState(event) && HitTestPoint(event.location())) { |
175 // If we're draggable (GetDragOperations returns a non-zero value), then | 175 TimeDelta delta = TimeTicks::Now() - menu_closed_time_; |
176 // don't pop on press, instead wait for release. | 176 if (delta.InMilliseconds() > kMinimumMsBetweenButtonClicks) |
177 if (event.IsOnlyLeftMouseButton() && | 177 return Activate(); |
178 HitTestPoint(event.location()) && | |
179 GetDragOperations(event.location()) == ui::DragDropTypes::DRAG_NONE) { | |
180 TimeDelta delta = TimeTicks::Now() - menu_closed_time_; | |
181 if (delta.InMilliseconds() > kMinimumMsBetweenButtonClicks) | |
182 return Activate(); | |
183 } | |
184 } | 178 } |
185 return true; | 179 return true; |
186 } | 180 } |
187 | 181 |
188 void MenuButton::OnMouseReleased(const ui::MouseEvent& event) { | 182 void MenuButton::OnMouseReleased(const ui::MouseEvent& event) { |
189 // Explicitly test for left mouse button to show the menu. If we tested for | 183 if (ShouldEnterPushedState(event) && HitTestPoint(event.location())) |
190 // !IsTriggerableEvent it could lead to a situation where we end up showing | |
191 // the menu and context menu (this would happen if the right button is not | |
192 // triggerable and there's a context menu). | |
193 if (GetDragOperations(event.location()) != ui::DragDropTypes::DRAG_NONE && | |
194 state() != STATE_DISABLED && !InDrag() && event.IsOnlyLeftMouseButton() && | |
195 HitTestPoint(event.location())) { | |
196 Activate(); | 184 Activate(); |
197 } else { | 185 else |
198 LabelButton::OnMouseReleased(event); | 186 LabelButton::OnMouseReleased(event); |
199 } | |
200 } | 187 } |
201 | 188 |
202 void MenuButton::OnMouseEntered(const ui::MouseEvent& event) { | 189 void MenuButton::OnMouseEntered(const ui::MouseEvent& event) { |
203 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked. | 190 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked. |
204 CustomButton::OnMouseEntered(event); | 191 LabelButton::OnMouseEntered(event); |
205 } | 192 } |
206 | 193 |
207 void MenuButton::OnMouseExited(const ui::MouseEvent& event) { | 194 void MenuButton::OnMouseExited(const ui::MouseEvent& event) { |
208 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked. | 195 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked. |
209 CustomButton::OnMouseExited(event); | 196 LabelButton::OnMouseExited(event); |
210 } | 197 } |
211 | 198 |
212 void MenuButton::OnMouseMoved(const ui::MouseEvent& event) { | 199 void MenuButton::OnMouseMoved(const ui::MouseEvent& event) { |
213 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked. | 200 if (pressed_lock_count_ == 0) // Ignore mouse movement if state is locked. |
214 CustomButton::OnMouseMoved(event); | 201 LabelButton::OnMouseMoved(event); |
215 } | 202 } |
216 | 203 |
217 void MenuButton::OnGestureEvent(ui::GestureEvent* event) { | 204 void MenuButton::OnGestureEvent(ui::GestureEvent* event) { |
218 if (state() != STATE_DISABLED && event->type() == ui::ET_GESTURE_TAP && | 205 if (ShouldEnterPushedState(*event) && !Activate()) { |
219 !Activate()) { | |
220 // When |Activate()| returns |false|, it means that a menu is shown and | 206 // When |Activate()| returns |false|, it means that a menu is shown and |
221 // has handled the gesture event. So, there is no need to further process | 207 // has handled the gesture event. So, there is no need to further process |
222 // the gesture event here. | 208 // the gesture event here. |
223 return; | 209 return; |
224 } | 210 } |
225 LabelButton::OnGestureEvent(event); | 211 LabelButton::OnGestureEvent(event); |
226 } | 212 } |
227 | 213 |
228 bool MenuButton::OnKeyPressed(const ui::KeyEvent& event) { | 214 bool MenuButton::OnKeyPressed(const ui::KeyEvent& event) { |
229 switch (event.key_code()) { | 215 switch (event.key_code()) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 gfx::Size s = size(); | 266 gfx::Size s = size(); |
281 | 267 |
282 if (show_menu_marker_) { | 268 if (show_menu_marker_) { |
283 s.set_width(s.width() - menu_marker_->width() - kMenuMarkerPaddingLeft - | 269 s.set_width(s.width() - menu_marker_->width() - kMenuMarkerPaddingLeft - |
284 kMenuMarkerPaddingRight); | 270 kMenuMarkerPaddingRight); |
285 } | 271 } |
286 | 272 |
287 return gfx::Rect(s); | 273 return gfx::Rect(s); |
288 } | 274 } |
289 | 275 |
276 bool MenuButton::ShouldEnterPushedState(const ui::Event& event) { | |
277 if (state() == STATE_DISABLED) | |
sky
2014/10/14 20:05:06
This function shouldn't have to check disabled (ju
jonross
2014/10/14 21:42:17
Done.
| |
278 return false; | |
279 | |
280 if (event.IsMouseEvent()) { | |
281 const ui::MouseEvent& mouseev = static_cast<const ui::MouseEvent&>(event); | |
282 // Active on left mouse button only, to prevent a menu from being activated | |
283 // when a right-click would also activate a context menu. | |
284 if (!mouseev.IsOnlyLeftMouseButton()) | |
285 return false; | |
286 // If dragging is supported activate on release, otherwise activate on | |
287 // pressed. | |
288 ui::EventType active_on = | |
289 GetDragOperations(mouseev.location()) == ui::DragDropTypes::DRAG_NONE ? | |
290 ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED; | |
291 if (event.type() == active_on && !InDrag()) | |
sky
2014/10/14 20:05:06
I also think InDrag should be checked in the call
jonross
2014/10/14 21:42:17
Done.
| |
292 return true; | |
293 } | |
294 | |
295 if (event.type() == ui::ET_GESTURE_TAP) | |
sky
2014/10/14 20:05:06
nit: return event.type() == ET_GESTURE_TAP.
jonross
2014/10/14 21:42:17
Done.
| |
296 return true; | |
297 | |
298 return false; | |
299 } | |
300 | |
290 void MenuButton::IncrementPressedLocked() { | 301 void MenuButton::IncrementPressedLocked() { |
291 ++pressed_lock_count_; | 302 ++pressed_lock_count_; |
292 SetState(STATE_PRESSED); | 303 SetState(STATE_PRESSED); |
293 } | 304 } |
294 | 305 |
295 void MenuButton::DecrementPressedLocked() { | 306 void MenuButton::DecrementPressedLocked() { |
296 --pressed_lock_count_; | 307 --pressed_lock_count_; |
297 DCHECK_GE(pressed_lock_count_, 0); | 308 DCHECK_GE(pressed_lock_count_, 0); |
298 | 309 |
299 // If this was the last lock, manually reset state to "normal". We set | 310 // If this was the last lock, manually reset state to "normal". We set |
300 // "normal" and not "hot" because the likelihood is that the mouse is now | 311 // "normal" and not "hot" because the likelihood is that the mouse is now |
301 // somewhere else (user clicked elsewhere on screen to close the menu or | 312 // somewhere else (user clicked elsewhere on screen to close the menu or |
302 // selected an item) and we will inevitably refresh the hot state in the event | 313 // selected an item) and we will inevitably refresh the hot state in the event |
303 // the mouse _is_ over the view. | 314 // the mouse _is_ over the view. |
304 if (pressed_lock_count_ == 0) | 315 if (pressed_lock_count_ == 0) |
305 SetState(STATE_NORMAL); | 316 SetState(STATE_NORMAL); |
306 } | 317 } |
307 | 318 |
308 int MenuButton::GetMaximumScreenXCoordinate() { | 319 int MenuButton::GetMaximumScreenXCoordinate() { |
309 if (!GetWidget()) { | 320 if (!GetWidget()) { |
310 NOTREACHED(); | 321 NOTREACHED(); |
311 return 0; | 322 return 0; |
312 } | 323 } |
313 | 324 |
314 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); | 325 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); |
315 return monitor_bounds.right() - 1; | 326 return monitor_bounds.right() - 1; |
316 } | 327 } |
317 | 328 |
318 } // namespace views | 329 } // namespace views |
OLD | NEW |