| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 MenuButton::MenuButton(const base::string16& text, | 65 MenuButton::MenuButton(const base::string16& text, |
| 66 MenuButtonListener* menu_button_listener, | 66 MenuButtonListener* menu_button_listener, |
| 67 bool show_menu_marker) | 67 bool show_menu_marker) |
| 68 : LabelButton(nullptr, text), | 68 : LabelButton(nullptr, text), |
| 69 menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY), | 69 menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY), |
| 70 listener_(menu_button_listener), | 70 listener_(menu_button_listener), |
| 71 show_menu_marker_(show_menu_marker), | 71 show_menu_marker_(show_menu_marker), |
| 72 menu_marker_(ui::ResourceBundle::GetSharedInstance() | 72 menu_marker_(ui::ResourceBundle::GetSharedInstance() |
| 73 .GetImageNamed(IDR_MENU_DROPARROW) | 73 .GetImageNamed(IDR_MENU_DROPARROW) |
| 74 .ToImageSkia()), | 74 .ToImageSkia()), |
| 75 destroyed_flag_(NULL), | 75 destroyed_flag_(nullptr), |
| 76 pressed_lock_count_(0), | 76 pressed_lock_count_(0), |
| 77 increment_pressed_lock_called_(nullptr), |
| 77 should_disable_after_press_(false), | 78 should_disable_after_press_(false), |
| 78 weak_factory_(this) { | 79 weak_factory_(this) { |
| 79 SetHorizontalAlignment(gfx::ALIGN_LEFT); | 80 SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 80 } | 81 } |
| 81 | 82 |
| 82 MenuButton::~MenuButton() { | 83 MenuButton::~MenuButton() { |
| 83 if (destroyed_flag_) | 84 if (destroyed_flag_) |
| 84 *destroyed_flag_ = true; | 85 *destroyed_flag_ = true; |
| 85 } | 86 } |
| 86 | 87 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 110 if (max_x_coordinate && max_x_coordinate <= menu_position.x()) | 111 if (max_x_coordinate && max_x_coordinate <= menu_position.x()) |
| 111 menu_position.set_x(max_x_coordinate - 1); | 112 menu_position.set_x(max_x_coordinate - 1); |
| 112 | 113 |
| 113 // We're about to show the menu from a mouse press. By showing from the | 114 // We're about to show the menu from a mouse press. By showing from the |
| 114 // mouse press event we block RootView in mouse dispatching. This also | 115 // mouse press event we block RootView in mouse dispatching. This also |
| 115 // appears to cause RootView to get a mouse pressed BEFORE the mouse | 116 // appears to cause RootView to get a mouse pressed BEFORE the mouse |
| 116 // release is seen, which means RootView sends us another mouse press no | 117 // release is seen, which means RootView sends us another mouse press no |
| 117 // matter where the user pressed. To force RootView to recalculate the | 118 // matter where the user pressed. To force RootView to recalculate the |
| 118 // mouse target during the mouse press we explicitly set the mouse handler | 119 // mouse target during the mouse press we explicitly set the mouse handler |
| 119 // to NULL. | 120 // to NULL. |
| 120 static_cast<internal::RootView*>(GetWidget()->GetRootView())-> | 121 static_cast<internal::RootView*>(GetWidget()->GetRootView()) |
| 121 SetMouseHandler(NULL); | 122 ->SetMouseHandler(nullptr); |
| 122 | 123 |
| 123 bool destroyed = false; | 124 bool destroyed = false; |
| 124 destroyed_flag_ = &destroyed; | 125 destroyed_flag_ = &destroyed; |
| 125 | 126 |
| 127 DCHECK(increment_pressed_lock_called_ == nullptr); |
| 128 // Observe if IncrementPressedLocked() was called so we can trigger the |
| 129 // correct ink drop animations. |
| 130 bool increment_pressed_lock_called = false; |
| 131 increment_pressed_lock_called_ = &increment_pressed_lock_called; |
| 132 |
| 126 // We don't set our state here. It's handled in the MenuController code or | 133 // We don't set our state here. It's handled in the MenuController code or |
| 127 // by our click listener. | 134 // by our click listener. |
| 128 | |
| 129 if (ink_drop_delegate()) | |
| 130 ink_drop_delegate()->OnAction(InkDropState::QUICK_ACTION); | |
| 131 listener_->OnMenuButtonClicked(this, menu_position, event); | 135 listener_->OnMenuButtonClicked(this, menu_position, event); |
| 132 | 136 |
| 133 if (destroyed) { | 137 if (destroyed) { |
| 134 // The menu was deleted while showing. Don't attempt any processing. | 138 // The menu was deleted while showing. Don't attempt any processing. |
| 135 return false; | 139 return false; |
| 136 } | 140 } |
| 137 | 141 |
| 138 destroyed_flag_ = NULL; | 142 increment_pressed_lock_called_ = nullptr; |
| 143 destroyed_flag_ = nullptr; |
| 139 | 144 |
| 140 menu_closed_time_ = TimeTicks::Now(); | 145 menu_closed_time_ = TimeTicks::Now(); |
| 141 | 146 |
| 147 if (ink_drop_delegate() && !increment_pressed_lock_called && |
| 148 pressed_lock_count_ == 0) { |
| 149 ink_drop_delegate()->OnAction(InkDropState::QUICK_ACTION); |
| 150 } |
| 151 |
| 142 // We must return false here so that the RootView does not get stuck | 152 // We must return false here so that the RootView does not get stuck |
| 143 // sending all mouse pressed events to us instead of the appropriate | 153 // sending all mouse pressed events to us instead of the appropriate |
| 144 // target. | 154 // target. |
| 145 return false; | 155 return false; |
| 146 } | 156 } |
| 157 |
| 158 if (ink_drop_delegate()) |
| 159 ink_drop_delegate()->OnAction(InkDropState::HIDDEN); |
| 147 return true; | 160 return true; |
| 148 } | 161 } |
| 149 | 162 |
| 150 bool MenuButton::IsTriggerableEventType(const ui::Event& event) { | 163 bool MenuButton::IsTriggerableEventType(const ui::Event& event) { |
| 151 if (event.IsMouseEvent()) { | 164 if (event.IsMouseEvent()) { |
| 152 const ui::MouseEvent& mouseev = static_cast<const ui::MouseEvent&>(event); | 165 const ui::MouseEvent& mouseev = static_cast<const ui::MouseEvent&>(event); |
| 153 // Active on left mouse button only, to prevent a menu from being activated | 166 // Active on left mouse button only, to prevent a menu from being activated |
| 154 // when a right-click would also activate a context menu. | 167 // when a right-click would also activate a context menu. |
| 155 if (!mouseev.IsOnlyLeftMouseButton()) | 168 if (!mouseev.IsOnlyLeftMouseButton()) |
| 156 return false; | 169 return false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 return kViewClassName; | 206 return kViewClassName; |
| 194 } | 207 } |
| 195 | 208 |
| 196 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) { | 209 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) { |
| 197 if (request_focus_on_press()) | 210 if (request_focus_on_press()) |
| 198 RequestFocus(); | 211 RequestFocus(); |
| 199 if (state() != STATE_DISABLED && HitTestPoint(event.location()) && | 212 if (state() != STATE_DISABLED && HitTestPoint(event.location()) && |
| 200 IsTriggerableEventType(event)) { | 213 IsTriggerableEventType(event)) { |
| 201 if (IsTriggerableEvent(event)) | 214 if (IsTriggerableEvent(event)) |
| 202 return Activate(&event); | 215 return Activate(&event); |
| 203 if (ink_drop_delegate()) | |
| 204 ink_drop_delegate()->OnAction(InkDropState::ACTION_PENDING); | |
| 205 } | 216 } |
| 206 return true; | 217 return true; |
| 207 } | 218 } |
| 208 | 219 |
| 209 void MenuButton::OnMouseReleased(const ui::MouseEvent& event) { | 220 void MenuButton::OnMouseReleased(const ui::MouseEvent& event) { |
| 210 if (state() != STATE_DISABLED && IsTriggerableEvent(event) && | 221 if (state() != STATE_DISABLED && IsTriggerableEvent(event) && |
| 211 HitTestPoint(event.location()) && !InDrag()) { | 222 HitTestPoint(event.location()) && !InDrag()) { |
| 212 Activate(&event); | 223 Activate(&event); |
| 213 } else { | 224 } else { |
| 214 if (ink_drop_delegate()) | 225 if (ink_drop_delegate()) |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 } | 363 } |
| 353 | 364 |
| 354 void MenuButton::NotifyClick(const ui::Event& event) { | 365 void MenuButton::NotifyClick(const ui::Event& event) { |
| 355 // We don't forward events to the normal button listener, instead using the | 366 // We don't forward events to the normal button listener, instead using the |
| 356 // MenuButtonListener. | 367 // MenuButtonListener. |
| 357 Activate(&event); | 368 Activate(&event); |
| 358 } | 369 } |
| 359 | 370 |
| 360 void MenuButton::IncrementPressedLocked() { | 371 void MenuButton::IncrementPressedLocked() { |
| 361 ++pressed_lock_count_; | 372 ++pressed_lock_count_; |
| 373 if (increment_pressed_lock_called_) |
| 374 *increment_pressed_lock_called_ = true; |
| 362 should_disable_after_press_ = state() == STATE_DISABLED; | 375 should_disable_after_press_ = state() == STATE_DISABLED; |
| 376 if (state() != STATE_PRESSED && ink_drop_delegate()) |
| 377 ink_drop_delegate()->OnAction(InkDropState::ACTIVATED); |
| 363 SetState(STATE_PRESSED); | 378 SetState(STATE_PRESSED); |
| 364 } | 379 } |
| 365 | 380 |
| 366 void MenuButton::DecrementPressedLocked() { | 381 void MenuButton::DecrementPressedLocked() { |
| 367 --pressed_lock_count_; | 382 --pressed_lock_count_; |
| 368 DCHECK_GE(pressed_lock_count_, 0); | 383 DCHECK_GE(pressed_lock_count_, 0); |
| 369 | 384 |
| 370 // If this was the last lock, manually reset state to the desired state. | 385 // If this was the last lock, manually reset state to the desired state. |
| 371 if (pressed_lock_count_ == 0) { | 386 if (pressed_lock_count_ == 0) { |
| 372 ButtonState desired_state = STATE_NORMAL; | 387 ButtonState desired_state = STATE_NORMAL; |
| 373 if (should_disable_after_press_) { | 388 if (should_disable_after_press_) { |
| 374 desired_state = STATE_DISABLED; | 389 desired_state = STATE_DISABLED; |
| 375 should_disable_after_press_ = false; | 390 should_disable_after_press_ = false; |
| 376 } else if (ShouldEnterHoveredState()) { | 391 } else if (ShouldEnterHoveredState()) { |
| 377 desired_state = STATE_HOVERED; | 392 desired_state = STATE_HOVERED; |
| 378 } | 393 } |
| 379 SetState(desired_state); | 394 SetState(desired_state); |
| 395 if (ink_drop_delegate() && state() != STATE_PRESSED) |
| 396 ink_drop_delegate()->OnAction(InkDropState::DEACTIVATED); |
| 380 } | 397 } |
| 381 } | 398 } |
| 382 | 399 |
| 383 int MenuButton::GetMaximumScreenXCoordinate() { | 400 int MenuButton::GetMaximumScreenXCoordinate() { |
| 384 if (!GetWidget()) { | 401 if (!GetWidget()) { |
| 385 NOTREACHED(); | 402 NOTREACHED(); |
| 386 return 0; | 403 return 0; |
| 387 } | 404 } |
| 388 | 405 |
| 389 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); | 406 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); |
| 390 return monitor_bounds.right() - 1; | 407 return monitor_bounds.right() - 1; |
| 391 } | 408 } |
| 392 | 409 |
| 393 } // namespace views | 410 } // namespace views |
| OLD | NEW |