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

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

Issue 2607923002: MacViews: Handle Space and Return keys correctly for Buttons. (Closed)
Patch Set: Address review. Created 3 years, 11 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/custom_button.h" 5 #include "ui/views/controls/button/custom_button.h"
6 6
7 #include "ui/accessibility/ax_node_data.h" 7 #include "ui/accessibility/ax_node_data.h"
8 #include "ui/events/event.h" 8 #include "ui/events/event.h"
9 #include "ui/events/event_utils.h" 9 #include "ui/events/event_utils.h"
10 #include "ui/events/keycodes/keyboard_codes.h" 10 #include "ui/events/keycodes/keyboard_codes.h"
11 #include "ui/gfx/animation/throb_animation.h" 11 #include "ui/gfx/animation/throb_animation.h"
12 #include "ui/gfx/color_palette.h" 12 #include "ui/gfx/color_palette.h"
13 #include "ui/native_theme/native_theme.h" 13 #include "ui/native_theme/native_theme.h"
14 #include "ui/views/animation/ink_drop_highlight.h" 14 #include "ui/views/animation/ink_drop_highlight.h"
15 #include "ui/views/animation/ink_drop_impl.h" 15 #include "ui/views/animation/ink_drop_impl.h"
16 #include "ui/views/controls/button/blue_button.h" 16 #include "ui/views/controls/button/blue_button.h"
17 #include "ui/views/controls/button/checkbox.h" 17 #include "ui/views/controls/button/checkbox.h"
18 #include "ui/views/controls/button/image_button.h" 18 #include "ui/views/controls/button/image_button.h"
19 #include "ui/views/controls/button/label_button.h" 19 #include "ui/views/controls/button/label_button.h"
20 #include "ui/views/controls/button/menu_button.h" 20 #include "ui/views/controls/button/menu_button.h"
21 #include "ui/views/controls/button/radio_button.h" 21 #include "ui/views/controls/button/radio_button.h"
22 #include "ui/views/controls/button/toggle_button.h" 22 #include "ui/views/controls/button/toggle_button.h"
23 #include "ui/views/style/platform_style.h"
23 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
24 25
25 #if defined(USE_AURA) 26 #if defined(USE_AURA)
26 #include "ui/aura/client/capture_client.h" 27 #include "ui/aura/client/capture_client.h"
27 #include "ui/aura/window.h" 28 #include "ui/aura/window.h"
28 #endif 29 #endif
29 30
30 namespace views { 31 namespace views {
31 32
32 namespace { 33 namespace {
33 34
34 // How long the hover animation takes if uninterrupted. 35 // How long the hover animation takes if uninterrupted.
35 const int kHoverFadeDurationMs = 150; 36 const int kHoverFadeDurationMs = 150;
36 37
38 CustomButton::ClickAction GetClickActionForKeyEvent(const ui::KeyEvent& event) {
39 if (event.key_code() == ui::VKEY_SPACE)
40 return PlatformStyle::kClickActionOnSpace;
41 if (event.key_code() == ui::VKEY_RETURN &&
42 PlatformStyle::kReturnClicksFocusedControl)
43 return CustomButton::CLICK_ON_PRESS;
44 return CustomButton::CLICK_NONE;
45 }
46
37 } // namespace 47 } // namespace
38 48
39 //////////////////////////////////////////////////////////////////////////////// 49 ////////////////////////////////////////////////////////////////////////////////
40 // CustomButton, public: 50 // CustomButton, public:
41 51
42 // static 52 // static
43 const char CustomButton::kViewClassName[] = "CustomButton"; 53 const char CustomButton::kViewClassName[] = "CustomButton";
44 54
45 // static 55 // static
46 const CustomButton* CustomButton::AsCustomButton(const views::View* view) { 56 const CustomButton* CustomButton::AsCustomButton(const views::View* view) {
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 241
232 void CustomButton::OnMouseMoved(const ui::MouseEvent& event) { 242 void CustomButton::OnMouseMoved(const ui::MouseEvent& event) {
233 if (state_ != STATE_DISABLED) 243 if (state_ != STATE_DISABLED)
234 SetState(HitTestPoint(event.location()) ? STATE_HOVERED : STATE_NORMAL); 244 SetState(HitTestPoint(event.location()) ? STATE_HOVERED : STATE_NORMAL);
235 } 245 }
236 246
237 bool CustomButton::OnKeyPressed(const ui::KeyEvent& event) { 247 bool CustomButton::OnKeyPressed(const ui::KeyEvent& event) {
238 if (state_ == STATE_DISABLED) 248 if (state_ == STATE_DISABLED)
239 return false; 249 return false;
240 250
241 // Space sets button state to pushed. Enter clicks the button. This matches 251 switch (GetClickActionForKeyEvent(event)) {
242 // the Windows native behavior of buttons, where Space clicks the button on 252 case ClickAction::CLICK_ON_RELEASE:
243 // KeyRelease and Enter clicks the button on KeyPressed. 253 SetState(STATE_PRESSED);
244 if (event.key_code() == ui::VKEY_SPACE) { 254 if (GetInkDrop()->GetTargetInkDropState() !=
245 SetState(STATE_PRESSED); 255 InkDropState::ACTION_PENDING) {
246 if (GetInkDrop()->GetTargetInkDropState() != 256 AnimateInkDrop(InkDropState::ACTION_PENDING, nullptr /* event */);
247 views::InkDropState::ACTION_PENDING) { 257 }
248 AnimateInkDrop(views::InkDropState::ACTION_PENDING, nullptr /* event */); 258 return true;
249 } 259 case ClickAction::CLICK_ON_PRESS:
250 } else if (event.key_code() == ui::VKEY_RETURN) { 260 SetState(STATE_NORMAL);
251 SetState(STATE_NORMAL); 261 NotifyClick(event);
252 NotifyClick(event); 262 return true;
253 } else { 263 case ClickAction::CLICK_NONE:
264 return false;
265 }
266
267 NOTREACHED();
268 return false;
269 }
270
271 bool CustomButton::OnKeyReleased(const ui::KeyEvent& event) {
272 const bool click_button =
273 state_ == STATE_PRESSED &&
274 GetClickActionForKeyEvent(event) == ClickAction::CLICK_ON_RELEASE;
275 if (!click_button)
254 return false; 276 return false;
255 } 277
278 SetState(STATE_NORMAL);
279 NotifyClick(event);
256 return true; 280 return true;
257 } 281 }
258 282
259 bool CustomButton::OnKeyReleased(const ui::KeyEvent& event) {
260 if ((state_ == STATE_PRESSED) && (event.key_code() == ui::VKEY_SPACE)) {
261 SetState(STATE_NORMAL);
262 NotifyClick(event);
263 return true;
264 }
265 return false;
266 }
267
268 void CustomButton::OnGestureEvent(ui::GestureEvent* event) { 283 void CustomButton::OnGestureEvent(ui::GestureEvent* event) {
269 if (state_ == STATE_DISABLED) { 284 if (state_ == STATE_DISABLED) {
270 Button::OnGestureEvent(event); 285 Button::OnGestureEvent(event);
271 return; 286 return;
272 } 287 }
273 288
274 if (event->type() == ui::ET_GESTURE_TAP && IsTriggerableEvent(*event)) { 289 if (event->type() == ui::ET_GESTURE_TAP && IsTriggerableEvent(*event)) {
275 // Set the button state to hot and start the animation fully faded in. The 290 // Set the button state to hot and start the animation fully faded in. The
276 // GESTURE_END event issued immediately after will set the state to 291 // GESTURE_END event issued immediately after will set the state to
277 // STATE_NORMAL beginning the fade out animation. See 292 // STATE_NORMAL beginning the fade out animation. See
(...skipping 21 matching lines...) Expand all
299 // TODO(beng): remove once NotifyClick takes ui::Event. 314 // TODO(beng): remove once NotifyClick takes ui::Event.
300 ui::MouseEvent synthetic_event( 315 ui::MouseEvent synthetic_event(
301 ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 316 ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(),
302 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); 317 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
303 NotifyClick(synthetic_event); 318 NotifyClick(synthetic_event);
304 return true; 319 return true;
305 } 320 }
306 321
307 bool CustomButton::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { 322 bool CustomButton::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
308 // If this button is focused and the user presses space or enter, don't let 323 // If this button is focused and the user presses space or enter, don't let
309 // that be treated as an accelerator. 324 // that be treated as an accelerator if there is a button action corresponding
310 return (event.key_code() == ui::VKEY_SPACE) || 325 // to it.
311 (event.key_code() == ui::VKEY_RETURN); 326 return GetClickActionForKeyEvent(event) != ClickAction::CLICK_NONE;
312 } 327 }
313 328
314 void CustomButton::ShowContextMenu(const gfx::Point& p, 329 void CustomButton::ShowContextMenu(const gfx::Point& p,
315 ui::MenuSourceType source_type) { 330 ui::MenuSourceType source_type) {
316 if (!context_menu_controller()) 331 if (!context_menu_controller())
317 return; 332 return;
318 333
319 // We're about to show the context menu. Showing the context menu likely means 334 // We're about to show the context menu. Showing the context menu likely means
320 // we won't get a mouse exited and reset state. Reset it now to be sure. 335 // we won't get a mouse exited and reset state. Reset it now to be sure.
321 if (state_ != STATE_DISABLED) 336 if (state_ != STATE_DISABLED)
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 views::InkDropState::ACTION_PENDING || 490 views::InkDropState::ACTION_PENDING ||
476 GetInkDrop()->GetTargetInkDropState() == 491 GetInkDrop()->GetTargetInkDropState() ==
477 views::InkDropState::ALTERNATE_ACTION_PENDING) { 492 views::InkDropState::ALTERNATE_ACTION_PENDING) {
478 AnimateInkDrop(views::InkDropState::HIDDEN, 493 AnimateInkDrop(views::InkDropState::HIDDEN,
479 ui::LocatedEvent::FromIfValid(&event)); 494 ui::LocatedEvent::FromIfValid(&event));
480 } 495 }
481 Button::OnClickCanceled(event); 496 Button::OnClickCanceled(event);
482 } 497 }
483 498
484 } // namespace views 499 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698