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