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_list.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 // A Border subclass for TextButtons that allows configurable insets for the
25 class VIEWS_EXPORT TextButtonBorder
: public Border
{
28 virtual ~TextButtonBorder();
30 void SetInsets(const gfx::Insets
& insets
);
33 virtual void Paint(const View
& view
, gfx::Canvas
* canvas
) OVERRIDE
;
34 virtual gfx::Insets
GetInsets() const OVERRIDE
;
35 virtual gfx::Size
GetMinimumSize() const OVERRIDE
;
40 DISALLOW_COPY_AND_ASSIGN(TextButtonBorder
);
44 // A Border subclass that paints a TextButton's background layer -- basically
45 // the button frame in the hot/pushed states.
47 // Note that this type of button is not focusable by default and will not be
48 // part of the focus chain. Call SetFocusable(true) to make it part of the
50 class VIEWS_EXPORT TextButtonDefaultBorder
: public TextButtonBorder
{
52 TextButtonDefaultBorder();
53 virtual ~TextButtonDefaultBorder();
55 // TextButtonDefaultBorder takes and retains ownership of these |painter|s.
56 void set_normal_painter(Painter
* painter
) { normal_painter_
.reset(painter
); }
57 void set_hot_painter(Painter
* painter
) { hot_painter_
.reset(painter
); }
58 void set_pushed_painter(Painter
* painter
) { pushed_painter_
.reset(painter
); }
62 virtual void Paint(const View
& view
, gfx::Canvas
* canvas
) OVERRIDE
;
63 virtual gfx::Size
GetMinimumSize() const OVERRIDE
;
65 scoped_ptr
<Painter
> normal_painter_
;
66 scoped_ptr
<Painter
> hot_painter_
;
67 scoped_ptr
<Painter
> pushed_painter_
;
69 int vertical_padding_
;
71 DISALLOW_COPY_AND_ASSIGN(TextButtonDefaultBorder
);
75 // A Border subclass that paints a TextButton's background layer using the
76 // platform's native theme look. This handles normal/disabled/hot/pressed
77 // states, with possible animation between states.
78 class VIEWS_EXPORT TextButtonNativeThemeBorder
: public TextButtonBorder
{
80 explicit TextButtonNativeThemeBorder(NativeThemeDelegate
* delegate
);
81 virtual ~TextButtonNativeThemeBorder();
84 virtual void Paint(const View
& view
, gfx::Canvas
* canvas
) OVERRIDE
;
85 // We don't override GetMinimumSize(), since there's no easy way to calculate
86 // the minimum size required by the various theme components.
89 // The delegate the controls the appearance of this border.
90 NativeThemeDelegate
* delegate_
;
92 DISALLOW_COPY_AND_ASSIGN(TextButtonNativeThemeBorder
);
96 // A base class for different types of buttons, like push buttons, radio
97 // buttons, and checkboxes, that do not depend on native components for look and
98 // feel. TextButton reserves space for the largest string passed to SetText. To
99 // reset the cached max size invoke ClearMaxTextSize.
100 class VIEWS_EXPORT TextButtonBase
: public CustomButton
,
101 public NativeThemeDelegate
{
103 // The menu button's class name.
104 static const char kViewClassName
[];
106 virtual ~TextButtonBase();
108 // Call SetText once per string in your set of possible values at button
109 // creation time, so that it can contain the largest of them and avoid
110 // resizing the button when the text changes.
111 virtual void SetText(const base::string16
& text
);
112 const base::string16
& text() const { return text_
; }
120 void set_alignment(TextAlignment alignment
) { alignment_
= alignment
; }
122 const gfx::Animation
* GetAnimation() const;
124 void SetIsDefault(bool is_default
);
125 bool is_default() const { return is_default_
; }
127 // Set whether the button text can wrap on multiple lines.
129 void SetMultiLine(bool multi_line
);
131 // Return whether the button text can wrap on multiple lines.
132 bool multi_line() const { return multi_line_
; }
134 // TextButton remembers the maximum display size of the text passed to
135 // SetText. This method resets the cached maximum display size to the
137 void ClearMaxTextSize();
139 void set_min_width(int min_width
) { min_width_
= min_width
; }
140 void set_min_height(int min_height
) { min_height_
= min_height
; }
141 void set_max_width(int max_width
) { max_width_
= max_width
; }
142 const gfx::FontList
& font_list() const { return font_list_
; }
143 void SetFontList(const gfx::FontList
& font_list
);
145 void SetEnabledColor(SkColor color
);
146 void SetDisabledColor(SkColor color
);
147 void SetHighlightColor(SkColor color
);
148 void SetHoverColor(SkColor color
);
150 // Sets whether or not to show the hot and pushed states for the button icon
151 // (if present) in addition to the normal state. Defaults to true.
152 bool show_multiple_icon_states() const { return show_multiple_icon_states_
; }
153 void SetShowMultipleIconStates(bool show_multiple_icon_states
);
155 void SetFocusPainter(scoped_ptr
<Painter
> focus_painter
);
156 Painter
* focus_painter() { return focus_painter_
.get(); }
158 // Paint the button into the specified canvas. If |mode| is |PB_FOR_DRAG|, the
159 // function paints a drag image representation into the canvas.
160 enum PaintButtonMode
{ PB_NORMAL
, PB_FOR_DRAG
};
161 virtual void PaintButton(gfx::Canvas
* canvas
, PaintButtonMode mode
);
163 // Overridden from View:
164 virtual gfx::Size
GetPreferredSize() const OVERRIDE
;
165 virtual gfx::Size
GetMinimumSize() const OVERRIDE
;
166 virtual int GetHeightForWidth(int w
) const OVERRIDE
;
167 virtual void OnEnabledChanged() OVERRIDE
;
168 virtual void OnPaint(gfx::Canvas
* canvas
) OVERRIDE
;
169 virtual void OnBoundsChanged(const gfx::Rect
& previous_bounds
) OVERRIDE
;
170 virtual const char* GetClassName() const OVERRIDE
;
171 virtual void OnNativeThemeChanged(const ui::NativeTheme
* theme
) OVERRIDE
;
174 TextButtonBase(ButtonListener
* listener
, const base::string16
& text
);
176 // Called when enabled or disabled state changes, or the colors for those
178 virtual void UpdateColor();
180 // Updates text_size_ and max_text_size_ from the current text/font. This is
181 // invoked when the font list or text changes.
182 void UpdateTextSize();
184 // Calculate the size of the text size without setting any of the members.
185 void CalculateTextSize(gfx::Size
* text_size
, int max_width
) const;
187 // Paint the button's text into the specified canvas. If |mode| is
188 // |PB_FOR_DRAG|, the function paints a drag image representation. Derived
189 // can override this function to change only the text rendering.
190 virtual void OnPaintText(gfx::Canvas
* canvas
, PaintButtonMode mode
);
192 void set_color_enabled(SkColor color
) { color_enabled_
= color
; }
193 void set_color_disabled(SkColor color
) { color_disabled_
= color
; }
194 void set_color_hover(SkColor color
) { color_hover_
= color
; }
196 bool use_enabled_color_from_theme() const {
197 return use_enabled_color_from_theme_
;
200 bool use_disabled_color_from_theme() const {
201 return use_disabled_color_from_theme_
;
204 bool use_hover_color_from_theme() const {
205 return use_hover_color_from_theme_
;
208 // Overridden from NativeThemeDelegate:
209 virtual gfx::Rect
GetThemePaintRect() const OVERRIDE
;
210 virtual ui::NativeTheme::State
GetThemeState(
211 ui::NativeTheme::ExtraParams
* params
) const OVERRIDE
;
212 virtual const gfx::Animation
* GetThemeAnimation() const OVERRIDE
;
213 virtual ui::NativeTheme::State
GetBackgroundThemeState(
214 ui::NativeTheme::ExtraParams
* params
) const OVERRIDE
;
215 virtual ui::NativeTheme::State
GetForegroundThemeState(
216 ui::NativeTheme::ExtraParams
* params
) const OVERRIDE
;
218 // Overridden from View:
219 virtual void OnFocus() OVERRIDE
;
220 virtual void OnBlur() OVERRIDE
;
222 virtual void GetExtraParams(ui::NativeTheme::ExtraParams
* params
) const;
224 virtual gfx::Rect
GetTextBounds() const;
226 int ComputeCanvasStringFlags() const;
228 // Calculate the bounds of the content of this button, including any extra
229 // width needed on top of the text width.
230 gfx::Rect
GetContentBounds(int extra_width
) const;
232 // The text string that is displayed in the button.
233 base::string16 text_
;
235 // The size of the text string.
236 mutable gfx::Size text_size_
;
238 // Track the size of the largest text string seen so far, so that
239 // changing text_ will not resize the button boundary.
240 gfx::Size max_text_size_
;
242 // The alignment of the text string within the button.
243 TextAlignment alignment_
;
245 // The font list used to paint the text.
246 gfx::FontList font_list_
;
248 // The dimensions of the button will be at least these values.
252 // The width of the button will never be larger than this value. A value <= 0
253 // indicates the width is not constrained.
256 // Whether or not to show the hot and pushed icon states.
257 bool show_multiple_icon_states_
;
259 // Whether or not the button appears and behaves as the default button in its
263 // Whether the text button should handle its text string as multi-line.
271 SkColor color_enabled_
;
272 SkColor color_disabled_
;
273 SkColor color_highlight_
;
274 SkColor color_hover_
;
276 // True if the specified color should be used from the theme.
277 bool use_enabled_color_from_theme_
;
278 bool use_disabled_color_from_theme_
;
279 bool use_highlight_color_from_theme_
;
280 bool use_hover_color_from_theme_
;
282 scoped_ptr
<Painter
> focus_painter_
;
284 DISALLOW_COPY_AND_ASSIGN(TextButtonBase
);
288 // A button which displays text and/or and icon that can be changed in response
289 // to actions. TextButton reserves space for the largest string passed to
290 // SetText. To reset the cached max size invoke ClearMaxTextSize.
291 class VIEWS_EXPORT TextButton
: public TextButtonBase
{
293 // The button's class name.
294 static const char kViewClassName
[];
296 TextButton(ButtonListener
* listener
, const base::string16
& text
);
297 virtual ~TextButton();
299 void set_icon_text_spacing(int icon_text_spacing
) {
300 icon_text_spacing_
= icon_text_spacing
;
304 virtual void SetIcon(const gfx::ImageSkia
& icon
);
305 virtual void SetHoverIcon(const gfx::ImageSkia
& icon
);
306 virtual void SetPushedIcon(const gfx::ImageSkia
& icon
);
308 bool HasIcon() const { return !icon_
.isNull(); }
310 // Meanings are reversed for right-to-left layouts.
314 ICON_CENTERED
// Centered is valid only when text is empty.
317 IconPlacement
icon_placement() { return icon_placement_
; }
318 void set_icon_placement(IconPlacement icon_placement
) {
319 // ICON_CENTERED works only when |text_| is empty.
320 DCHECK((icon_placement
!= ICON_CENTERED
) || text_
.empty());
321 icon_placement_
= icon_placement
;
324 void set_ignore_minimum_size(bool ignore_minimum_size
);
326 void set_full_justification(bool full_justification
);
328 // Overridden from View:
329 virtual gfx::Size
GetPreferredSize() const OVERRIDE
;
330 virtual const char* GetClassName() const OVERRIDE
;
332 // Overridden from TextButtonBase:
333 virtual void PaintButton(gfx::Canvas
* canvas
, PaintButtonMode mode
) OVERRIDE
;
336 // Paint the button's icon into the specified canvas. If |mode| is
337 // |PB_FOR_DRAG|, the function paints a drag image representation. Derived
338 // can override this function to change only the icon rendering.
339 virtual void OnPaintIcon(gfx::Canvas
* canvas
, PaintButtonMode mode
);
341 gfx::ImageSkia
icon() const { return icon_
; }
343 virtual const gfx::ImageSkia
& GetImageToPaint() const;
345 // Overridden from NativeThemeDelegate:
346 virtual ui::NativeTheme::Part
GetThemePart() const OVERRIDE
;
348 // Overridden from TextButtonBase:
349 virtual void GetExtraParams(
350 ui::NativeTheme::ExtraParams
* params
) const OVERRIDE
;
351 virtual gfx::Rect
GetTextBounds() const OVERRIDE
;
354 // The position of the icon.
355 IconPlacement icon_placement_
;
357 // An icon displayed with the text.
358 gfx::ImageSkia icon_
;
360 // An optional different version of the icon for hover state.
361 gfx::ImageSkia icon_hover_
;
362 bool has_hover_icon_
;
364 // An optional different version of the icon for pushed state.
365 gfx::ImageSkia icon_pushed_
;
366 bool has_pushed_icon_
;
368 // Space between icon and text.
369 int icon_text_spacing_
;
371 // True if the button should ignore the minimum size for the platform. Default
372 // is true. Set to false to prevent narrower buttons.
373 bool ignore_minimum_size_
;
375 // True if the icon and the text are aligned along both the left and right
376 // margins of the button.
377 bool full_justification_
;
379 DISALLOW_COPY_AND_ASSIGN(TextButton
);
384 #endif // UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_