Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / button / text_button.h
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.
4
5 #ifndef UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_
6 #define UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_
7
8 #include <string>
9
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"
20
21 namespace views {
22
23 // A Border subclass for TextButtons that allows configurable insets for the
24 // button.
25 class VIEWS_EXPORT TextButtonBorder : public Border {
26  public:
27   TextButtonBorder();
28   virtual ~TextButtonBorder();
29
30   void SetInsets(const gfx::Insets& insets);
31
32   // Border:
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;
36
37  private:
38   // Border:
39   virtual TextButtonBorder* AsTextButtonBorder() OVERRIDE;
40   virtual const TextButtonBorder* AsTextButtonBorder() const OVERRIDE;
41
42   gfx::Insets insets_;
43
44   DISALLOW_COPY_AND_ASSIGN(TextButtonBorder);
45 };
46
47
48 // A Border subclass that paints a TextButton's background layer -- basically
49 // the button frame in the hot/pushed states.
50 //
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
53 // focus chain.
54 class VIEWS_EXPORT TextButtonDefaultBorder : public TextButtonBorder {
55  public:
56   TextButtonDefaultBorder();
57   virtual ~TextButtonDefaultBorder();
58
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); }
63
64  private:
65   // TextButtonBorder:
66   virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
67   virtual gfx::Size GetMinimumSize() const OVERRIDE;
68
69   scoped_ptr<Painter> normal_painter_;
70   scoped_ptr<Painter> hot_painter_;
71   scoped_ptr<Painter> pushed_painter_;
72
73   int vertical_padding_;
74
75   DISALLOW_COPY_AND_ASSIGN(TextButtonDefaultBorder);
76 };
77
78
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 {
83  public:
84   explicit TextButtonNativeThemeBorder(NativeThemeDelegate* delegate);
85   virtual ~TextButtonNativeThemeBorder();
86
87   // TextButtonBorder:
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.
91
92  private:
93   // The delegate the controls the appearance of this border.
94   NativeThemeDelegate* delegate_;
95
96   DISALLOW_COPY_AND_ASSIGN(TextButtonNativeThemeBorder);
97 };
98
99
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 {
106  public:
107   // The menu button's class name.
108   static const char kViewClassName[];
109
110   virtual ~TextButtonBase();
111
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_; }
117
118   enum TextAlignment {
119     ALIGN_LEFT,
120     ALIGN_CENTER,
121     ALIGN_RIGHT
122   };
123
124   void set_alignment(TextAlignment alignment) { alignment_ = alignment; }
125
126   const gfx::Animation* GetAnimation() const;
127
128   void SetIsDefault(bool is_default);
129   bool is_default() const { return is_default_; }
130
131   // Set whether the button text can wrap on multiple lines.
132   // Default is false.
133   void SetMultiLine(bool multi_line);
134
135   // Return whether the button text can wrap on multiple lines.
136   bool multi_line() const { return multi_line_; }
137
138   // TextButton remembers the maximum display size of the text passed to
139   // SetText. This method resets the cached maximum display size to the
140   // current size.
141   void ClearMaxTextSize();
142
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);
148
149   void SetEnabledColor(SkColor color);
150   void SetDisabledColor(SkColor color);
151   void SetHighlightColor(SkColor color);
152   void SetHoverColor(SkColor color);
153
154   // Enables a drop shadow underneath the text.
155   void SetTextShadowColors(SkColor active_color, SkColor inactive_color);
156
157   // Sets the drop shadow's offset from the text.
158   void SetTextShadowOffset(int x, int y);
159
160   // Disables shadows.
161   void ClearEmbellishing();
162
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);
167
168   void SetFocusPainter(scoped_ptr<Painter> focus_painter);
169   Painter* focus_painter() { return focus_painter_.get(); }
170
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);
175
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;
185
186  protected:
187   TextButtonBase(ButtonListener* listener, const base::string16& text);
188
189   // Called when enabled or disabled state changes, or the colors for those
190   // states change.
191   virtual void UpdateColor();
192
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();
196
197   // Calculate the size of the text size without setting any of the members.
198   void CalculateTextSize(gfx::Size* text_size, int max_width);
199
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; }
203
204   bool use_enabled_color_from_theme() const {
205     return use_enabled_color_from_theme_;
206   }
207
208   bool use_disabled_color_from_theme() const {
209     return use_disabled_color_from_theme_;
210   }
211
212   bool use_hover_color_from_theme() const {
213     return use_hover_color_from_theme_;
214   }
215
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;
225
226   // Overridden from View:
227   virtual void OnFocus() OVERRIDE;
228   virtual void OnBlur() OVERRIDE;
229
230   virtual void GetExtraParams(ui::NativeTheme::ExtraParams* params) const;
231
232   virtual gfx::Rect GetTextBounds() const;
233
234   int ComputeCanvasStringFlags() const;
235
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;
239
240   // The text string that is displayed in the button.
241   base::string16 text_;
242
243   // The size of the text string.
244   gfx::Size text_size_;
245
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_;
249
250   // The alignment of the text string within the button.
251   TextAlignment alignment_;
252
253   // The font list used to paint the text.
254   gfx::FontList font_list_;
255
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_;
263
264   // The dimensions of the button will be at least these values.
265   int min_width_;
266   int min_height_;
267
268   // The width of the button will never be larger than this value. A value <= 0
269   // indicates the width is not constrained.
270   int max_width_;
271
272   // Whether or not to show the hot and pushed icon states.
273   bool show_multiple_icon_states_;
274
275   // Whether or not the button appears and behaves as the default button in its
276   // current context.
277   bool is_default_;
278
279   // Whether the text button should handle its text string as multi-line.
280   bool multi_line_;
281
282  private:
283   // Text color.
284   SkColor color_;
285
286   // State colors.
287   SkColor color_enabled_;
288   SkColor color_disabled_;
289   SkColor color_highlight_;
290   SkColor color_hover_;
291
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_;
297
298   scoped_ptr<Painter> focus_painter_;
299
300   DISALLOW_COPY_AND_ASSIGN(TextButtonBase);
301 };
302
303
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 {
308  public:
309   // The button's class name.
310   static const char kViewClassName[];
311
312   TextButton(ButtonListener* listener, const base::string16& text);
313   virtual ~TextButton();
314
315   void set_icon_text_spacing(int icon_text_spacing) {
316     icon_text_spacing_ = icon_text_spacing;
317   }
318
319   // Sets the icon.
320   virtual void SetIcon(const gfx::ImageSkia& icon);
321   virtual void SetHoverIcon(const gfx::ImageSkia& icon);
322   virtual void SetPushedIcon(const gfx::ImageSkia& icon);
323
324   bool HasIcon() const { return !icon_.isNull(); }
325
326   // Meanings are reversed for right-to-left layouts.
327   enum IconPlacement {
328     ICON_ON_LEFT,
329     ICON_ON_RIGHT,
330     ICON_CENTERED  // Centered is valid only when text is empty.
331   };
332
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;
338   }
339
340   void set_ignore_minimum_size(bool ignore_minimum_size);
341
342   void set_full_justification(bool full_justification);
343
344   // Overridden from View:
345   virtual gfx::Size GetPreferredSize() OVERRIDE;
346   virtual const char* GetClassName() const OVERRIDE;
347
348   // Overridden from TextButtonBase:
349   virtual void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) OVERRIDE;
350
351  protected:
352   gfx::ImageSkia icon() const { return icon_; }
353
354   virtual const gfx::ImageSkia& GetImageToPaint() const;
355
356   // Overridden from NativeThemeDelegate:
357   virtual ui::NativeTheme::Part GetThemePart() const OVERRIDE;
358
359   // Overridden from TextButtonBase:
360   virtual void GetExtraParams(
361       ui::NativeTheme::ExtraParams* params) const OVERRIDE;
362   virtual gfx::Rect GetTextBounds() const OVERRIDE;
363
364  private:
365   // The position of the icon.
366   IconPlacement icon_placement_;
367
368   // An icon displayed with the text.
369   gfx::ImageSkia icon_;
370
371   // An optional different version of the icon for hover state.
372   gfx::ImageSkia icon_hover_;
373   bool has_hover_icon_;
374
375   // An optional different version of the icon for pushed state.
376   gfx::ImageSkia icon_pushed_;
377   bool has_pushed_icon_;
378
379   // Space between icon and text.
380   int icon_text_spacing_;
381
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_;
385
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_;
389
390   DISALLOW_COPY_AND_ASSIGN(TextButton);
391 };
392
393 }  // namespace views
394
395 #endif  // UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_