#ifndef UI_VIEWS_CONTROLS_LABEL_H_
#define UI_VIEWS_CONTROLS_LABEL_H_
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "base/gtest_prod_util.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/color/color_id.h"
#include "ui/color/color_variant.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/render_text.h"
#include "ui/gfx/text_constants.h"
#include "ui/menus/simple_menu_model.h"
#include "ui/views/buildflags.h"
#include "ui/views/cascading_property.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/metadata/view_factory.h"
#include "ui/views/selection_controller_delegate.h"
#include "ui/views/style/typography.h"
#include "ui/views/view.h"
#include "ui/views/views_export.h"
#include "ui/views/word_lookup_client.h"
namespace views {
class LabelSelectionTest;
class MenuRunner;
class SelectionController;
VIEWS_EXPORT extern const ui::ClassProperty<CascadingProperty<SkColor>*>* const
kCascadingLabelEnabledColor;
class VIEWS_EXPORT Label : public View,
public ContextMenuController,
public WordLookupClient,
public SelectionControllerDelegate,
public ui::SimpleMenuModel::Delegate {
METADATA_HEADER(Label, View)
public:
enum MenuCommands {
kCopy = 1,
kSelectAll,
kLastCommandId = kSelectAll,
};
struct CustomFont {
const gfx::FontList font_list;
};
explicit Label(std::u16string_view text = {});
Label(std::u16string_view text,
int text_context,
int text_style = style::STYLE_PRIMARY,
gfx::DirectionalityMode directionality_mode =
gfx::DirectionalityMode::DIRECTIONALITY_FROM_TEXT);
Label(std::u16string_view text, const CustomFont& font);
Label(const Label&) = delete;
Label& operator=(const Label&) = delete;
~Label() override;
static const gfx::FontList& GetDefaultFontList();
const gfx::FontList& font_list() const { return full_text_->font_list(); }
virtual void SetFontList(const gfx::FontList& font_list);
std::u16string_view GetText() const;
virtual void SetText(std::u16string_view text);
void AdjustAccessibleName(std::u16string& new_name,
ax::mojom::NameFrom& name_from) override;
int GetTextContext() const;
void SetTextContext(int text_context);
int GetTextStyle() const;
void SetTextStyle(int style);
void SetTextStyleRange(int style, const gfx::Range& range);
void ApplyBaselineTextStyle();
bool GetAutoColorReadabilityEnabled() const;
void SetAutoColorReadabilityEnabled(bool enabled);
SkColor GetEnabledColor() const;
virtual void SetEnabledColor(ui::ColorVariant color);
std::optional<ui::ColorVariant> GetRequestedEnabledColor() const;
SkColor GetBackgroundColor() const;
void SetBackgroundColor(ui::ColorVariant color);
SkColor GetSelectionTextColor() const;
void SetSelectionTextColor(SkColor color);
SkColor GetSelectionBackgroundColor() const;
void SetSelectionBackgroundColor(SkColor color);
const gfx::ShadowValues& GetShadows() const;
void SetShadows(const gfx::ShadowValues& shadows);
bool GetSubpixelRenderingEnabled() const;
void SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled);
bool GetSkipSubpixelRenderingOpacityCheck() const;
void SetSkipSubpixelRenderingOpacityCheck(
bool skip_subpixel_rendering_opacity_check);
gfx::HorizontalAlignment GetHorizontalAlignment() const;
void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
gfx::VerticalAlignment GetVerticalAlignment() const;
void SetVerticalAlignment(gfx::VerticalAlignment alignment);
int GetLineHeight() const;
void SetLineHeight(int line_height);
bool GetMultiLine() const;
void SetMultiLine(bool multi_line);
size_t GetMaxLines() const;
void SetMaxLines(size_t max_lines);
void SetMaximumWidthSingleLine(int max_width);
size_t GetRequiredLines() const;
bool GetObscured() const;
void SetObscured(bool obscured);
bool IsDisplayTextClipped() const;
bool IsDisplayTextTruncated() const;
bool GetAllowCharacterBreak() const;
void SetAllowCharacterBreak(bool allow_character_break);
size_t GetTextIndexOfLine(size_t line) const;
void SetTruncateLength(size_t truncate_length);
gfx::ElideBehavior GetElideBehavior() const;
void SetElideBehavior(gfx::ElideBehavior elide_behavior);
void SetDrawStringsFlags(int flags);
int GetDrawStringsFlags() const { return draw_strings_flags_; }
void SetCustomTooltipText(std::u16string_view tooltip_text);
void UpdateTooltipText();
std::u16string_view GetComputedTooltip();
bool GetHandlesTooltips() const;
void SetHandlesTooltips(bool enabled);
int GetFixedWidth() const;
void SizeToFit(int fixed_width);
int GetMaximumWidth() const;
void SetMaximumWidth(int max_width);
bool GetCollapseWhenHidden() const;
void SetCollapseWhenHidden(bool value);
std::u16string_view GetDisplayTextForTesting() const;
base::i18n::TextDirection GetTextDirectionForTesting();
virtual bool IsSelectionSupported() const;
bool GetSelectable() const;
bool SetSelectable(bool selectable);
bool HasSelection() const;
bool HasFullSelection() const;
void SelectAll();
void ClearSelection();
void SelectRange(const gfx::Range& range);
std::vector<gfx::Rect> GetSubstringBounds(const gfx::Range& range);
[[nodiscard]] base::CallbackListSubscription AddTextChangedCallback(
views::PropertyChangedCallback callback);
[[nodiscard]] base::CallbackListSubscription
AddAccessibleTextOffsetsChangedCallback(
views::PropertyChangedCallback callback);
[[nodiscard]] base::CallbackListSubscription AddTextContextChangedCallback(
PropertyChangedCallback callback);
int GetBaseline() const override;
gfx::Size CalculatePreferredSize(
const SizeBounds& available_size) const override;
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
bool GetCanProcessEventsWithinSubtree() const override;
WordLookupClient* GetWordLookupClient() override;
#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
void OnAccessibilityInitializing(ui::AXNodeData* data) override;
#endif
void ExecuteCommand(int command_id, int event_flags) override;
void AddDisplayTextTruncationCallback(
base::RepeatingCallback<void(Label*)> callback);
void AddLabelTooltipTextChangedCallback(
base::RepeatingCallback<void()> callback);
protected:
virtual std::unique_ptr<gfx::RenderText> CreateRenderText() const;
gfx::Rect GetTextBounds() const;
int GetFontListY() const;
void PaintText(gfx::Canvas* canvas);
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
void OnPaint(gfx::Canvas* canvas) override;
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override;
void OnThemeChanged() override;
ui::Cursor GetCursor(const ui::MouseEvent& event) override;
void OnFocus() override;
void OnBlur() override;
bool OnMousePressed(const ui::MouseEvent& event) override;
bool OnMouseDragged(const ui::MouseEvent& event) override;
void OnMouseReleased(const ui::MouseEvent& event) override;
void OnMouseCaptureLost() override;
bool OnKeyPressed(const ui::KeyEvent& event) override;
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
bool CanHandleAccelerators() const override;
private:
FRIEND_TEST_ALL_PREFIXES(LabelTest, ResetRenderTextData);
FRIEND_TEST_ALL_PREFIXES(LabelTest, MultilineSupportedRenderText);
FRIEND_TEST_ALL_PREFIXES(LabelTest, TextChangeWithoutLayout);
FRIEND_TEST_ALL_PREFIXES(LabelTest, EmptyLabel);
FRIEND_TEST_ALL_PREFIXES(LabelTest, FocusBounds);
FRIEND_TEST_ALL_PREFIXES(LabelTest, MultiLineSizingWithElide);
FRIEND_TEST_ALL_PREFIXES(LabelTest, IsDisplayTextTruncated);
FRIEND_TEST_ALL_PREFIXES(LabelTest, ChecksSubpixelRenderingOntoOpaqueSurface);
FRIEND_TEST_ALL_PREFIXES(ViewAXPlatformNodeDelegateWinInnerTextRangeTest,
Label_LTR);
FRIEND_TEST_ALL_PREFIXES(ViewAXPlatformNodeDelegateWinInnerTextRangeTest,
Label_RTL);
friend class LabelSelectionTest;
void ShowContextMenuForViewImpl(
View* source,
const gfx::Point& point,
ui::mojom::MenuSourceType source_type) override;
bool GetWordLookupDataAtPoint(const gfx::Point& point,
gfx::DecoratedText* decorated_word,
gfx::Rect* rect) override;
bool GetWordLookupDataFromSelection(gfx::DecoratedText* decorated_text,
gfx::Rect* rect) override;
gfx::RenderText* GetRenderTextForSelectionController() override;
bool IsReadOnly() const override;
bool SupportsDrag() const override;
bool HasTextBeingDragged() const override;
void SetTextBeingDragged(bool value) override;
int GetViewHeight() const override;
int GetViewWidth() const override;
int GetDragSelectionDelay() const override;
void OnBeforePointerAction() override;
void OnAfterPointerAction(bool text_changed, bool selection_changed) override;
bool PasteSelectionClipboard() override;
void UpdateSelectionClipboard() override;
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) const override;
const gfx::RenderText* GetRenderTextForSelectionController() const;
void Init(std::u16string_view text,
const gfx::FontList& font_list,
gfx::DirectionalityMode directionality_mode);
void MaybeBuildDisplayText() const;
gfx::Size GetTextSize() const;
gfx::Size GetBoundedTextSize(const SizeBounds& available_size) const;
int GetLabelHeightForWidth(int w) const;
SkColor GetForegroundColor(SkColor foreground, SkColor background) const;
void RecalculateColors();
void ApplyTextColors() const;
void UpdateColorsFromTheme();
bool ShouldShowDefaultTooltip() const;
void ClearDisplayText();
std::u16string_view GetSelectedText() const;
void CopyToClipboard();
void BuildContextMenuContents();
void UpdateFullTextElideBehavior();
void OnDisplayTextTruncation();
#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
void MaybeRefreshAccessibleTextOffsets() const;
bool RefreshAccessibleTextOffsetsIfNeeded() const;
mutable std::u16string ax_name_used_to_compute_offsets_;
#endif
int text_context_;
int text_style_;
std::optional<int> line_height_;
std::unique_ptr<gfx::RenderText> full_text_;
mutable std::unique_ptr<gfx::RenderText> display_text_;
mutable gfx::Range stored_selection_range_ = gfx::Range::InvalidRange();
std::optional<ui::ColorVariant> requested_enabled_color_;
std::optional<SkColor> resolved_enabled_color_;
SkColor actual_enabled_color_ = gfx::kPlaceholderColor;
std::optional<ui::ColorVariant> requested_background_color_;
std::optional<SkColor> resolved_background_color_;
SkColor actual_background_color_ = gfx::kPlaceholderColor;
SkColor requested_selection_text_color_ = gfx::kPlaceholderColor;
SkColor actual_selection_text_color_ = gfx::kPlaceholderColor;
SkColor selection_background_color_ = gfx::kPlaceholderColor;
bool selection_text_color_set_ = false;
bool selection_background_color_set_ = false;
gfx::ElideBehavior elide_behavior_ = gfx::ELIDE_TAIL;
bool subpixel_rendering_enabled_ = true;
bool skip_subpixel_rendering_opacity_check_ = false;
bool auto_color_readability_enabled_ = true;
bool multi_line_ = false;
size_t max_lines_ = 0;
std::u16string custom_tooltip_text_;
bool handles_tooltips_ = true;
bool collapse_when_hidden_ = false;
int fixed_width_ = 0;
int max_width_ = 0;
int max_width_single_line_ = 0;
int draw_strings_flags_ = 0;
std::unique_ptr<SelectionController> selection_controller_;
ui::SimpleMenuModel context_menu_contents_;
std::unique_ptr<views::MenuRunner> context_menu_runner_;
std::u16string suppressed_tooltip_text_;
base::RepeatingCallback<void(Label*)>
on_display_text_truncation_changed_callback_;
base::RepeatingCallback<void()> label_tooltip_text_changed_callback_;
};
BEGIN_VIEW_BUILDER(VIEWS_EXPORT, Label, View)
VIEW_BUILDER_PROPERTY(const gfx::FontList&, FontList)
VIEW_BUILDER_PROPERTY(std::u16string, Text)
VIEW_BUILDER_PROPERTY(int, TextStyle)
VIEW_BUILDER_PROPERTY(int, TextContext)
VIEW_BUILDER_PROPERTY(bool, AutoColorReadabilityEnabled)
VIEW_BUILDER_PROPERTY(ui::ColorVariant, EnabledColor)
VIEW_BUILDER_PROPERTY(ui::ColorVariant, BackgroundColor)
VIEW_BUILDER_PROPERTY(SkColor, SelectionTextColor)
VIEW_BUILDER_PROPERTY(SkColor, SelectionBackgroundColor)
VIEW_BUILDER_PROPERTY(const gfx::ShadowValues&, Shadows)
VIEW_BUILDER_PROPERTY(bool, SubpixelRenderingEnabled)
VIEW_BUILDER_PROPERTY(bool, SkipSubpixelRenderingOpacityCheck)
VIEW_BUILDER_PROPERTY(gfx::HorizontalAlignment, HorizontalAlignment)
VIEW_BUILDER_PROPERTY(gfx::VerticalAlignment, VerticalAlignment)
VIEW_BUILDER_PROPERTY(int, LineHeight)
VIEW_BUILDER_PROPERTY(bool, MultiLine)
VIEW_BUILDER_PROPERTY(size_t, MaxLines)
VIEW_BUILDER_PROPERTY(bool, Obscured)
VIEW_BUILDER_PROPERTY(bool, AllowCharacterBreak)
VIEW_BUILDER_PROPERTY(size_t, TruncateLength)
VIEW_BUILDER_PROPERTY(gfx::ElideBehavior, ElideBehavior)
VIEW_BUILDER_PROPERTY(std::u16string, TooltipText)
VIEW_BUILDER_PROPERTY(bool, HandlesTooltips)
VIEW_BUILDER_PROPERTY(int, MaximumWidth)
VIEW_BUILDER_PROPERTY(int, MaximumWidthSingleLine)
VIEW_BUILDER_PROPERTY(bool, CollapseWhenHidden)
VIEW_BUILDER_PROPERTY(bool, Selectable)
VIEW_BUILDER_METHOD(SizeToFit, int)
END_VIEW_BUILDER
}
DEFINE_VIEW_BUILDER(VIEWS_EXPORT, Label)
#endif