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" |
| 11 #include "ui/base/resource/resource_bundle.h" | 11 #include "ui/base/resource/resource_bundle.h" |
| 12 #include "ui/base/ui_base_switches_util.h" | 12 #include "ui/base/ui_base_switches_util.h" |
| 13 #include "ui/events/event.h" | 13 #include "ui/events/event.h" |
| 14 #include "ui/events/event_constants.h" | 14 #include "ui/events/event_constants.h" |
| 15 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
| 16 #include "ui/gfx/image/image.h" | 16 #include "ui/gfx/image/image.h" |
| 17 #include "ui/gfx/screen.h" | 17 #include "ui/gfx/screen.h" |
| 18 #include "ui/gfx/text_constants.h" | 18 #include "ui/gfx/text_constants.h" |
| 19 #include "ui/resources/grit/ui_resources.h" | 19 #include "ui/resources/grit/ui_resources.h" |
| 20 #include "ui/strings/grit/ui_strings.h" | 20 #include "ui/strings/grit/ui_strings.h" |
| 21 #include "ui/views/animation/ink_drop_delegate.h" | 21 #include "ui/views/animation/ink_drop_delegate.h" |
| 22 #include "ui/views/controls/button/button.h" | 22 #include "ui/views/controls/button/button.h" |
| 23 #include "ui/views/controls/button/menu_button_listener.h" | 23 #include "ui/views/controls/button/menu_button_listener.h" |
| 24 #include "ui/views/controls/focusable_border.h" | |
| 24 #include "ui/views/mouse_constants.h" | 25 #include "ui/views/mouse_constants.h" |
| 25 #include "ui/views/resources/grit/views_resources.h" | 26 #include "ui/views/resources/grit/views_resources.h" |
| 27 #include "ui/views/style/platform_style.h" | |
| 26 #include "ui/views/widget/root_view.h" | 28 #include "ui/views/widget/root_view.h" |
| 27 #include "ui/views/widget/widget.h" | 29 #include "ui/views/widget/widget.h" |
| 28 | 30 |
| 29 using base::TimeTicks; | 31 using base::TimeTicks; |
| 30 using base::TimeDelta; | 32 using base::TimeDelta; |
| 31 | 33 |
| 32 namespace views { | 34 namespace views { |
| 33 | 35 |
| 34 // Default menu offset. | 36 // Default menu offset. |
| 35 static const int kDefaultMenuOffsetX = -2; | 37 static const int kDefaultMenuOffsetX = -2; |
| 36 static const int kDefaultMenuOffsetY = -4; | 38 static const int kDefaultMenuOffsetY = -4; |
| 37 | 39 |
| 38 // static | 40 // static |
| 39 const char MenuButton::kViewClassName[] = "MenuButton"; | 41 const char MenuButton::kViewClassName[] = "MenuButton"; |
| 40 const int MenuButton::kMenuMarkerPaddingLeft = 3; | |
| 41 const int MenuButton::kMenuMarkerPaddingRight = -1; | |
| 42 | 42 |
| 43 //////////////////////////////////////////////////////////////////////////////// | 43 //////////////////////////////////////////////////////////////////////////////// |
| 44 // | 44 // |
| 45 // MenuButton::PressedLock | 45 // MenuButton::PressedLock |
| 46 // | 46 // |
| 47 //////////////////////////////////////////////////////////////////////////////// | 47 //////////////////////////////////////////////////////////////////////////////// |
| 48 | 48 |
| 49 MenuButton::PressedLock::PressedLock(MenuButton* menu_button) | 49 MenuButton::PressedLock::PressedLock(MenuButton* menu_button) |
| 50 : PressedLock(menu_button, false) {} | 50 : PressedLock(menu_button, false) {} |
| 51 | 51 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 66 // | 66 // |
| 67 //////////////////////////////////////////////////////////////////////////////// | 67 //////////////////////////////////////////////////////////////////////////////// |
| 68 | 68 |
| 69 MenuButton::MenuButton(const base::string16& text, | 69 MenuButton::MenuButton(const base::string16& text, |
| 70 MenuButtonListener* menu_button_listener, | 70 MenuButtonListener* menu_button_listener, |
| 71 bool show_menu_marker) | 71 bool show_menu_marker) |
| 72 : LabelButton(nullptr, text), | 72 : LabelButton(nullptr, text), |
| 73 menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY), | 73 menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY), |
| 74 listener_(menu_button_listener), | 74 listener_(menu_button_listener), |
| 75 show_menu_marker_(show_menu_marker), | 75 show_menu_marker_(show_menu_marker), |
| 76 menu_marker_(ui::ResourceBundle::GetSharedInstance() | |
| 77 .GetImageNamed(IDR_MENU_DROPARROW) | |
| 78 .ToImageSkia()), | |
| 79 destroyed_flag_(nullptr), | 76 destroyed_flag_(nullptr), |
| 80 pressed_lock_count_(0), | 77 pressed_lock_count_(0), |
| 81 increment_pressed_lock_called_(nullptr), | 78 increment_pressed_lock_called_(nullptr), |
| 82 should_disable_after_press_(false), | 79 should_disable_after_press_(false), |
| 83 weak_factory_(this) { | 80 weak_factory_(this) { |
| 84 SetHorizontalAlignment(gfx::ALIGN_LEFT); | 81 SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 82 if (show_menu_marker_) { | |
| 83 menu_marker_ = PlatformStyle::CreateMenuButtonArrow(enabled()); | |
| 84 set_background(PlatformStyle::CreateMenuButtonBackground(GetShoulderWidth()) | |
|
tapted
2016/04/29 06:53:18
The background will need similar treatment to the
Elly Fong-Jones
2016/05/06 21:30:45
Done.
| |
| 85 .release()); | |
| 86 } | |
| 85 } | 87 } |
| 86 | 88 |
| 87 MenuButton::~MenuButton() { | 89 MenuButton::~MenuButton() { |
| 88 if (destroyed_flag_) | 90 if (destroyed_flag_) |
| 89 *destroyed_flag_ = true; | 91 *destroyed_flag_ = true; |
| 90 } | 92 } |
| 91 | 93 |
| 92 //////////////////////////////////////////////////////////////////////////////// | 94 //////////////////////////////////////////////////////////////////////////////// |
| 93 // | 95 // |
| 94 // MenuButton - Public APIs | 96 // MenuButton - Public APIs |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 } | 193 } |
| 192 | 194 |
| 193 //////////////////////////////////////////////////////////////////////////////// | 195 //////////////////////////////////////////////////////////////////////////////// |
| 194 // | 196 // |
| 195 // MenuButton - Events | 197 // MenuButton - Events |
| 196 // | 198 // |
| 197 //////////////////////////////////////////////////////////////////////////////// | 199 //////////////////////////////////////////////////////////////////////////////// |
| 198 | 200 |
| 199 gfx::Size MenuButton::GetPreferredSize() const { | 201 gfx::Size MenuButton::GetPreferredSize() const { |
| 200 gfx::Size prefsize = LabelButton::GetPreferredSize(); | 202 gfx::Size prefsize = LabelButton::GetPreferredSize(); |
| 201 if (show_menu_marker_) { | 203 prefsize.Enlarge(GetShoulderWidth(), 0); |
| 202 prefsize.Enlarge(menu_marker_->width() + kMenuMarkerPaddingLeft + | |
| 203 kMenuMarkerPaddingRight, | |
| 204 0); | |
| 205 } | |
| 206 return prefsize; | 204 return prefsize; |
| 207 } | 205 } |
| 208 | 206 |
| 209 const char* MenuButton::GetClassName() const { | 207 const char* MenuButton::GetClassName() const { |
| 210 return kViewClassName; | 208 return kViewClassName; |
| 211 } | 209 } |
| 212 | 210 |
| 213 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) { | 211 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) { |
| 214 if (request_focus_on_press()) | 212 if (request_focus_on_press()) |
| 215 RequestFocus(); | 213 RequestFocus(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 return false; | 302 return false; |
| 305 } | 303 } |
| 306 | 304 |
| 307 void MenuButton::GetAccessibleState(ui::AXViewState* state) { | 305 void MenuButton::GetAccessibleState(ui::AXViewState* state) { |
| 308 CustomButton::GetAccessibleState(state); | 306 CustomButton::GetAccessibleState(state); |
| 309 state->role = ui::AX_ROLE_POP_UP_BUTTON; | 307 state->role = ui::AX_ROLE_POP_UP_BUTTON; |
| 310 state->default_action = l10n_util::GetStringUTF16(IDS_APP_ACCACTION_PRESS); | 308 state->default_action = l10n_util::GetStringUTF16(IDS_APP_ACCACTION_PRESS); |
| 311 state->AddStateFlag(ui::AX_STATE_HASPOPUP); | 309 state->AddStateFlag(ui::AX_STATE_HASPOPUP); |
| 312 } | 310 } |
| 313 | 311 |
| 312 void MenuButton::OnEnabledChanged() { | |
| 313 if (show_menu_marker_) | |
| 314 menu_marker_ = PlatformStyle::CreateMenuButtonArrow(enabled()); | |
| 315 LabelButton::OnEnabledChanged(); | |
| 316 } | |
| 317 | |
| 318 void MenuButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { | |
| 319 if (ShouldUsePlatformStyleBorder()) | |
| 320 SetBorder(PlatformStyle::CreateMenuButtonBorder()); | |
| 321 } | |
| 322 | |
| 314 void MenuButton::PaintMenuMarker(gfx::Canvas* canvas) { | 323 void MenuButton::PaintMenuMarker(gfx::Canvas* canvas) { |
| 315 gfx::Insets insets = GetInsets(); | 324 gfx::Insets insets = GetInsets(); |
| 316 | 325 |
| 317 // Using the Views mirroring infrastructure incorrectly flips icon content. | 326 // Using the Views mirroring infrastructure incorrectly flips icon content. |
| 318 // Instead, manually mirror the position of the down arrow. | 327 // Instead, manually mirror the position of the down arrow. |
| 319 gfx::Rect arrow_bounds(width() - insets.right() - | 328 gfx::Rect arrow_bounds(width() - GetShoulderWidth(), 0, |
| 320 menu_marker_->width() - kMenuMarkerPaddingRight, | 329 GetShoulderWidth(), height()); |
| 321 height() / 2 - menu_marker_->height() / 2, | 330 arrow_bounds.ClampToCenteredSize(menu_marker_.size()); |
|
tapted
2016/04/29 06:53:18
With kMenuMarkerPaddingLeft/Right gone, won't this
Elly Fong-Jones
2016/05/06 21:30:45
I *think* that I accounted for that in GetShoulder
tapted
2016/05/09 08:01:35
GetShoulderWidth() is the sum though. It might wor
tapted
2016/05/10 08:03:23
Added Windows screenshots to http://crbug.com/6051
| |
| 322 menu_marker_->width(), | |
| 323 menu_marker_->height()); | |
| 324 arrow_bounds.set_x(GetMirroredXForRect(arrow_bounds)); | 331 arrow_bounds.set_x(GetMirroredXForRect(arrow_bounds)); |
| 325 canvas->DrawImageInt(*menu_marker_, arrow_bounds.x(), arrow_bounds.y()); | 332 canvas->DrawImageInt(menu_marker_, arrow_bounds.x(), arrow_bounds.y()); |
| 326 } | 333 } |
| 327 | 334 |
| 328 gfx::Rect MenuButton::GetChildAreaBounds() { | 335 gfx::Rect MenuButton::GetChildAreaBounds() { |
| 329 gfx::Size s = size(); | 336 return gfx::Rect(width() - GetShoulderWidth(), height()); |
| 330 | |
| 331 if (show_menu_marker_) { | |
| 332 s.set_width(s.width() - menu_marker_->width() - kMenuMarkerPaddingLeft - | |
| 333 kMenuMarkerPaddingRight); | |
| 334 } | |
| 335 | |
| 336 return gfx::Rect(s); | |
| 337 } | 337 } |
| 338 | 338 |
| 339 bool MenuButton::IsTriggerableEvent(const ui::Event& event) { | 339 bool MenuButton::IsTriggerableEvent(const ui::Event& event) { |
| 340 if (!IsTriggerableEventType(event)) | 340 if (!IsTriggerableEventType(event)) |
| 341 return false; | 341 return false; |
| 342 | 342 |
| 343 TimeDelta delta = TimeTicks::Now() - menu_closed_time_; | 343 TimeDelta delta = TimeTicks::Now() - menu_closed_time_; |
| 344 if (delta.InMilliseconds() < kMinimumMsBetweenButtonClicks) | 344 if (delta.InMilliseconds() < kMinimumMsBetweenButtonClicks) |
| 345 return false; // Not enough time since the menu closed. | 345 return false; // Not enough time since the menu closed. |
| 346 | 346 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 365 LabelButton::StateChanged(); | 365 LabelButton::StateChanged(); |
| 366 } | 366 } |
| 367 } | 367 } |
| 368 | 368 |
| 369 void MenuButton::NotifyClick(const ui::Event& event) { | 369 void MenuButton::NotifyClick(const ui::Event& event) { |
| 370 // We don't forward events to the normal button listener, instead using the | 370 // We don't forward events to the normal button listener, instead using the |
| 371 // MenuButtonListener. | 371 // MenuButtonListener. |
| 372 Activate(&event); | 372 Activate(&event); |
| 373 } | 373 } |
| 374 | 374 |
| 375 bool MenuButton::ShouldUsePlatformStyleBorder() const { | |
| 376 return false; | |
|
tapted
2016/04/29 06:53:18
nothing overrides this yet. I believe the current
Elly Fong-Jones
2016/05/06 21:30:45
I added some examples in views_examples for this.
| |
| 377 } | |
| 378 | |
| 375 void MenuButton::IncrementPressedLocked(bool snap_ink_drop_to_activated) { | 379 void MenuButton::IncrementPressedLocked(bool snap_ink_drop_to_activated) { |
| 376 ++pressed_lock_count_; | 380 ++pressed_lock_count_; |
| 377 if (increment_pressed_lock_called_) | 381 if (increment_pressed_lock_called_) |
| 378 *increment_pressed_lock_called_ = true; | 382 *increment_pressed_lock_called_ = true; |
| 379 should_disable_after_press_ = state() == STATE_DISABLED; | 383 should_disable_after_press_ = state() == STATE_DISABLED; |
| 380 if (state() != STATE_PRESSED && ink_drop_delegate()) { | 384 if (state() != STATE_PRESSED && ink_drop_delegate()) { |
| 381 if (snap_ink_drop_to_activated) | 385 if (snap_ink_drop_to_activated) |
| 382 ink_drop_delegate()->SnapToActivated(); | 386 ink_drop_delegate()->SnapToActivated(); |
| 383 else | 387 else |
| 384 ink_drop_delegate()->OnAction(InkDropState::ACTIVATED); | 388 ink_drop_delegate()->OnAction(InkDropState::ACTIVATED); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 408 int MenuButton::GetMaximumScreenXCoordinate() { | 412 int MenuButton::GetMaximumScreenXCoordinate() { |
| 409 if (!GetWidget()) { | 413 if (!GetWidget()) { |
| 410 NOTREACHED(); | 414 NOTREACHED(); |
| 411 return 0; | 415 return 0; |
| 412 } | 416 } |
| 413 | 417 |
| 414 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); | 418 gfx::Rect monitor_bounds = GetWidget()->GetWorkAreaBoundsInScreen(); |
| 415 return monitor_bounds.right() - 1; | 419 return monitor_bounds.right() - 1; |
| 416 } | 420 } |
| 417 | 421 |
| 422 int MenuButton::GetShoulderWidth() const { | |
| 423 const int kPadding = 7; | |
| 424 if (!show_menu_marker_) | |
| 425 return 0; | |
| 426 return menu_marker_.width() + 2 * kPadding; | |
| 427 } | |
| 428 | |
| 418 } // namespace views | 429 } // namespace views |
| OLD | NEW |