Skip to content

Commit

Permalink
Switch Hover Card FadeLabel to use new FadeView
Browse files Browse the repository at this point in the history
Refactored the FadeLabel class so that the hover card title and domain
label will use the new FadeView class instead. In follow up CL's, the
footer will use the FadeView as well so that all labels in the hover
card will cross fade appropriately.

Visually, the hover card title and domains should not look any different
after this change.

Bug: 1424226
Change-Id: I1a9c0318f46b16c11a429bd739613bae839ff011
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4493760
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Reviewed-by: Dana Fried <dfried@chromium.org>
Commit-Queue: Steven Luong <stluong@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1146560}
  • Loading branch information
stluong authored and Chromium LUCI CQ committed May 19, 2023
1 parent 268694f commit 8661ba1
Show file tree
Hide file tree
Showing 9 changed files with 572 additions and 449 deletions.
5 changes: 5 additions & 0 deletions chrome/browser/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -5377,6 +5377,11 @@ static_library("ui") {
"views/tabs/color_picker_view.h",
"views/tabs/compound_tab_container.cc",
"views/tabs/compound_tab_container.h",
"views/tabs/fade_label_view.cc",
"views/tabs/fade_label_view.h",
"views/tabs/fade_view.h",
"views/tabs/filename_elider.cc",
"views/tabs/filename_elider.h",
"views/tabs/glow_hover_controller.cc",
"views/tabs/glow_hover_controller.h",
"views/tabs/new_tab_button.cc",
Expand Down
80 changes: 80 additions & 0 deletions chrome/browser/ui/views/tabs/fade_label_view.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/tabs/fade_label_view.h"

#include "chrome/browser/ui/views/tabs/filename_elider.h"
#include "ui/gfx/canvas.h"

namespace {
template <typename T>
std::unique_ptr<T> CreateLabel(int context) {
return std::make_unique<T>(std::u16string(), context,
views::style::STYLE_PRIMARY);
}
} // namespace

// FadeLabel
// ----------------------------------------------------------

void FadeLabel::SetData(const FadeLabelViewData& data) {
data_ = data;
std::u16string text = data.text;
absl::optional<bool> is_filename = data.is_filename;
SetElideBehavior(is_filename ? gfx::NO_ELIDE : gfx::ELIDE_TAIL);
if (is_filename) {
text = TruncateFilenameToTwoLines(text);
}
SetText(text);
}

void FadeLabel::SetFade(double percent) {
percent = std::min(1.0, percent);
const SkAlpha alpha = base::saturated_cast<SkAlpha>(
std::numeric_limits<SkAlpha>::max() * (1.0 - percent));
SetBackgroundColor(SkColorSetA(GetBackgroundColor(), alpha));
SetEnabledColor(SkColorSetA(GetEnabledColor(), alpha));
}

void FadeLabel::SetPaintBackground(bool paint_background) {
paint_background_ = paint_background;
}

void FadeLabel::OnPaintBackground(gfx::Canvas* canvas) {
if (paint_background_) {
canvas->DrawColor(GetBackgroundColor());
} else {
views::Label::OnPaintBackground(canvas);
}
}

// Returns a version of the text that's middle-elided on two lines.
std::u16string FadeLabel::TruncateFilenameToTwoLines(
const std::u16string& text) const {
FilenameElider elider(CreateRenderText());
gfx::Rect text_rect = GetContentsBounds();
text_rect.Inset(-gfx::ShadowValue::GetMargin(GetShadows()));
return elider.Elide(text, text_rect);
}

// FadeLabelView:
// ----------------------------------------------------------

FadeLabelView::FadeLabelView(int context, int num_lines)
: FadeView<FadeLabel, FadeLabel, FadeLabelViewData>(
CreateLabel<FadeLabel>(context),
CreateLabel<FadeLabel>(context)) {
if (num_lines > 1) {
primary_view_->SetMultiLine(true);
fade_out_view_->SetMultiLine(true);
primary_view_->SetMaxLines(num_lines);
fade_out_view_->SetMaxLines(num_lines);
}

fade_out_view_->SetPaintBackground(true);
}

std::u16string FadeLabelView::GetText() {
return primary_view_->GetText();
}
61 changes: 61 additions & 0 deletions chrome/browser/ui/views/tabs/fade_label_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_TABS_FADE_LABEL_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_FADE_LABEL_VIEW_H_

#include "chrome/browser/ui/views/tabs/fade_view.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/label.h"

struct FadeLabelViewData {
std::u16string text;
bool is_filename;
};

// Label that is able to fade when used in conjunction with FadeView
class FadeLabel : public FadeWrapper<views::Label, FadeLabelViewData> {
public:
template <typename... Args>
explicit FadeLabel(Args&&... args)
: FadeWrapper<views::Label, FadeLabelViewData>(
std::forward<Args>(args)...) {
SetHorizontalAlignment(gfx::ALIGN_LEFT);
SetVerticalAlignment(gfx::ALIGN_TOP);
}

~FadeLabel() override = default;

// FadeWrapper:
void SetData(const FadeLabelViewData& data) override;
void SetFade(double percent) override;

// Renders the label's background in a solid color so that the label can be
// placed in front of a nother label and animate a fade out
void SetPaintBackground(bool paint_background);

// views::Label:
void OnPaintBackground(gfx::Canvas* canvas) override;

private:
// Returns a version of the text that's middle-elided on two lines.
std::u16string TruncateFilenameToTwoLines(const std::u16string& text) const;

bool paint_background_ = false;
};

// This view overlays and fades out an old version of the text of a label,
// while displaying the new text underneath. It is used to fade out the old
// value of the title and domain labels on the hover card when the tab switches
// or the tab title changes.
class FadeLabelView : public FadeView<FadeLabel, FadeLabel, FadeLabelViewData> {
public:
FadeLabelView(int context, int num_lines);

~FadeLabelView() override = default;

std::u16string GetText();
};

#endif // CHROME_BROWSER_UI_VIEWS_TABS_FADE_LABEL_VIEW_H_
87 changes: 87 additions & 0 deletions chrome/browser/ui/views/tabs/fade_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_TABS_FADE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_FADE_VIEW_H_

#include "ui/color/color_provider.h"
#include "ui/gfx/animation/tween.h"
#include "ui/views/background.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"

// Adapts any view `T` so that the view can fade when used by a FadeView
template <typename T, typename V>
class FadeWrapper : public T {
public:
template <typename... Args>
explicit FadeWrapper(Args&&... args) : T(std::forward<Args>(args)...) {}

virtual void SetData(const V& data) = 0;
const V& GetData() { return data_; }

// Sets the fade of this FadeWrapper's fade as |percent| in the range [0, 1]
virtual void SetFade(double percent) = 0;

protected:
V data_;
};

// Cross fades any view so that view `U` is the old view that would be faded
// away. This allows view `T` to fade in for the user to ensure a smooth
// transition from the view with the old data `U` to the updated data in `T`
template <typename T, typename U, typename V>
class FadeView : public views::View {
public:
FadeView(std::unique_ptr<T> primary_view, std::unique_ptr<U> fade_out_view) {
SetLayoutManager(std::make_unique<views::FillLayout>());
primary_view_ = AddChildView(std::move(primary_view));
fade_out_view_ = AddChildView(std::move(fade_out_view));
}

~FadeView() override = default;

void SetData(const V& data) {
fade_out_view_->SetData(primary_view_->GetData());
primary_view_->SetData(data);
}

// Sets the fade-out of the `fade_out_view_` as |percent| in the range [0, 1].
// Since FadeView is designed to mask new view with the old and then fade
// away, the higher the percentage the less opaque the view.
void SetFade(double percent) {
percent_ = percent;
fade_out_view_->SetFade(percent);
if (percent == 1.0) {
fade_out_view_->SetData(V());
}
}

gfx::Size GetMinimumSize() const override {
return primary_view_->GetMinimumSize();
}

gfx::Size CalculatePreferredSize() const override {
return primary_view_->CalculatePreferredSize();
}

int GetHeightForWidth(int width) const override {
return primary_view_->GetHeightForWidth(width);
}

gfx::Size GetMaximumSize() const override {
return gfx::Tween::SizeValueBetween(percent_,
fade_out_view_->GetPreferredSize(),
primary_view_->GetPreferredSize());
}

protected:
raw_ptr<T> primary_view_ = nullptr;
raw_ptr<U> fade_out_view_ = nullptr;
double percent_ = 1.0;
};

#endif // CHROME_BROWSER_UI_VIEWS_TABS_FADE_VIEW_H_

0 comments on commit 8661ba1

Please sign in to comment.