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/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/focus_border.h" |
| 17 #include "ui/views/widget/widget.h" | 17 #include "ui/views/widget/widget.h" |
| 18 | 18 |
| 19 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
| 20 #include "skia/ext/skia_utils_win.h" | 20 #include "skia/ext/skia_utils_win.h" |
| 21 #include "ui/base/native_theme/native_theme_win.h" | 21 #include "ui/base/native_theme/native_theme_win.h" |
| 22 #include "ui/gfx/platform_font_win.h" | 22 #include "ui/gfx/platform_font_win.h" |
| 23 #endif | 23 #endif |
| 24 | 24 |
| 25 namespace views { | 25 namespace views { |
| 26 | 26 |
| 27 #if defined(OS_WIN) | 27 namespace { |
| 28 // The min size in DLUs comes from | |
| 29 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/c h14e.asp | |
| 30 static const int kMinWidthDLUs = 50; | |
| 31 static const int kMinHeightDLUs = 14; | |
| 32 #endif | |
| 33 | |
| 34 | 28 |
| 35 // Default space between the icon and text. | 29 // Default space between the icon and text. |
| 36 static const int kDefaultIconTextSpacing = 5; | 30 static const int kDefaultIconTextSpacing = 5; |
|
tfarina
2012/10/26 00:40:18
nit: since we are here, can we remove the 'static'
msw
2012/10/27 07:40:57
Done (same for label_button.cc) and moved PrefixTy
| |
| 37 | 31 |
| 38 // Preferred padding between text and edge. | 32 // Preferred padding between text and edge. |
| 39 static const int kPreferredPaddingHorizontal = 6; | 33 static const int kPreferredPaddingHorizontal = 6; |
| 40 static const int kPreferredPaddingVertical = 5; | 34 static const int kPreferredPaddingVertical = 5; |
| 41 | 35 |
| 42 // Preferred padding between text and edge for NativeTheme border. | 36 // Preferred padding between text and edge for NativeTheme border. |
| 43 static const int kPreferredNativeThemePaddingHorizontal = 12; | 37 static const int kPreferredNativeThemePaddingHorizontal = 12; |
| 44 static const int kPreferredNativeThemePaddingVertical = 5; | 38 static const int kPreferredNativeThemePaddingVertical = 5; |
| 45 | 39 |
| 46 // By default the focus rect is drawn at the border of the view. | 40 // By default the focus rect is drawn at the border of the view. |
| 47 // For a button, we inset the focus rect by 3 pixels so that it | 41 // For a button, we inset the focus rect by 3 pixels so that it |
| 48 // doesn't draw on top of the button's border. This roughly matches | 42 // doesn't draw on top of the button's border. This roughly matches |
| 49 // how the Windows native focus rect for buttons looks. A subclass | 43 // how the Windows native focus rect for buttons looks. A subclass |
| 50 // that draws a button with different padding may need to | 44 // that draws a button with different padding may need to |
| 51 // override OnPaintFocusBorder and do something different. | 45 // override OnPaintFocusBorder and do something different. |
| 52 static const int kFocusRectInset = 3; | 46 static const int kFocusRectInset = 3; |
| 53 | 47 |
| 54 // How long the hover fade animation should last. | 48 // How long the hover fade animation should last. |
| 55 static const int kHoverAnimationDurationMs = 170; | 49 static const int kHoverAnimationDurationMs = 170; |
| 56 | 50 |
| 51 #if defined(OS_WIN) | |
| 52 // These sizes are from http://msdn.microsoft.com/en-us/library/aa511279.aspx | |
| 53 static const int kMinWidthDLUs = 50; | |
| 54 static const int kMinHeightDLUs = 14; | |
| 55 #endif | |
| 56 | |
| 57 } // namespace | |
| 58 | |
| 57 // static | 59 // static |
| 58 const char TextButtonBase::kViewClassName[] = "views/TextButtonBase"; | 60 const char TextButtonBase::kViewClassName[] = "views/TextButtonBase"; |
| 59 // static | 61 // static |
| 60 const char TextButton::kViewClassName[] = "views/TextButton"; | 62 const char TextButton::kViewClassName[] = "views/TextButton"; |
| 61 // static | 63 // static |
| 62 const char NativeTextButton::kViewClassName[] = "views/NativeTextButton"; | 64 const char NativeTextButton::kViewClassName[] = "views/NativeTextButton"; |
| 63 | 65 |
| 64 static int PrefixTypeToCanvasType(TextButton::PrefixType type) { | 66 static int PrefixTypeToCanvasType(TextButton::PrefixType type) { |
| 65 switch (type) { | 67 switch (type) { |
| 66 case TextButton::PREFIX_HIDE: | 68 case TextButton::PREFIX_HIDE: |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 77 | 79 |
| 78 //////////////////////////////////////////////////////////////////////////////// | 80 //////////////////////////////////////////////////////////////////////////////// |
| 79 // | 81 // |
| 80 // TextButtonBorder - constructors, destructors, initialization | 82 // TextButtonBorder - constructors, destructors, initialization |
| 81 // | 83 // |
| 82 //////////////////////////////////////////////////////////////////////////////// | 84 //////////////////////////////////////////////////////////////////////////////// |
| 83 | 85 |
| 84 TextButtonBorder::TextButtonBorder() | 86 TextButtonBorder::TextButtonBorder() |
| 85 : vertical_padding_(kPreferredPaddingVertical) { | 87 : vertical_padding_(kPreferredPaddingVertical) { |
| 86 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 88 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 87 BorderImageSet normal_set = { | 89 set_hot_set(BorderImages(BorderImages::kHot)); |
| 88 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 90 set_pushed_set(BorderImages(BorderImages::kPushed)); |
| 89 }; | |
| 90 set_normal_set(normal_set); | |
| 91 | |
| 92 BorderImageSet hot_set = { | |
| 93 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_TOP_LEFT).ToImageSkia(), | |
| 94 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_TOP).ToImageSkia(), | |
| 95 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_TOP_RIGHT).ToImageSkia(), | |
| 96 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_LEFT).ToImageSkia(), | |
| 97 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_CENTER).ToImageSkia(), | |
| 98 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_RIGHT).ToImageSkia(), | |
| 99 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_BOTTOM_LEFT).ToImageSkia(), | |
| 100 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_BOTTOM).ToImageSkia(), | |
| 101 rb.GetImageNamed(IDR_TEXTBUTTON_HOVER_BOTTOM_RIGHT).ToImageSkia(), | |
| 102 }; | |
| 103 set_hot_set(hot_set); | |
| 104 | |
| 105 BorderImageSet pushed_set = { | |
| 106 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_TOP_LEFT).ToImageSkia(), | |
| 107 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_TOP).ToImageSkia(), | |
| 108 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_TOP_RIGHT).ToImageSkia(), | |
| 109 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_LEFT).ToImageSkia(), | |
| 110 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_CENTER).ToImageSkia(), | |
| 111 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_RIGHT).ToImageSkia(), | |
| 112 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_BOTTOM_LEFT).ToImageSkia(), | |
| 113 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_BOTTOM).ToImageSkia(), | |
| 114 rb.GetImageNamed(IDR_TEXTBUTTON_PRESSED_BOTTOM_RIGHT).ToImageSkia(), | |
| 115 }; | |
| 116 set_pushed_set(pushed_set); | |
| 117 } | 91 } |
| 118 | 92 |
| 119 TextButtonBorder::~TextButtonBorder() { | 93 TextButtonBorder::~TextButtonBorder() { |
| 120 } | 94 } |
| 121 | 95 |
| 122 | 96 |
| 123 //////////////////////////////////////////////////////////////////////////////// | 97 //////////////////////////////////////////////////////////////////////////////// |
| 124 // | 98 // |
| 125 // TextButtonBorder - painting | 99 // TextButtonBorder - painting |
| 126 // | 100 // |
| 127 //////////////////////////////////////////////////////////////////////////////// | 101 //////////////////////////////////////////////////////////////////////////////// |
| 128 void TextButtonBorder::Paint(const View& view, gfx::Canvas* canvas) const { | 102 void TextButtonBorder::Paint(const View& view, gfx::Canvas* canvas) const { |
|
Peter Kasting
2012/10/25 23:56:38
This now looks a lot like the label button paint f
msw
2012/10/27 07:40:57
Yes, I hope to merge them in a followup.
| |
| 129 const TextButton* button = static_cast<const TextButton*>(&view); | 103 const TextButton* button = static_cast<const TextButton*>(&view); |
| 130 int state = button->state(); | 104 int state = button->state(); |
| 131 | 105 |
| 132 const BorderImageSet* set = &normal_set_; | 106 const BorderImages* set = &normal_set_; |
| 133 if (button->show_multiple_icon_states() && | 107 if (button->show_multiple_icon_states() && |
| 134 ((state == TextButton::BS_HOT) || (state == TextButton::BS_PUSHED))) | 108 ((state == TextButton::BS_HOT) || (state == TextButton::BS_PUSHED))) |
| 135 set = (state == TextButton::BS_HOT) ? &hot_set_ : &pushed_set_; | 109 set = (state == TextButton::BS_HOT) ? &hot_set_ : &pushed_set_; |
| 136 if (set->top_left) { | 110 if (!set->top_left.isNull()) { |
| 137 if (button->GetAnimation()->is_animating()) { | 111 if (button->GetAnimation()->is_animating()) { |
| 138 // TODO(pkasting): Really this should crossfade between states so it could | 112 // TODO(pkasting): Really this should crossfade between states so it could |
| 139 // handle the case of having a non-NULL |normal_set_|. | 113 // handle the case of having a non-NULL |normal_set_|. |
| 140 canvas->SaveLayerAlpha(static_cast<uint8>( | 114 canvas->SaveLayerAlpha(static_cast<uint8>( |
| 141 button->GetAnimation()->CurrentValueBetween(0, 255))); | 115 button->GetAnimation()->CurrentValueBetween(0, 255))); |
| 142 Paint(view, canvas, *set); | 116 set->Paint(view.GetLocalBounds(), canvas); |
| 143 canvas->Restore(); | 117 canvas->Restore(); |
| 144 } else { | 118 } else { |
| 145 Paint(view, canvas, *set); | 119 set->Paint(view.GetLocalBounds(), canvas); |
| 146 } | 120 } |
| 147 } | 121 } |
| 148 } | 122 } |
| 149 | 123 |
| 150 void TextButtonBorder::Paint(const View& view, | |
| 151 gfx::Canvas* canvas, | |
| 152 const BorderImageSet& set) const { | |
| 153 DCHECK(set.top_left); | |
| 154 int width = view.bounds().width(); | |
| 155 int height = view.bounds().height(); | |
| 156 int tl_width = set.top_left->width(); | |
| 157 int tl_height = set.top_left->height(); | |
| 158 int t_height = set.top->height(); | |
| 159 int tr_height = set.top_right->height(); | |
| 160 int l_width = set.left->width(); | |
| 161 int r_width = set.right->width(); | |
| 162 int bl_width = set.bottom_left->width(); | |
| 163 int bl_height = set.bottom_left->height(); | |
| 164 int b_height = set.bottom->height(); | |
| 165 int br_width = set.bottom_right->width(); | |
| 166 int br_height = set.bottom_right->height(); | |
| 167 | |
| 168 canvas->DrawImageInt(*set.top_left, 0, 0); | |
| 169 canvas->DrawImageInt(*set.top, 0, 0, set.top->width(), t_height, tl_width, 0, | |
| 170 width - tl_width - set.top_right->width(), t_height, false); | |
| 171 canvas->DrawImageInt(*set.top_right, width - set.top_right->width(), 0); | |
| 172 canvas->DrawImageInt(*set.left, 0, 0, l_width, set.left->height(), 0, | |
| 173 tl_height, tl_width, height - tl_height - bl_height, false); | |
| 174 canvas->DrawImageInt(*set.center, 0, 0, set.center->width(), | |
| 175 set.center->height(), l_width, t_height, width - l_width - r_width, | |
| 176 height - t_height - b_height, false); | |
| 177 canvas->DrawImageInt(*set.right, 0, 0, r_width, set.right->height(), | |
| 178 width - r_width, tr_height, r_width, | |
| 179 height - tr_height - br_height, false); | |
| 180 canvas->DrawImageInt(*set.bottom_left, 0, height - bl_height); | |
| 181 canvas->DrawImageInt(*set.bottom, 0, 0, set.bottom->width(), b_height, | |
| 182 bl_width, height - b_height, | |
| 183 width - bl_width - br_width, b_height, false); | |
| 184 canvas->DrawImageInt(*set.bottom_right, width - br_width, | |
| 185 height - br_height); | |
| 186 } | |
| 187 | |
| 188 void TextButtonBorder::GetInsets(gfx::Insets* insets) const { | 124 void TextButtonBorder::GetInsets(gfx::Insets* insets) const { |
| 189 insets->Set(vertical_padding_, kPreferredPaddingHorizontal, | 125 insets->Set(vertical_padding_, kPreferredPaddingHorizontal, |
| 190 vertical_padding_, kPreferredPaddingHorizontal); | 126 vertical_padding_, kPreferredPaddingHorizontal); |
| 191 } | 127 } |
| 192 | 128 |
| 193 //////////////////////////////////////////////////////////////////////////////// | 129 //////////////////////////////////////////////////////////////////////////////// |
| 194 // | 130 // |
| 195 // TextButtonNativeThemeBorder | 131 // TextButtonNativeThemeBorder |
| 196 // | 132 // |
| 197 //////////////////////////////////////////////////////////////////////////////// | 133 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 // Windows may paint a dotted focus rect in | 762 // Windows may paint a dotted focus rect in |
| 827 // NativeTextButton::OnPaintFocusBorder. To avoid getting two focus | 763 // NativeTextButton::OnPaintFocusBorder. To avoid getting two focus |
| 828 // indications (A dotted rect and a highlighted border) only set is_focused on | 764 // indications (A dotted rect and a highlighted border) only set is_focused on |
| 829 // non windows platforms. | 765 // non windows platforms. |
| 830 params->button.is_focused = HasFocus() && | 766 params->button.is_focused = HasFocus() && |
| 831 (focusable() || IsAccessibilityFocusable()); | 767 (focusable() || IsAccessibilityFocusable()); |
| 832 #endif | 768 #endif |
| 833 } | 769 } |
| 834 | 770 |
| 835 } // namespace views | 771 } // namespace views |
| OLD | NEW |