9d9f86cfd2e8e35fb64472771c90609d08f252f8
[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.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 ////////////////////////////////////////////////////////////////////////////////
24 //
25 // TextButtonBorder
26 //
27 //  An abstract Border subclass for TextButtons that allows configurable insets
28 //  for the button.
29 //
30 ////////////////////////////////////////////////////////////////////////////////
31 class VIEWS_EXPORT TextButtonBorder : public Border {
32  public:
33   TextButtonBorder();
34   virtual ~TextButtonBorder();
35
36   void SetInsets(const gfx::Insets& insets);
37
38   // Border:
39   virtual gfx::Insets GetInsets() const OVERRIDE;
40
41 private:
42   // Border:
43   virtual TextButtonBorder* AsTextButtonBorder() OVERRIDE;
44   virtual const TextButtonBorder* AsTextButtonBorder() const OVERRIDE;
45
46   gfx::Insets insets_;
47
48   DISALLOW_COPY_AND_ASSIGN(TextButtonBorder);
49 };
50
51 ////////////////////////////////////////////////////////////////////////////////
52 //
53 // TextButtonDefaultBorder
54 //
55 //  A Border subclass that paints a TextButton's background layer -
56 //  basically the button frame in the hot/pushed states.
57 //
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
60 // focus chain.
61 //
62 ////////////////////////////////////////////////////////////////////////////////
63 class VIEWS_EXPORT TextButtonDefaultBorder : public TextButtonBorder {
64  public:
65   TextButtonDefaultBorder();
66   virtual ~TextButtonDefaultBorder();
67
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); }
72
73  private:
74   // Implementation of Border:
75   virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
76
77   scoped_ptr<Painter> normal_painter_;
78   scoped_ptr<Painter> hot_painter_;
79   scoped_ptr<Painter> pushed_painter_;
80
81   int vertical_padding_;
82
83   DISALLOW_COPY_AND_ASSIGN(TextButtonDefaultBorder);
84 };
85
86
87 ////////////////////////////////////////////////////////////////////////////////
88 //
89 // TextButtonNativeThemeBorder
90 //
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.
94 //
95 ////////////////////////////////////////////////////////////////////////////////
96 class VIEWS_EXPORT TextButtonNativeThemeBorder : public TextButtonBorder {
97  public:
98   explicit TextButtonNativeThemeBorder(NativeThemeDelegate* delegate);
99   virtual ~TextButtonNativeThemeBorder();
100
101   // Implementation of Border:
102   virtual void Paint(const View& view, gfx::Canvas* canvas) OVERRIDE;
103
104  private:
105   // The delegate the controls the appearance of this border.
106   NativeThemeDelegate* delegate_;
107
108   DISALLOW_COPY_AND_ASSIGN(TextButtonNativeThemeBorder);
109 };
110
111
112 ////////////////////////////////////////////////////////////////////////////////
113 //
114 // TextButtonBase
115 //
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.
120 //
121 ////////////////////////////////////////////////////////////////////////////////
122 class VIEWS_EXPORT TextButtonBase : public CustomButton,
123                                     public NativeThemeDelegate {
124  public:
125   // The menu button's class name.
126   static const char kViewClassName[];
127
128   virtual ~TextButtonBase();
129
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_; }
135
136   enum TextAlignment {
137     ALIGN_LEFT,
138     ALIGN_CENTER,
139     ALIGN_RIGHT
140   };
141
142   void set_alignment(TextAlignment alignment) { alignment_ = alignment; }
143
144   const gfx::Animation* GetAnimation() const;
145
146   void SetIsDefault(bool is_default);
147   bool is_default() const { return is_default_; }
148
149   // Set whether the button text can wrap on multiple lines.
150   // Default is false.
151   void SetMultiLine(bool multi_line);
152
153   // Return whether the button text can wrap on multiple lines.
154   bool multi_line() const { return multi_line_; }
155
156   // TextButton remembers the maximum display size of the text passed to
157   // SetText. This method resets the cached maximum display size to the
158   // current size.
159   void ClearMaxTextSize();
160
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_; }
167
168   void SetEnabledColor(SkColor color);
169   void SetDisabledColor(SkColor color);
170   void SetHighlightColor(SkColor color);
171   void SetHoverColor(SkColor color);
172
173   // Enables a drop shadow underneath the text.
174   void SetTextShadowColors(SkColor active_color, SkColor inactive_color);
175
176   // Sets the drop shadow's offset from the text.
177   void SetTextShadowOffset(int x, int y);
178
179   // Disables shadows.
180   void ClearEmbellishing();
181
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);
186
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);
191
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;
201
202  protected:
203   TextButtonBase(ButtonListener* listener, const string16& text);
204
205   // Called when enabled or disabled state changes, or the colors for those
206   // states change.
207   virtual void UpdateColor();
208
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();
212
213   // Calculate the size of the text size without setting any of the members.
214   void CalculateTextSize(gfx::Size* text_size, int max_width);
215
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; }
219
220   bool use_enabled_color_from_theme() const {
221     return use_enabled_color_from_theme_;
222   }
223
224   bool use_disabled_color_from_theme() const {
225     return use_disabled_color_from_theme_;
226   }
227
228   bool use_hover_color_from_theme() const {
229     return use_hover_color_from_theme_;
230   }
231
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;
241
242   virtual void GetExtraParams(ui::NativeTheme::ExtraParams* params) const;
243
244   virtual gfx::Rect GetTextBounds() const;
245
246   int ComputeCanvasStringFlags() const;
247
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;
251
252   // The text string that is displayed in the button.
253   string16 text_;
254
255   // The size of the text string.
256   gfx::Size text_size_;
257
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_;
261
262   // The alignment of the text string within the button.
263   TextAlignment alignment_;
264
265   // The font used to paint the text.
266   gfx::Font font_;
267
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_;
275
276   // The dimensions of the button will be at least these values.
277   int min_width_;
278   int min_height_;
279
280   // The width of the button will never be larger than this value. A value <= 0
281   // indicates the width is not constrained.
282   int max_width_;
283
284   // Whether or not to show the hot and pushed icon states.
285   bool show_multiple_icon_states_;
286
287   // Whether or not the button appears and behaves as the default button in its
288   // current context.
289   bool is_default_;
290
291   // Whether the text button should handle its text string as multi-line.
292   bool multi_line_;
293
294  private:
295   // Text color.
296   SkColor color_;
297
298   // State colors.
299   SkColor color_enabled_;
300   SkColor color_disabled_;
301   SkColor color_highlight_;
302   SkColor color_hover_;
303
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_;
309
310   DISALLOW_COPY_AND_ASSIGN(TextButtonBase);
311 };
312
313 ////////////////////////////////////////////////////////////////////////////////
314 //
315 // TextButton
316 //
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.
320 //
321 ////////////////////////////////////////////////////////////////////////////////
322 class VIEWS_EXPORT TextButton : public TextButtonBase {
323  public:
324   // The button's class name.
325   static const char kViewClassName[];
326
327   TextButton(ButtonListener* listener, const string16& text);
328   virtual ~TextButton();
329
330   void set_icon_text_spacing(int icon_text_spacing) {
331     icon_text_spacing_ = icon_text_spacing;
332   }
333
334   // Sets the icon.
335   virtual void SetIcon(const gfx::ImageSkia& icon);
336   virtual void SetHoverIcon(const gfx::ImageSkia& icon);
337   virtual void SetPushedIcon(const gfx::ImageSkia& icon);
338
339   bool HasIcon() const { return !icon_.isNull(); }
340
341   // Meanings are reversed for right-to-left layouts.
342   enum IconPlacement {
343     ICON_ON_LEFT,
344     ICON_ON_RIGHT,
345     ICON_CENTERED  // Centered is valid only when text is empty.
346   };
347
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;
353   }
354
355   void set_ignore_minimum_size(bool ignore_minimum_size);
356
357   // Overridden from View:
358   virtual gfx::Size GetPreferredSize() OVERRIDE;
359   virtual const char* GetClassName() const OVERRIDE;
360
361   // Overridden from TextButtonBase:
362   virtual void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) OVERRIDE;
363
364  protected:
365   gfx::ImageSkia icon() const { return icon_; }
366
367   virtual const gfx::ImageSkia& GetImageToPaint() const;
368
369   // Overridden from NativeThemeDelegate:
370   virtual ui::NativeTheme::Part GetThemePart() const OVERRIDE;
371
372   // Overridden from TextButtonBase:
373   virtual void GetExtraParams(
374       ui::NativeTheme::ExtraParams* params) const OVERRIDE;
375   virtual gfx::Rect GetTextBounds() const OVERRIDE;
376
377  private:
378   // The position of the icon.
379   IconPlacement icon_placement_;
380
381   // An icon displayed with the text.
382   gfx::ImageSkia icon_;
383
384   // An optional different version of the icon for hover state.
385   gfx::ImageSkia icon_hover_;
386   bool has_hover_icon_;
387
388   // An optional different version of the icon for pushed state.
389   gfx::ImageSkia icon_pushed_;
390   bool has_pushed_icon_;
391
392   // Space between icon and text.
393   int icon_text_spacing_;
394
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_;
398
399   DISALLOW_COPY_AND_ASSIGN(TextButton);
400 };
401
402 }  // namespace views
403
404 #endif  // UI_VIEWS_CONTROLS_BUTTON_TEXT_BUTTON_H_