| 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 |