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
3 // found in the LICENSE file.
5 #ifndef UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_
6 #define UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_
10 #include "base/compiler_specific.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string16.h"
13 #include "third_party/skia/include/core/SkColor.h"
14 #include "ui/gfx/font.h"
15 #include "ui/gfx/image/image_skia.h"
16 #include "ui/views/border.h"
17 #include "ui/views/controls/button/custom_button.h"
18 #include "ui/views/native_theme_delegate.h"
19 #include "ui/views/painter.h"
23 ////////////////////////////////////////////////////////////////////////////////
27 // An abstract Border subclass for TextButtons that allows configurable insets
30 ////////////////////////////////////////////////////////////////////////////////
31 class VIEWS_EXPORT TextButtonBorder : public Border {
34 virtual ~TextButtonBorder();
36 void SetInsets(const gfx::Insets& insets);
39 virtual gfx::Insets GetInsets() const OVERRIDE;
43 virtual TextButtonBorder* AsTextButtonBorder() OVERRIDE;
44 virtual const TextButtonBorder* AsTextButtonBorder() const OVERRIDE;
48 DISALLOW_COPY_AND_ASSIGN(TextButtonBorder);
51 ////////////////////////////////////////////////////////////////////////////////
53 // TextButtonDefaultBorder
55 // A Border subclass that paints a TextButton's background layer -
56 // basically the button frame in the hot/pushed states.
58 // Note that this type of button is not focusable by default and will not be
59 // part of the focus chain. Call set_focusable(true) to make it part of the
62 ////////////////////////////////////////////////////////////////////////////////
63 class VIEWS_EXPORT TextButtonDefaultBorder : public TextButtonBorder {
65 TextButtonDefaultBorder();
66 virtual ~TextButtonDefaultBorder();
68 // TextButtonDefaultBorder takes and retains ownership of these |painter|s.
69 void set_normal_painter(Painter* painter) { normal_painter_.reset(painter); }
70 void set_hot_painter(Painter* painter) { hot_painter_.reset(painter); }
71 void set_pushed_painter(Painter* painter) { pushed_painter_.reset(painter); }
74 // Implementation of Border:
75 virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
77 scoped_ptr<Painter> normal_painter_;
78 scoped_ptr<Painter> hot_painter_;
79 scoped_ptr<Painter> pushed_painter_;
81 int vertical_padding_;
83 DISALLOW_COPY_AND_ASSIGN(TextButtonDefaultBorder);
87 ////////////////////////////////////////////////////////////////////////////////
89 // TextButtonNativeThemeBorder
91 // A Border subclass that paints a TextButton's background layer using the
92 // platform's native theme look. This handles normal/disabled/hot/pressed
93 // states, with possible animation between states.
95 ////////////////////////////////////////////////////////////////////////////////
96 class VIEWS_EXPORT TextButtonNativeThemeBorder : public TextButtonBorder {
98 explicit TextButtonNativeThemeBorder(NativeThemeDelegate* delegate);
99 virtual ~TextButtonNativeThemeBorder();
101 // Implementation of Border:
102 virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
105 // The delegate the controls the appearance of this border.
106 NativeThemeDelegate* delegate_;
108 DISALLOW_COPY_AND_ASSIGN(TextButtonNativeThemeBorder);
112 ////////////////////////////////////////////////////////////////////////////////
116 // A base class for different types of buttons, like push buttons, radio
117 // buttons, and checkboxes, that do not depend on native components for
118 // look and feel. TextButton reserves space for the largest string
119 // passed to SetText. To reset the cached max size invoke ClearMaxTextSize.
121 ////////////////////////////////////////////////////////////////////////////////
122 class VIEWS_EXPORT TextButtonBase : public CustomButton,
123 public NativeThemeDelegate {
125 // The menu button's class name.
126 static const char kViewClassName[];
128 virtual ~TextButtonBase();
130 // Call SetText once per string in your set of possible values at button
131 // creation time, so that it can contain the largest of them and avoid
132 // resizing the button when the text changes.
133 virtual void SetText(const string16& text);
134 const string16& text() const { return text_; }
142 void set_alignment(TextAlignment alignment) { alignment_ = alignment; }
144 const gfx::Animation* GetAnimation() const;
146 void SetIsDefault(bool is_default);
147 bool is_default() const { return is_default_; }
149 // Set whether the button text can wrap on multiple lines.
151 void SetMultiLine(bool multi_line);
153 // Return whether the button text can wrap on multiple lines.
154 bool multi_line() const { return multi_line_; }
156 // TextButton remembers the maximum display size of the text passed to
157 // SetText. This method resets the cached maximum display size to the
159 void ClearMaxTextSize();
161 void set_min_width(int min_width) { min_width_ = min_width; }
162 void set_min_height(int min_height) { min_height_ = min_height; }
163 void set_max_width(int max_width) { max_width_ = max_width; }
164 void SetFont(const gfx::Font& font);
165 // Return the font used by this button.
166 gfx::Font font() const { return font_; }
168 void SetEnabledColor(SkColor color);
169 void SetDisabledColor(SkColor color);
170 void SetHighlightColor(SkColor color);
171 void SetHoverColor(SkColor color);
173 // Enables a drop shadow underneath the text.
174 void SetTextShadowColors(SkColor active_color, SkColor inactive_color);
176 // Sets the drop shadow's offset from the text.
177 void SetTextShadowOffset(int x, int y);
180 void ClearEmbellishing();
182 // Sets whether or not to show the hot and pushed states for the button icon
183 // (if present) in addition to the normal state. Defaults to true.
184 bool show_multiple_icon_states() const { return show_multiple_icon_states_; }
185 void SetShowMultipleIconStates(bool show_multiple_icon_states);
187 // Paint the button into the specified canvas. If |mode| is |PB_FOR_DRAG|, the
188 // function paints a drag image representation into the canvas.
189 enum PaintButtonMode { PB_NORMAL, PB_FOR_DRAG };
190 virtual void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode);
192 // Overridden from View:
193 virtual gfx::Size GetPreferredSize() OVERRIDE;
194 virtual gfx::Size GetMinimumSize() OVERRIDE;
195 virtual int GetHeightForWidth(int w) OVERRIDE;
196 virtual void OnEnabledChanged() OVERRIDE;
197 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
198 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
199 virtual const char* GetClassName() const OVERRIDE;
200 virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
203 TextButtonBase(ButtonListener* listener, const string16& text);
205 // Called when enabled or disabled state changes, or the colors for those
207 virtual void UpdateColor();
209 // Updates text_size_ and max_text_size_ from the current text/font. This is
210 // invoked when the font or text changes.
211 void UpdateTextSize();
213 // Calculate the size of the text size without setting any of the members.
214 void CalculateTextSize(gfx::Size* text_size, int max_width);
216 void set_color_enabled(SkColor color) { color_enabled_ = color; }
217 void set_color_disabled(SkColor color) { color_disabled_ = color; }
218 void set_color_hover(SkColor color) { color_hover_ = color; }
220 bool use_enabled_color_from_theme() const {
221 return use_enabled_color_from_theme_;
224 bool use_disabled_color_from_theme() const {
225 return use_disabled_color_from_theme_;
228 bool use_hover_color_from_theme() const {
229 return use_hover_color_from_theme_;
232 // Overridden from NativeThemeDelegate:
233 virtual gfx::Rect GetThemePaintRect() const OVERRIDE;
234 virtual ui::NativeTheme::State GetThemeState(
235 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
236 virtual const gfx::Animation* GetThemeAnimation() const OVERRIDE;
237 virtual ui::NativeTheme::State GetBackgroundThemeState(
238 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
239 virtual ui::NativeTheme::State GetForegroundThemeState(
240 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
242 virtual void GetExtraParams(ui::NativeTheme::ExtraParams* params) const;
244 virtual gfx::Rect GetTextBounds() const;
246 int ComputeCanvasStringFlags() const;
248 // Calculate the bounds of the content of this button, including any extra
249 // width needed on top of the text width.
250 gfx::Rect GetContentBounds(int extra_width) const;
252 // The text string that is displayed in the button.
255 // The size of the text string.
256 gfx::Size text_size_;
258 // Track the size of the largest text string seen so far, so that
259 // changing text_ will not resize the button boundary.
260 gfx::Size max_text_size_;
262 // The alignment of the text string within the button.
263 TextAlignment alignment_;
265 // The font used to paint the text.
268 // Flag indicating if a shadow should be drawn behind the text.
269 bool has_text_shadow_;
270 // Optional shadow text colors for active and inactive widget states.
271 SkColor active_text_shadow_color_;
272 SkColor inactive_text_shadow_color_;
273 // Space between the text and its shadow. Defaults to (1,1).
274 gfx::Point text_shadow_offset_;
276 // The dimensions of the button will be at least these values.
280 // The width of the button will never be larger than this value. A value <= 0
281 // indicates the width is not constrained.
284 // Whether or not to show the hot and pushed icon states.
285 bool show_multiple_icon_states_;
287 // Whether or not the button appears and behaves as the default button in its
291 // Whether the text button should handle its text string as multi-line.
299 SkColor color_enabled_;
300 SkColor color_disabled_;
301 SkColor color_highlight_;
302 SkColor color_hover_;
304 // True if the specified color should be used from the theme.
305 bool use_enabled_color_from_theme_;
306 bool use_disabled_color_from_theme_;
307 bool use_highlight_color_from_theme_;
308 bool use_hover_color_from_theme_;
310 DISALLOW_COPY_AND_ASSIGN(TextButtonBase);
313 ////////////////////////////////////////////////////////////////////////////////
317 // A button which displays text and/or and icon that can be changed in
318 // response to actions. TextButton reserves space for the largest string
319 // passed to SetText. To reset the cached max size invoke ClearMaxTextSize.
321 ////////////////////////////////////////////////////////////////////////////////
322 class VIEWS_EXPORT TextButton : public TextButtonBase {
324 // The button's class name.
325 static const char kViewClassName[];
327 TextButton(ButtonListener* listener, const string16& text);
328 virtual ~TextButton();
330 void set_icon_text_spacing(int icon_text_spacing) {
331 icon_text_spacing_ = icon_text_spacing;
335 virtual void SetIcon(const gfx::ImageSkia& icon);
336 virtual void SetHoverIcon(const gfx::ImageSkia& icon);
337 virtual void SetPushedIcon(const gfx::ImageSkia& icon);
339 bool HasIcon() const { return !icon_.isNull(); }
341 // Meanings are reversed for right-to-left layouts.
345 ICON_CENTERED // Centered is valid only when text is empty.
348 IconPlacement icon_placement() { return icon_placement_; }
349 void set_icon_placement(IconPlacement icon_placement) {
350 // ICON_CENTERED works only when |text_| is empty.
351 DCHECK((icon_placement != ICON_CENTERED) || text_.empty());
352 icon_placement_ = icon_placement;
355 void set_ignore_minimum_size(bool ignore_minimum_size);
357 // Overridden from View:
358 virtual gfx::Size GetPreferredSize() OVERRIDE;
359 virtual const char* GetClassName() const OVERRIDE;
361 // Overridden from TextButtonBase:
362 virtual void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) OVERRIDE;
365 gfx::ImageSkia icon() const { return icon_; }
367 virtual const gfx::ImageSkia& GetImageToPaint() const;
369 // Overridden from NativeThemeDelegate:
370 virtual ui::NativeTheme::Part GetThemePart() const OVERRIDE;
372 // Overridden from TextButtonBase:
373 virtual void GetExtraParams(
374 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
375 virtual gfx::Rect GetTextBounds() const OVERRIDE;
378 // The position of the icon.
379 IconPlacement icon_placement_;
381 // An icon displayed with the text.
382 gfx::ImageSkia icon_;
384 // An optional different version of the icon for hover state.
385 gfx::ImageSkia icon_hover_;
386 bool has_hover_icon_;
388 // An optional different version of the icon for pushed state.
389 gfx::ImageSkia icon_pushed_;
390 bool has_pushed_icon_;
392 // Space between icon and text.
393 int icon_text_spacing_;
395 // True if the button should ignore the minimum size for the platform. Default
396 // is true. Set to false to prevent narrower buttons.
397 bool ignore_minimum_size_;
399 DISALLOW_COPY_AND_ASSIGN(TextButton);
404 #endif // UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_