Commit 0d901db5 authored by Dana Fried's avatar Dana Fried Committed by Commit Bot

Allow vertical alignment for multiline text, improve hover card visuals.

Label text was previously middle-aligned even in the multiline case,
despite our text renderer being able to render all vertical alignments.
This caused hover card titles to animate vertically and be cut off
strangely during transitions between tabs with different numbers of
title lines.

This CL adds the ability to support vertical alignment for multiline
labels, and then aligns the title label on the hover card to ALIGN_TOP
so that during transitions from a hover card with one line to one with
two title lines results in the first line of the title staying in place
while the bottom line is revealed during the animation, which is far
more visually pleasing.

Because RenderText does not yet support vertical alignment for single-
line text, DCHECK guards have been added (as they were previously added
to prevent incompatibility between multiline and elision mode) and also
TODO reminders to extend functionality to single-line in the future.

Bug: 984963, 996905
Change-Id: Ibd2ef6a3c8502a272654b673f83893e06ac5fb53
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1764942
Auto-Submit: Dana Fried <dfried@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Commit-Queue: Dana Fried <dfried@chromium.org>
Cr-Commit-Position: refs/heads/master@{#689968}
parent cc0fc8c9
......@@ -557,12 +557,14 @@ void TabHoverCardBubbleView::UpdateCardContent(const Tab* tab) {
}
base::string16 domain;
if (domain_url.SchemeIsFile()) {
title_label_->SetVerticalAlignment(gfx::ALIGN_MIDDLE);
title_label_->SetMultiLine(false);
title_label_->SetElideBehavior(gfx::ELIDE_MIDDLE);
domain = l10n_util::GetStringUTF16(IDS_HOVER_CARD_FILE_URL_SOURCE);
} else {
title_label_->SetElideBehavior(gfx::ELIDE_TAIL);
title_label_->SetMultiLine(true);
title_label_->SetVerticalAlignment(gfx::ALIGN_TOP);
domain = url_formatter::FormatUrl(
domain_url,
url_formatter::kFormatUrlOmitDefaults |
......
......@@ -229,6 +229,8 @@ class GFX_EXPORT RenderText {
return horizontal_alignment_;
}
void SetHorizontalAlignment(HorizontalAlignment alignment);
VerticalAlignment vertical_alignment() const { return vertical_alignment_; }
void SetVerticalAlignment(VerticalAlignment alignment);
const FontList& font_list() const { return font_list_; }
......
......@@ -42,6 +42,7 @@ enum LabelPropertyKey {
kLabelText = 1,
kLabelShadows,
kLabelHorizontalAlignment,
kLabelVerticalAlignment,
kLabelLineHeight,
kLabelObscured,
kLabelAllowCharacterBreak,
......@@ -202,6 +203,22 @@ void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
kPropertyEffectsLayout);
}
gfx::VerticalAlignment Label::GetVerticalAlignment() const {
return full_text_->vertical_alignment();
}
void Label::SetVerticalAlignment(gfx::VerticalAlignment alignment) {
// TODO(crbug.com/996905): remove once single-line vertical alignment is
// supported.
DCHECK(GetMultiLine() || alignment == gfx::ALIGN_MIDDLE);
if (GetVerticalAlignment() == alignment)
return;
full_text_->SetVerticalAlignment(alignment);
// TODO(dfried): consider if this should be kPropertyEffectsPaint instead.
OnPropertyChanged(&full_text_ + kLabelVerticalAlignment,
kPropertyEffectsLayout);
}
int Label::GetLineHeight() const {
return full_text_->min_line_height();
}
......@@ -220,6 +237,9 @@ bool Label::GetMultiLine() const {
void Label::SetMultiLine(bool multi_line) {
DCHECK(!multi_line || (elide_behavior_ == gfx::ELIDE_TAIL ||
elide_behavior_ == gfx::NO_ELIDE));
// TODO(crbug.com/996905): remove once single-line vertical alignment is
// supported.
DCHECK(multi_line || GetVerticalAlignment() == gfx::ALIGN_MIDDLE);
if (this->GetMultiLine() == multi_line)
return;
multi_line_ = multi_line;
......@@ -283,8 +303,8 @@ gfx::ElideBehavior Label::GetElideBehavior() const {
}
void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
DCHECK(!GetMultiLine() || (elide_behavior_ == gfx::ELIDE_TAIL ||
elide_behavior_ == gfx::NO_ELIDE));
DCHECK(!GetMultiLine() || (elide_behavior == gfx::ELIDE_TAIL ||
elide_behavior == gfx::NO_ELIDE));
if (elide_behavior_ == elide_behavior)
return;
elide_behavior_ = elide_behavior;
......@@ -556,6 +576,7 @@ std::unique_ptr<gfx::RenderText> Label::CreateRenderText() const {
auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
render_text->SetHorizontalAlignment(GetHorizontalAlignment());
render_text->SetVerticalAlignment(GetVerticalAlignment());
render_text->SetDirectionalityMode(full_text_->directionality_mode());
render_text->SetElideBehavior(elide_behavior);
render_text->SetObscured(GetObscured());
......@@ -564,8 +585,9 @@ std::unique_ptr<gfx::RenderText> Label::CreateRenderText() const {
render_text->set_shadows(GetShadows());
render_text->SetCursorEnabled(false);
render_text->SetText(GetText());
render_text->SetMultiline(GetMultiLine());
render_text->SetMaxLines(GetMultiLine() ? GetMaxLines() : 0);
const bool multiline = GetMultiLine();
render_text->SetMultiline(multiline);
render_text->SetMaxLines(multiline ? GetMaxLines() : 0);
render_text->SetWordWrapBehavior(full_text_->word_wrap_behavior());
// Setup render text for selection controller.
......@@ -1110,6 +1132,7 @@ ADD_PROPERTY_METADATA(Label, SkColor, SelectionBackgroundColor)
ADD_PROPERTY_METADATA(Label, bool, SubpixelRenderingEnabled)
ADD_PROPERTY_METADATA(Label, gfx::ShadowValues, Shadows)
ADD_PROPERTY_METADATA(Label, gfx::HorizontalAlignment, HorizontalAlignment)
ADD_PROPERTY_METADATA(Label, gfx::VerticalAlignment, VerticalAlignment)
ADD_PROPERTY_METADATA(Label, int, LineHeight)
ADD_PROPERTY_METADATA(Label, bool, MultiLine)
ADD_PROPERTY_METADATA(Label, int, MaxLines)
......
......@@ -129,6 +129,15 @@ class VIEWS_EXPORT Label : public View,
gfx::HorizontalAlignment GetHorizontalAlignment() const;
void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
// Gets/Sets the vertical alignment. Affects how whitespace is distributed
// vertically around the label text, or if the label is not tall enough to
// render all of the text, what gets cut off.
//
// Currently, this must be ALIGN_MIDDLE (default) for non-multiline labels.
// TODO(crbug.com/996905): support single-line vertical alignment.
gfx::VerticalAlignment GetVerticalAlignment() const;
void SetVerticalAlignment(gfx::VerticalAlignment alignment);
// Get or set the distance in pixels between baselines of multi-line text.
// Default is 0, indicating the distance between lines should be the standard
// one for the label's text, font list, and platform.
......
......@@ -242,6 +242,12 @@ DEFINE_ENUM_CONVERTERS(gfx::HorizontalAlignment,
{gfx::HorizontalAlignment::ALIGN_TO_HEAD,
base::ASCIIToUTF16("ALIGN_TO_HEAD")})
DEFINE_ENUM_CONVERTERS(
gfx::VerticalAlignment,
{gfx::VerticalAlignment::ALIGN_TOP, base::ASCIIToUTF16("ALIGN_TOP")},
{gfx::VerticalAlignment::ALIGN_MIDDLE, base::ASCIIToUTF16("ALIGN_MIDDLE")},
{gfx::VerticalAlignment::ALIGN_BOTTOM, base::ASCIIToUTF16("ALIGN_BOTTOM")})
DEFINE_ENUM_CONVERTERS(
gfx::ElideBehavior,
{gfx::ElideBehavior::NO_ELIDE, base::ASCIIToUTF16("NO_ELIDE")},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment