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 && ShouldEnterPushedState(event) && |
190 // !IsTriggerableEvent it could lead to a situation where we end up showing | 185 HitTestPoint(event.location()) && !InDrag()) { |
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(); | 186 Activate(); |
197 } else { | 187 } else { |
198 LabelButton::OnMouseReleased(event); | 188 LabelButton::OnMouseReleased(event); |
199 } | 189 } |
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 // If dragging is supported activate on release, otherwise activate on |
| 288 // pressed. |
| 289 ui::EventType active_on = |
| 290 GetDragOperations(mouseev.location()) == ui::DragDropTypes::DRAG_NONE ? |
| 291 ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED; |
| 292 return event.type() == active_on; |
| 293 } |
| 294 |
| 295 return event.type() == ui::ET_GESTURE_TAP; |
| 296 } |
| 297 |
290 void MenuButton::IncrementPressedLocked() { | 298 void MenuButton::IncrementPressedLocked() { |
291 ++pressed_lock_count_; | 299 ++pressed_lock_count_; |
292 SetState(STATE_PRESSED); | 300 SetState(STATE_PRESSED); |
293 } | 301 } |
294 | 302 |
295 void MenuButton::DecrementPressedLocked() { | 303 void MenuButton::DecrementPressedLocked() { |
296 --pressed_lock_count_; | 304 --pressed_lock_count_; |
297 DCHECK_GE(pressed_lock_count_, 0); | 305 DCHECK_GE(pressed_lock_count_, 0); |
298 | 306 |
299 // If this was the last lock, manually reset state to "normal". We set | 307 // 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 | 308 // "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 | 309 // 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 | 310 // selected an item) and we will inevitably refresh the hot state in the event |
303 // the mouse _is_ over the view. | 311 // the mouse _is_ over the view. |
304 if (pressed_lock_count_ == 0) | 312 if (pressed_lock_count_ == 0) |
305 SetState(STATE_NORMAL); | 313 SetState(STATE_NORMAL); |
306 } | 314 } |
307 | 315 |
308 int MenuButton::GetMaximumScreenXCoordinate() { | 316 int MenuButton::GetMaximumScreenXCoordinate() { |
309 if (!GetWidget()) { | 317 if (!GetWidget()) { |
310 NOTREACHED(); | 318 NOTREACHED(); |
311 return 0; | 319 return 0; |
312 } | 320 } |
313 | 321 |
314 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); | 322 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); |
315 return monitor_bounds.right() - 1; | 323 return monitor_bounds.right() - 1; |
316 } | 324 } |
317 | 325 |
318 } // namespace views | 326 } // namespace views |
OLD | NEW |