Home | History | Annotate | Download | only in controls
      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_LABEL_H_
      6 #define UI_VIEWS_CONTROLS_LABEL_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/compiler_specific.h"
     12 #include "base/gtest_prod_util.h"
     13 #include "base/strings/string16.h"
     14 #include "third_party/skia/include/core/SkColor.h"
     15 #include "ui/gfx/font_list.h"
     16 #include "ui/gfx/shadow_value.h"
     17 #include "ui/gfx/text_constants.h"
     18 #include "ui/views/view.h"
     19 
     20 namespace views {
     21 
     22 // A view subclass that can display a string.
     23 class VIEWS_EXPORT Label : public View {
     24  public:
     25   // Internal class name.
     26   static const char kViewClassName[];
     27 
     28   // The padding for the focus border when rendering focused text.
     29   static const int kFocusBorderPadding;
     30 
     31   Label();
     32   explicit Label(const base::string16& text);
     33   Label(const base::string16& text, const gfx::FontList& font_list);
     34   virtual ~Label();
     35 
     36   // Gets or sets the fonts used by this label.
     37   const gfx::FontList& font_list() const { return font_list_; }
     38   virtual void SetFontList(const gfx::FontList& font_list);
     39 
     40   // Get or set the label text.
     41   const base::string16& text() const { return text_; }
     42   virtual void SetText(const base::string16& text);
     43 
     44   // Enables or disables auto-color-readability (enabled by default).  If this
     45   // is enabled, then calls to set any foreground or background color will
     46   // trigger an automatic mapper that uses color_utils::GetReadableColor() to
     47   // ensure that the foreground colors are readable over the background color.
     48   void SetAutoColorReadabilityEnabled(bool enabled);
     49 
     50   // Sets the color.  This will automatically force the color to be readable
     51   // over the current background color.
     52   virtual void SetEnabledColor(SkColor color);
     53   void SetDisabledColor(SkColor color);
     54 
     55   SkColor enabled_color() const { return actual_enabled_color_; }
     56 
     57   // Sets the background color.  This won't be explicitly drawn, but the label
     58   // will force the text color to be readable over it.
     59   void SetBackgroundColor(SkColor color);
     60   SkColor background_color() const { return background_color_; }
     61 
     62   // Set drop shadows underneath the text.
     63   void set_shadows(const gfx::ShadowValues& shadows) {
     64     shadows_ = shadows;
     65     text_size_valid_ = false;
     66   }
     67   const gfx::ShadowValues& shadows() const { return shadows_; }
     68 
     69   // Sets whether subpixel rendering is used; the default is true, but this
     70   // feature also requires an opaque background color.
     71   void set_subpixel_rendering_enabled(bool subpixel_rendering_enabled) {
     72     subpixel_rendering_enabled_ = subpixel_rendering_enabled;
     73   }
     74 
     75   // Sets the horizontal alignment; the argument value is mirrored in RTL UI.
     76   void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
     77   gfx::HorizontalAlignment GetHorizontalAlignment() const;
     78 
     79   // Sets the directionality mode. The default value is DIRECTIONALITY_FROM_UI,
     80   // which should be suitable for most text originating from UI string assets.
     81   // Most text originating from web content should use DIRECTIONALITY_FROM_TEXT.
     82   void set_directionality_mode(gfx::DirectionalityMode mode) {
     83     directionality_mode_ = mode;
     84   }
     85   gfx::DirectionalityMode directionality_mode() const {
     86     return directionality_mode_;
     87   }
     88 
     89   // Get or set the distance in pixels between baselines of multi-line text.
     90   // Default is 0, indicating the distance between lines should be the standard
     91   // one for the label's text, font list, and platform.
     92   int line_height() const { return line_height_; }
     93   void SetLineHeight(int height);
     94 
     95   // Get or set if the label text can wrap on multiple lines; default is false.
     96   bool is_multi_line() const { return is_multi_line_; }
     97   void SetMultiLine(bool multi_line);
     98 
     99   // Get or set if the label text should be obscured before rendering (e.g.
    100   // should "Password!" display as "*********"); default is false.
    101   bool is_obscured() const { return is_obscured_; }
    102   void SetObscured(bool obscured);
    103 
    104   // Get the text as displayed to the user, respecting the 'obscured' flag.
    105   const base::string16& layout_text() const { return layout_text_; }
    106 
    107   // Sets whether the label text can be split on words.
    108   // Default is false. This only works when is_multi_line is true.
    109   void SetAllowCharacterBreak(bool allow_character_break);
    110 
    111   // Sets the eliding or fading behavior, applied as necessary. The default is
    112   // to elide at the end. Eliding is not well supported for multi-line labels.
    113   void SetElideBehavior(gfx::ElideBehavior elide_behavior);
    114 
    115   // Sets the tooltip text.  Default behavior for a label (single-line) is to
    116   // show the full text if it is wider than its bounds.  Calling this overrides
    117   // the default behavior and lets you set a custom tooltip.  To revert to
    118   // default behavior, call this with an empty string.
    119   void SetTooltipText(const base::string16& tooltip_text);
    120 
    121   // Resizes the label so its width is set to the width of the longest line and
    122   // its height deduced accordingly.
    123   // This is only intended for multi-line labels and is useful when the label's
    124   // text contains several lines separated with \n.
    125   // |max_width| is the maximum width that will be used (longer lines will be
    126   // wrapped).  If 0, no maximum width is enforced.
    127   void SizeToFit(int max_width);
    128 
    129   // Gets/sets the flag to determine whether the label should be collapsed when
    130   // it's hidden (not visible). If this flag is true, the label will return a
    131   // preferred size of (0, 0) when it's not visible.
    132   void set_collapse_when_hidden(bool value) { collapse_when_hidden_ = value; }
    133   bool collapse_when_hidden() const { return collapse_when_hidden_; }
    134 
    135   // View:
    136   virtual gfx::Insets GetInsets() const OVERRIDE;
    137   virtual int GetBaseline() const OVERRIDE;
    138   // Overridden to compute the size required to display this label.
    139   virtual gfx::Size GetPreferredSize() const OVERRIDE;
    140   // Returns the width of an ellipsis if the label is non-empty, or 0 otherwise.
    141   virtual gfx::Size GetMinimumSize() const OVERRIDE;
    142   // Returns the height necessary to display this label with the provided width.
    143   // This method is used to layout multi-line labels. It is equivalent to
    144   // GetPreferredSize().height() if the receiver is not multi-line.
    145   virtual int GetHeightForWidth(int w) const OVERRIDE;
    146   virtual const char* GetClassName() const OVERRIDE;
    147   virtual View* GetTooltipHandlerForPoint(const gfx::Point& point) OVERRIDE;
    148   virtual bool CanProcessEventsWithinSubtree() const OVERRIDE;
    149   virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
    150   // Gets the tooltip text for labels that are wider than their bounds, except
    151   // when the label is multiline, in which case it just returns false (no
    152   // tooltip).  If a custom tooltip has been specified with SetTooltipText()
    153   // it is returned instead.
    154   virtual bool GetTooltipText(const gfx::Point& p,
    155                               base::string16* tooltip) const OVERRIDE;
    156 
    157  protected:
    158   // Called by Paint to paint the text.  Override this to change how
    159   // text is painted.
    160   virtual void PaintText(gfx::Canvas* canvas,
    161                          const base::string16& text,
    162                          const gfx::Rect& text_bounds,
    163                          int flags);
    164 
    165   virtual gfx::Size GetTextSize() const;
    166 
    167   SkColor disabled_color() const { return actual_disabled_color_; }
    168 
    169   // Overridden from View:
    170   // Overridden to dirty our text bounds if we're multi-line.
    171   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
    172   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
    173   virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
    174 
    175  private:
    176   // These tests call CalculateDrawStringParams in order to verify the
    177   // calculations done for drawing text.
    178   FRIEND_TEST_ALL_PREFIXES(LabelTest, DrawSingleLineString);
    179   FRIEND_TEST_ALL_PREFIXES(LabelTest, DrawMultiLineString);
    180   FRIEND_TEST_ALL_PREFIXES(LabelTest, DrawSingleLineStringInRTL);
    181   FRIEND_TEST_ALL_PREFIXES(LabelTest, DrawMultiLineStringInRTL);
    182   FRIEND_TEST_ALL_PREFIXES(LabelTest, DirectionalityFromText);
    183   FRIEND_TEST_ALL_PREFIXES(LabelTest, DisableSubpixelRendering);
    184 
    185   // Sets both |text_| and |layout_text_| to appropriate values, taking
    186   // the label's 'obscured' status into account.
    187   void SetTextInternal(const base::string16& text);
    188 
    189   void Init(const base::string16& text, const gfx::FontList& font_list);
    190 
    191   void RecalculateColors();
    192 
    193   // Returns where the text is drawn, in the receivers coordinate system.
    194   gfx::Rect GetTextBounds() const;
    195 
    196   int ComputeDrawStringFlags() const;
    197 
    198   gfx::Rect GetAvailableRect() const;
    199 
    200   // Returns parameters to be used for the DrawString call.
    201   void CalculateDrawStringParams(base::string16* paint_text,
    202                                  gfx::Rect* text_bounds,
    203                                  int* flags) const;
    204 
    205   // Updates any colors that have not been explicitly set from the theme.
    206   void UpdateColorsFromTheme(const ui::NativeTheme* theme);
    207 
    208   // Resets |cached_heights_| and |cached_heights_cursor_| and mark
    209   // |text_size_valid_| as false.
    210   void ResetCachedSize();
    211 
    212   bool ShouldShowDefaultTooltip() const;
    213 
    214   base::string16 text_;
    215   base::string16 layout_text_;
    216   gfx::FontList font_list_;
    217   SkColor requested_enabled_color_;
    218   SkColor actual_enabled_color_;
    219   SkColor requested_disabled_color_;
    220   SkColor actual_disabled_color_;
    221   SkColor background_color_;
    222 
    223   // Set to true once the corresponding setter is invoked.
    224   bool enabled_color_set_;
    225   bool disabled_color_set_;
    226   bool background_color_set_;
    227 
    228   bool subpixel_rendering_enabled_;
    229   bool auto_color_readability_;
    230   mutable gfx::Size text_size_;
    231   mutable bool text_size_valid_;
    232   int line_height_;
    233   bool is_multi_line_;
    234   bool is_obscured_;
    235   bool allow_character_break_;
    236   gfx::ElideBehavior elide_behavior_;
    237   gfx::HorizontalAlignment horizontal_alignment_;
    238   base::string16 tooltip_text_;
    239   // Whether to collapse the label when it's not visible.
    240   bool collapse_when_hidden_;
    241   // Controls whether the directionality is auto-detected based on first strong
    242   // directionality character or is determined by the application UI's locale.
    243   gfx::DirectionalityMode directionality_mode_;
    244   gfx::ShadowValues shadows_;
    245 
    246   // The cached heights to avoid recalculation in GetHeightForWidth().
    247   mutable std::vector<gfx::Size> cached_heights_;
    248   mutable int cached_heights_cursor_;
    249 
    250   DISALLOW_COPY_AND_ASSIGN(Label);
    251 };
    252 
    253 }  // namespace views
    254 
    255 #endif  // UI_VIEWS_CONTROLS_LABEL_H_
    256