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;
39 virtual TextButtonBorder* AsTextButtonBorder() OVERRIDE;
40 virtual const TextButtonBorder* AsTextButtonBorder() const OVERRIDE;
44 DISALLOW_COPY_AND_ASSIGN(TextButtonBorder);
48 // A Border subclass that paints a TextButton's background layer -- basically
49 // the button frame in the hot/pushed states.
51 // Note that this type of button is not focusable by default and will not be
52 // part of the focus chain. Call SetFocusable(true) to make it part of the
54 class VIEWS_EXPORT TextButtonDefaultBorder : public TextButtonBorder {
56 TextButtonDefaultBorder();
57 virtual ~TextButtonDefaultBorder();
59 // TextButtonDefaultBorder takes and retains ownership of these |painter|s.
60 void set_normal_painter(Painter* painter) { normal_painter_.reset(painter); }
61 void set_hot_painter(Painter* painter) { hot_painter_.reset(painter); }
62 void set_pushed_painter(Painter* painter) { pushed_painter_.reset(painter); }
66 virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
67 virtual gfx::Size GetMinimumSize() const OVERRIDE;
69 scoped_ptr<Painter> normal_painter_;
70 scoped_ptr<Painter> hot_painter_;
71 scoped_ptr<Painter> pushed_painter_;
73 int vertical_padding_;
75 DISALLOW_COPY_AND_ASSIGN(TextButtonDefaultBorder);
79 // A Border subclass that paints a TextButton's background layer using the
80 // platform's native theme look. This handles normal/disabled/hot/pressed
81 // states, with possible animation between states.
82 class VIEWS_EXPORT TextButtonNativeThemeBorder : public TextButtonBorder {
84 explicit TextButtonNativeThemeBorder(NativeThemeDelegate* delegate);
85 virtual ~TextButtonNativeThemeBorder();
88 virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
89 // We don't override GetMinimumSize(), since there's no easy way to calculate
90 // the minimum size required by the various theme components.
93 // The delegate the controls the appearance of this border.
94 NativeThemeDelegate* delegate_;
96 DISALLOW_COPY_AND_ASSIGN(TextButtonNativeThemeBorder);
100 // A base class for different types of buttons, like push buttons, radio
101 // buttons, and checkboxes, that do not depend on native components for look and
102 // feel. TextButton reserves space for the largest string passed to SetText. To
103 // reset the cached max size invoke ClearMaxTextSize.
104 class VIEWS_EXPORT TextButtonBase : public CustomButton,
105 public NativeThemeDelegate {
107 // The menu button's class name.
108 static const char kViewClassName[];
110 virtual ~TextButtonBase();
112 // Call SetText once per string in your set of possible values at button
113 // creation time, so that it can contain the largest of them and avoid
114 // resizing the button when the text changes.
115 virtual void SetText(const base::string16& text);
116 const base::string16& text() const { return text_; }
124 void set_alignment(TextAlignment alignment) { alignment_ = alignment; }
126 const gfx::Animation* GetAnimation() const;
128 void SetIsDefault(bool is_default);
129 bool is_default() const { return is_default_; }
131 // Set whether the button text can wrap on multiple lines.
133 void SetMultiLine(bool multi_line);
135 // Return whether the button text can wrap on multiple lines.
136 bool multi_line() const { return multi_line_; }
138 // TextButton remembers the maximum display size of the text passed to
139 // SetText. This method resets the cached maximum display size to the
141 void ClearMaxTextSize();
143 void set_min_width(int min_width) { min_width_ = min_width; }
144 void set_min_height(int min_height) { min_height_ = min_height; }
145 void set_max_width(int max_width) { max_width_ = max_width; }
146 const gfx::FontList& font_list() const { return font_list_; }
147 void SetFontList(const gfx::FontList& font_list);
149 void SetEnabledColor(SkColor color);
150 void SetDisabledColor(SkColor color);
151 void SetHighlightColor(SkColor color);
152 void SetHoverColor(SkColor color);
154 // Enables a drop shadow underneath the text.
155 void SetTextShadowColors(SkColor active_color, SkColor inactive_color);
157 // Sets the drop shadow's offset from the text.
158 void SetTextShadowOffset(int x, int y);
161 void ClearEmbellishing();
163 // Sets whether or not to show the hot and pushed states for the button icon
164 // (if present) in addition to the normal state. Defaults to true.
165 bool show_multiple_icon_states() const { return show_multiple_icon_states_; }
166 void SetShowMultipleIconStates(bool show_multiple_icon_states);
168 void SetFocusPainter(scoped_ptr<Painter> focus_painter);
169 Painter* focus_painter() { return focus_painter_.get(); }
171 // Paint the button into the specified canvas. If |mode| is |PB_FOR_DRAG|, the
172 // function paints a drag image representation into the canvas.
173 enum PaintButtonMode { PB_NORMAL, PB_FOR_DRAG };
174 virtual void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode);
176 // Overridden from View:
177 virtual gfx::Size GetPreferredSize() OVERRIDE;
178 virtual gfx::Size GetMinimumSize() OVERRIDE;
179 virtual int GetHeightForWidth(int w) OVERRIDE;
180 virtual void OnEnabledChanged() OVERRIDE;
181 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
182 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
183 virtual const char* GetClassName() const OVERRIDE;
184 virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
187 TextButtonBase(ButtonListener* listener, const base::string16& text);
189 // Called when enabled or disabled state changes, or the colors for those
191 virtual void UpdateColor();
193 // Updates text_size_ and max_text_size_ from the current text/font. This is
194 // invoked when the font list or text changes.
195 void UpdateTextSize();
197 // Calculate the size of the text size without setting any of the members.
198 void CalculateTextSize(gfx::Size* text_size, int max_width);
200 void set_color_enabled(SkColor color) { color_enabled_ = color; }
201 void set_color_disabled(SkColor color) { color_disabled_ = color; }
202 void set_color_hover(SkColor color) { color_hover_ = color; }
204 bool use_enabled_color_from_theme() const {
205 return use_enabled_color_from_theme_;
208 bool use_disabled_color_from_theme() const {
209 return use_disabled_color_from_theme_;
212 bool use_hover_color_from_theme() const {
213 return use_hover_color_from_theme_;
216 // Overridden from NativeThemeDelegate:
217 virtual gfx::Rect GetThemePaintRect() const OVERRIDE;
218 virtual ui::NativeTheme::State GetThemeState(
219 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
220 virtual const gfx::Animation* GetThemeAnimation() const OVERRIDE;
221 virtual ui::NativeTheme::State GetBackgroundThemeState(
222 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
223 virtual ui::NativeTheme::State GetForegroundThemeState(
224 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
226 // Overridden from View:
227 virtual void OnFocus() OVERRIDE;
228 virtual void OnBlur() OVERRIDE;
230 virtual void GetExtraParams(ui::NativeTheme::ExtraParams* params) const;
232 virtual gfx::Rect GetTextBounds() const;
234 int ComputeCanvasStringFlags() const;
236 // Calculate the bounds of the content of this button, including any extra
237 // width needed on top of the text width.
238 gfx::Rect GetContentBounds(int extra_width) const;
240 // The text string that is displayed in the button.
241 base::string16 text_;
243 // The size of the text string.
244 gfx::Size text_size_;
246 // Track the size of the largest text string seen so far, so that
247 // changing text_ will not resize the button boundary.
248 gfx::Size max_text_size_;
250 // The alignment of the text string within the button.
251 TextAlignment alignment_;
253 // The font list used to paint the text.
254 gfx::FontList font_list_;
256 // Flag indicating if a shadow should be drawn behind the text.
257 bool has_text_shadow_;
258 // Optional shadow text colors for active and inactive widget states.
259 SkColor active_text_shadow_color_;
260 SkColor inactive_text_shadow_color_;
261 // Space between the text and its shadow. Defaults to (1,1).
262 gfx::Point text_shadow_offset_;
264 // The dimensions of the button will be at least these values.
268 // The width of the button will never be larger than this value. A value <= 0
269 // indicates the width is not constrained.
272 // Whether or not to show the hot and pushed icon states.
273 bool show_multiple_icon_states_;
275 // Whether or not the button appears and behaves as the default button in its
279 // Whether the text button should handle its text string as multi-line.
287 SkColor color_enabled_;
288 SkColor color_disabled_;
289 SkColor color_highlight_;
290 SkColor color_hover_;
292 // True if the specified color should be used from the theme.
293 bool use_enabled_color_from_theme_;
294 bool use_disabled_color_from_theme_;
295 bool use_highlight_color_from_theme_;
296 bool use_hover_color_from_theme_;
298 scoped_ptr<Painter> focus_painter_;
300 DISALLOW_COPY_AND_ASSIGN(TextButtonBase);
304 // A button which displays text and/or and icon that can be changed in response
305 // to actions. TextButton reserves space for the largest string passed to
306 // SetText. To reset the cached max size invoke ClearMaxTextSize.
307 class VIEWS_EXPORT TextButton : public TextButtonBase {
309 // The button's class name.
310 static const char kViewClassName[];
312 TextButton(ButtonListener* listener, const base::string16& text);
313 virtual ~TextButton();
315 void set_icon_text_spacing(int icon_text_spacing) {
316 icon_text_spacing_ = icon_text_spacing;
320 virtual void SetIcon(const gfx::ImageSkia& icon);
321 virtual void SetHoverIcon(const gfx::ImageSkia& icon);
322 virtual void SetPushedIcon(const gfx::ImageSkia& icon);
324 bool HasIcon() const { return !icon_.isNull(); }
326 // Meanings are reversed for right-to-left layouts.
330 ICON_CENTERED // Centered is valid only when text is empty.
333 IconPlacement icon_placement() { return icon_placement_; }
334 void set_icon_placement(IconPlacement icon_placement) {
335 // ICON_CENTERED works only when |text_| is empty.
336 DCHECK((icon_placement != ICON_CENTERED) || text_.empty());
337 icon_placement_ = icon_placement;
340 void set_ignore_minimum_size(bool ignore_minimum_size);
342 void set_full_justification(bool full_justification);
344 // Overridden from View:
345 virtual gfx::Size GetPreferredSize() OVERRIDE;
346 virtual const char* GetClassName() const OVERRIDE;
348 // Overridden from TextButtonBase:
349 virtual void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) OVERRIDE;
352 gfx::ImageSkia icon() const { return icon_; }
354 virtual const gfx::ImageSkia& GetImageToPaint() const;
356 // Overridden from NativeThemeDelegate:
357 virtual ui::NativeTheme::Part GetThemePart() const OVERRIDE;
359 // Overridden from TextButtonBase:
360 virtual void GetExtraParams(
361 ui::NativeTheme::ExtraParams* params) const OVERRIDE;
362 virtual gfx::Rect GetTextBounds() const OVERRIDE;
365 // The position of the icon.
366 IconPlacement icon_placement_;
368 // An icon displayed with the text.
369 gfx::ImageSkia icon_;
371 // An optional different version of the icon for hover state.
372 gfx::ImageSkia icon_hover_;
373 bool has_hover_icon_;
375 // An optional different version of the icon for pushed state.
376 gfx::ImageSkia icon_pushed_;
377 bool has_pushed_icon_;
379 // Space between icon and text.
380 int icon_text_spacing_;
382 // True if the button should ignore the minimum size for the platform. Default
383 // is true. Set to false to prevent narrower buttons.
384 bool ignore_minimum_size_;
386 // True if the icon and the text are aligned along both the left and right
387 // margins of the button.
388 bool full_justification_;
390 DISALLOW_COPY_AND_ASSIGN(TextButton);
395 #endif // UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_