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