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/text_button.h" | 5 #include "ui/views/controls/button/text_button.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "grit/ui_resources.h" | 10 #include "grit/ui_resources.h" |
11 #include "ui/base/animation/throb_animation.h" | 11 #include "ui/base/animation/throb_animation.h" |
12 #include "ui/base/resource/resource_bundle.h" | 12 #include "ui/base/resource/resource_bundle.h" |
13 #include "ui/gfx/canvas.h" | 13 #include "ui/gfx/canvas.h" |
14 #include "ui/gfx/image/image.h" | 14 #include "ui/gfx/image/image.h" |
15 #include "ui/views/controls/button/button.h" | 15 #include "ui/views/controls/button/button.h" |
| 16 #include "ui/views/focus_border.h" |
16 #include "ui/views/widget/widget.h" | 17 #include "ui/views/widget/widget.h" |
17 | 18 |
18 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
19 #include "skia/ext/skia_utils_win.h" | 20 #include "skia/ext/skia_utils_win.h" |
20 #include "ui/base/native_theme/native_theme_win.h" | 21 #include "ui/base/native_theme/native_theme_win.h" |
21 #include "ui/gfx/platform_font_win.h" | 22 #include "ui/gfx/platform_font_win.h" |
22 #endif | 23 #endif |
23 | 24 |
24 namespace views { | 25 namespace views { |
25 | 26 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 color_highlight_(ui::NativeTheme::instance()->GetSystemColor( | 261 color_highlight_(ui::NativeTheme::instance()->GetSystemColor( |
261 ui::NativeTheme::kColorId_TextButtonHighlightColor)), | 262 ui::NativeTheme::kColorId_TextButtonHighlightColor)), |
262 color_hover_(ui::NativeTheme::instance()->GetSystemColor( | 263 color_hover_(ui::NativeTheme::instance()->GetSystemColor( |
263 ui::NativeTheme::kColorId_TextButtonHoverColor)), | 264 ui::NativeTheme::kColorId_TextButtonHoverColor)), |
264 text_halo_color_(0), | 265 text_halo_color_(0), |
265 has_text_halo_(false), | 266 has_text_halo_(false), |
266 active_text_shadow_color_(0), | 267 active_text_shadow_color_(0), |
267 inactive_text_shadow_color_(0), | 268 inactive_text_shadow_color_(0), |
268 has_shadow_(false), | 269 has_shadow_(false), |
269 shadow_offset_(gfx::Point(1, 1)), | 270 shadow_offset_(gfx::Point(1, 1)), |
| 271 min_width_(0), |
| 272 min_height_(0), |
270 max_width_(0), | 273 max_width_(0), |
271 show_multiple_icon_states_(true), | 274 show_multiple_icon_states_(true), |
272 is_default_(false), | 275 is_default_(false), |
273 multi_line_(false), | 276 multi_line_(false), |
274 prefix_type_(PREFIX_NONE) { | 277 prefix_type_(PREFIX_NONE) { |
275 SetText(text); | 278 SetText(text); |
276 SetAnimationDuration(kHoverAnimationDurationMs); | 279 SetAnimationDuration(kHoverAnimationDurationMs); |
277 } | 280 } |
278 | 281 |
279 TextButtonBase::~TextButtonBase() { | 282 TextButtonBase::~TextButtonBase() { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 // In multiline mode max size can be undefined while | 367 // In multiline mode max size can be undefined while |
365 // width() is 0, so max it out with current text size. | 368 // width() is 0, so max it out with current text size. |
366 gfx::Size prefsize(std::max(max_text_size_.width(), | 369 gfx::Size prefsize(std::max(max_text_size_.width(), |
367 text_size_.width()) + insets.width(), | 370 text_size_.width()) + insets.width(), |
368 std::max(max_text_size_.height(), | 371 std::max(max_text_size_.height(), |
369 text_size_.height()) + insets.height()); | 372 text_size_.height()) + insets.height()); |
370 | 373 |
371 if (max_width_ > 0) | 374 if (max_width_ > 0) |
372 prefsize.set_width(std::min(max_width_, prefsize.width())); | 375 prefsize.set_width(std::min(max_width_, prefsize.width())); |
373 | 376 |
| 377 prefsize.set_width(std::max(prefsize.height(), min_width_)); |
| 378 prefsize.set_height(std::max(prefsize.height(), min_height_)); |
| 379 |
374 return prefsize; | 380 return prefsize; |
375 } | 381 } |
376 | 382 |
377 int TextButtonBase::GetHeightForWidth(int w) { | 383 int TextButtonBase::GetHeightForWidth(int w) { |
378 if (!multi_line_) | 384 if (!multi_line_) |
379 return View::GetHeightForWidth(w); | 385 return View::GetHeightForWidth(w); |
380 | 386 |
381 if (max_width_ > 0) | 387 if (max_width_ > 0) |
382 w = std::min(max_width_, w); | 388 w = std::min(max_width_, w); |
383 | 389 |
384 gfx::Size text_size; | 390 gfx::Size text_size; |
385 CalculateTextSize(&text_size, w); | 391 CalculateTextSize(&text_size, w); |
386 return text_size.height() + GetInsets().height(); | 392 int height = text_size.height() + GetInsets().height(); |
| 393 |
| 394 return std::max(height, min_height_); |
387 } | 395 } |
388 | 396 |
389 void TextButtonBase::OnPaint(gfx::Canvas* canvas) { | 397 void TextButtonBase::OnPaint(gfx::Canvas* canvas) { |
390 PaintButton(canvas, PB_NORMAL); | 398 PaintButton(canvas, PB_NORMAL); |
391 } | 399 } |
392 | 400 |
393 void TextButtonBase::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 401 void TextButtonBase::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
394 if (multi_line_) | 402 if (multi_line_) |
395 UpdateTextSize(); | 403 UpdateTextSize(); |
396 } | 404 } |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 //////////////////////////////////////////////////////////////////////////////// | 671 //////////////////////////////////////////////////////////////////////////////// |
664 | 672 |
665 TextButton::TextButton(ButtonListener* listener, const string16& text) | 673 TextButton::TextButton(ButtonListener* listener, const string16& text) |
666 : TextButtonBase(listener, text), | 674 : TextButtonBase(listener, text), |
667 icon_placement_(ICON_ON_LEFT), | 675 icon_placement_(ICON_ON_LEFT), |
668 has_hover_icon_(false), | 676 has_hover_icon_(false), |
669 has_pushed_icon_(false), | 677 has_pushed_icon_(false), |
670 icon_text_spacing_(kDefaultIconTextSpacing), | 678 icon_text_spacing_(kDefaultIconTextSpacing), |
671 ignore_minimum_size_(true) { | 679 ignore_minimum_size_(true) { |
672 set_border(new TextButtonBorder); | 680 set_border(new TextButtonBorder); |
| 681 set_focus_border(FocusBorder::CreateDashedFocusBorder(kFocusRectInset, |
| 682 kFocusRectInset, |
| 683 kFocusRectInset, |
| 684 kFocusRectInset)); |
673 } | 685 } |
674 | 686 |
675 TextButton::~TextButton() { | 687 TextButton::~TextButton() { |
676 } | 688 } |
677 | 689 |
678 void TextButton::SetIcon(const gfx::ImageSkia& icon) { | 690 void TextButton::SetIcon(const gfx::ImageSkia& icon) { |
679 icon_ = icon; | 691 icon_ = icon; |
680 SchedulePaint(); | 692 SchedulePaint(); |
681 } | 693 } |
682 | 694 |
(...skipping 28 matching lines...) Expand all Loading... |
711 static_cast<gfx::PlatformFontWin*>(font_.platform_font()); | 723 static_cast<gfx::PlatformFontWin*>(font_.platform_font()); |
712 prefsize.set_width(std::max( | 724 prefsize.set_width(std::max( |
713 prefsize.width(), | 725 prefsize.width(), |
714 platform_font->horizontal_dlus_to_pixels(kMinWidthDLUs))); | 726 platform_font->horizontal_dlus_to_pixels(kMinWidthDLUs))); |
715 prefsize.set_height(std::max( | 727 prefsize.set_height(std::max( |
716 prefsize.height(), | 728 prefsize.height(), |
717 platform_font->vertical_dlus_to_pixels(kMinHeightDLUs))); | 729 platform_font->vertical_dlus_to_pixels(kMinHeightDLUs))); |
718 } | 730 } |
719 #endif | 731 #endif |
720 | 732 |
| 733 prefsize.set_width(std::max(prefsize.height(), min_width_)); |
| 734 prefsize.set_height(std::max(prefsize.height(), min_height_)); |
| 735 |
721 return prefsize; | 736 return prefsize; |
722 } | 737 } |
723 | 738 |
724 void TextButton::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { | 739 void TextButton::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { |
725 TextButtonBase::PaintButton(canvas, mode); | 740 TextButtonBase::PaintButton(canvas, mode); |
726 | 741 |
727 const gfx::ImageSkia& icon = GetImageToPaint(); | 742 const gfx::ImageSkia& icon = GetImageToPaint(); |
728 | 743 |
729 if (icon.width() > 0) { | 744 if (icon.width() > 0) { |
730 gfx::Rect text_bounds = GetTextBounds(); | 745 gfx::Rect text_bounds = GetTextBounds(); |
(...skipping 17 matching lines...) Expand all Loading... |
748 } | 763 } |
749 | 764 |
750 void TextButton::set_ignore_minimum_size(bool ignore_minimum_size) { | 765 void TextButton::set_ignore_minimum_size(bool ignore_minimum_size) { |
751 ignore_minimum_size_ = ignore_minimum_size; | 766 ignore_minimum_size_ = ignore_minimum_size; |
752 } | 767 } |
753 | 768 |
754 std::string TextButton::GetClassName() const { | 769 std::string TextButton::GetClassName() const { |
755 return kViewClassName; | 770 return kViewClassName; |
756 } | 771 } |
757 | 772 |
758 void TextButton::OnPaintFocusBorder(gfx::Canvas* canvas) { | |
759 if (HasFocus() && (focusable() || IsAccessibilityFocusable())) { | |
760 gfx::Rect rect(GetLocalBounds()); | |
761 rect.Inset(kFocusRectInset, kFocusRectInset); | |
762 canvas->DrawFocusRect(rect); | |
763 } | |
764 } | |
765 | |
766 ui::NativeTheme::Part TextButton::GetThemePart() const { | 773 ui::NativeTheme::Part TextButton::GetThemePart() const { |
767 return ui::NativeTheme::kPushButton; | 774 return ui::NativeTheme::kPushButton; |
768 } | 775 } |
769 | 776 |
770 void TextButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { | 777 void TextButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { |
771 TextButtonBase::GetExtraParams(params); | 778 TextButtonBase::GetExtraParams(params); |
772 params->button.is_default = is_default_; | 779 params->button.is_default = is_default_; |
773 } | 780 } |
774 | 781 |
775 gfx::Rect TextButton::GetTextBounds() const { | 782 gfx::Rect TextButton::GetTextBounds() const { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 | 829 |
823 void NativeTextButton::Init() { | 830 void NativeTextButton::Init() { |
824 #if defined(OS_WIN) | 831 #if defined(OS_WIN) |
825 // Windows will like to show its own colors. | 832 // Windows will like to show its own colors. |
826 // Halos and such are ignored as they are always set by specific calls. | 833 // Halos and such are ignored as they are always set by specific calls. |
827 color_enabled_ = skia::COLORREFToSkColor(GetSysColor(COLOR_BTNTEXT)); | 834 color_enabled_ = skia::COLORREFToSkColor(GetSysColor(COLOR_BTNTEXT)); |
828 color_disabled_ = skia::COLORREFToSkColor(GetSysColor(COLOR_GRAYTEXT)); | 835 color_disabled_ = skia::COLORREFToSkColor(GetSysColor(COLOR_GRAYTEXT)); |
829 color_hover_ = color_ = color_enabled_; | 836 color_hover_ = color_ = color_enabled_; |
830 #endif | 837 #endif |
831 set_border(new TextButtonNativeThemeBorder(this)); | 838 set_border(new TextButtonNativeThemeBorder(this)); |
| 839 #if !defined(OS_WIN) |
| 840 // Paint nothing, focus will be indicated with a border highlight drawn by |
| 841 // NativeThemeBase::PaintButton. |
| 842 set_focus_border(NULL); |
| 843 #endif |
832 set_ignore_minimum_size(false); | 844 set_ignore_minimum_size(false); |
833 set_alignment(ALIGN_CENTER); | 845 set_alignment(ALIGN_CENTER); |
834 set_focusable(true); | 846 set_focusable(true); |
835 } | 847 } |
836 | 848 |
837 gfx::Size NativeTextButton::GetMinimumSize() { | 849 gfx::Size NativeTextButton::GetMinimumSize() { |
838 return GetPreferredSize(); | 850 return GetPreferredSize(); |
839 } | 851 } |
840 | 852 |
841 std::string NativeTextButton::GetClassName() const { | 853 std::string NativeTextButton::GetClassName() const { |
842 return kViewClassName; | 854 return kViewClassName; |
843 } | 855 } |
844 | 856 |
845 void NativeTextButton::OnPaintFocusBorder(gfx::Canvas* canvas) { | |
846 #if defined(OS_WIN) | |
847 if (HasFocus() && (focusable() || IsAccessibilityFocusable())) { | |
848 gfx::Rect rect(GetLocalBounds()); | |
849 rect.Inset(kFocusRectInset, kFocusRectInset); | |
850 canvas->DrawFocusRect(rect); | |
851 } | |
852 #else | |
853 // Paint nothing, focus will be indicated with a border highlight drawn by | |
854 // NativeThemeBase::PaintButton. | |
855 #endif | |
856 } | |
857 | |
858 void NativeTextButton::GetExtraParams( | 857 void NativeTextButton::GetExtraParams( |
859 ui::NativeTheme::ExtraParams* params) const { | 858 ui::NativeTheme::ExtraParams* params) const { |
860 TextButton::GetExtraParams(params); | 859 TextButton::GetExtraParams(params); |
861 params->button.has_border = true; | 860 params->button.has_border = true; |
862 #if !defined(OS_WIN) | 861 #if !defined(OS_WIN) |
863 // Windows may paint a dotted focus rect in | 862 // Windows may paint a dotted focus rect in |
864 // NativeTextButton::OnPaintFocusBorder. To avoid getting two focus | 863 // NativeTextButton::OnPaintFocusBorder. To avoid getting two focus |
865 // indications (A dotted rect and a highlighted border) only set is_focused on | 864 // indications (A dotted rect and a highlighted border) only set is_focused on |
866 // non windows platforms. | 865 // non windows platforms. |
867 params->button.is_focused = HasFocus() && | 866 params->button.is_focused = HasFocus() && |
868 (focusable() || IsAccessibilityFocusable()); | 867 (focusable() || IsAccessibilityFocusable()); |
869 #endif | 868 #endif |
870 } | 869 } |
871 | 870 |
872 } // namespace views | 871 } // namespace views |
OLD | NEW |