Commit 62c1d3b1 authored by Dana Fried's avatar Dana Fried Committed by Chromium LUCI CQ

[User Education] Expandable tip that sits in tabstrip (prototype)

Currently nothing will cause this tip to be displayed, but this CL
provides the mechanism to do so for future experimentation.

Change-Id: Id8730bcf9c0a543c825a8842ebb6c4d73a5562aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2552035
Commit-Queue: Dana Fried <dfried@chromium.org>
Reviewed-by: default avatarTaylor Bergquist <tbergquist@chromium.org>
Reviewed-by: default avatarCollin Baker <collinbaker@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845593}
parent 147955f6
......@@ -4161,6 +4161,8 @@ static_library("ui") {
"views/user_education/feature_promo_registry.h",
"views/user_education/new_badge_label.cc",
"views/user_education/new_badge_label.h",
"views/user_education/tip_marquee_view.cc",
"views/user_education/tip_marquee_view.h",
"views/web_apps/frame_toolbar/web_app_content_settings_container.cc",
"views/web_apps/frame_toolbar/web_app_content_settings_container.h",
"views/web_apps/frame_toolbar/web_app_frame_toolbar_utils.cc",
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/ui/views/frame/tab_strip_region_view.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/ui_features.h"
......@@ -13,6 +14,7 @@
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
#include "chrome/browser/ui/views/tabs/tab_style_views.h"
#include "chrome/browser/ui/views/user_education/tip_marquee_view.h"
#include "chrome/grit/generated_resources.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -20,8 +22,10 @@
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/metadata/metadata_header_macros.h"
#include "ui/views/metadata/metadata_impl_macros.h"
#include "ui/views/style/typography.h"
#include "ui/views/view_class_properties.h"
namespace {
......@@ -208,7 +212,25 @@ TabStripRegionView::TabStripRegionView(std::unique_ptr<TabStrip> tab_strip) {
reserved_grab_handle_space_->SetProperty(
views::kFlexBehaviorKey,
views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
views::MaximumFlexSizeRule::kUnbounded));
views::MaximumFlexSizeRule::kUnbounded)
.WithOrder(3));
// This is the margin necessary to ensure correct spacing between right-
// aligned control and the end of the TabStripRegionView.
const gfx::Insets control_padding = gfx::Insets(
0, 0, 0, GetLayoutConstant(TABSTRIP_REGION_VIEW_CONTROL_PADDING));
tip_marquee_view_ = AddChildView(
std::make_unique<TipMarqueeView>(views::style::CONTEXT_LABEL));
tip_marquee_view_->SetProperty(
views::kFlexBehaviorKey,
views::FlexSpecification(
views::LayoutOrientation::kHorizontal,
views::MinimumFlexSizeRule::kPreferredSnapToMinimum)
.WithOrder(2));
tip_marquee_view_->SetProperty(views::kCrossAxisAlignmentKey,
views::LayoutAlignment::kCenter);
tip_marquee_view_->SetProperty(views::kMarginsKey, control_padding);
const Browser* browser = tab_strip_->controller()->GetBrowser();
if (base::FeatureList::IsEnabled(features::kTabSearch) && browser &&
......@@ -221,11 +243,7 @@ TabStripRegionView::TabStripRegionView(std::unique_ptr<TabStrip> tab_strip) {
tab_search_button->SetProperty(views::kCrossAxisAlignmentKey,
views::LayoutAlignment::kCenter);
tab_search_button_ = AddChildView(std::move(tab_search_button));
// Add the margin necessary to ensure correct spacing between right-aligned
// controls and the end of the TabStripRegionView.
layout_manager_->SetInteriorMargin(gfx::Insets(
0, 0, 0, GetLayoutConstant(TABSTRIP_REGION_VIEW_CONTROL_PADDING)));
tab_search_button_->SetProperty(views::kMarginsKey, control_padding);
}
}
......@@ -326,15 +344,14 @@ void TabStripRegionView::OnViewPreferredSizeChanged(View* view) {
int TabStripRegionView::GetTabStripAvailableWidth() const {
// The tab strip can occupy the space not currently taken by its fixed-width
// sibling views.
int reserved_width = 0;
for (View* const child : children()) {
if (child != tab_strip_container_)
reserved_width += child->GetMinimumSize().width();
}
return size().width() - reserved_width -
layout_manager_->interior_margin().width();
// sibling views. First ask for the available size of the container.
views::SizeBound width_bound = GetAvailableSize(tab_strip_container_).width();
// Because we can't return a null value, and we can't return zero, for cases
// where we have never been laid out we will return something arbitrary (the
// width of the region view is as good a choice as any, as it's strictly
// larger than the tabstrip should be able to display).
return width_bound.min_of(width());
}
void TabStripRegionView::ScrollTowardsLeadingTab() {
......
......@@ -17,6 +17,7 @@ class FlexLayout;
class NewTabButton;
class TabSearchButton;
class TabStrip;
class TipMarqueeView;
// Container for the tabstrip, new tab button, and reserved grab handle space.
class TabStripRegionView final : public views::AccessiblePaneView,
......@@ -45,6 +46,8 @@ class TabStripRegionView final : public views::AccessiblePaneView,
TabSearchButton* tab_search_button() { return tab_search_button_; }
TipMarqueeView* tip_marquee_view() { return tip_marquee_view_; }
views::View* reserved_grab_handle_space_for_testing() {
return reserved_grab_handle_space_;
}
......@@ -84,6 +87,7 @@ class TabStripRegionView final : public views::AccessiblePaneView,
TabSearchButton* tab_search_button_ = nullptr;
views::ImageButton* leading_scroll_button_;
views::ImageButton* trailing_scroll_button_;
TipMarqueeView* tip_marquee_view_ = nullptr;
const base::CallbackListSubscription subscription_ =
ui::TouchUiController::Get()->RegisterCallback(
......
......@@ -7,6 +7,7 @@
#include "base/feature_list.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tabs/new_tab_button.h"
......@@ -180,10 +181,8 @@ IN_PROC_BROWSER_TEST_P(TabStripRegionViewBrowserTest, TestBeginEndFocus) {
IN_PROC_BROWSER_TEST_P(TabStripRegionViewBrowserTest,
TestSearchButtonIsEndAligned) {
if (base::FeatureList::IsEnabled(features::kTabSearch)) {
const int kRightMargin = tab_strip_region_view()
->layout_manager_for_testing()
->interior_margin()
.right();
const int kRightMargin =
GetLayoutConstant(TABSTRIP_REGION_VIEW_CONTROL_PADDING);
EXPECT_EQ(tab_strip_region_view()->GetLocalBounds().right() - kRightMargin,
tab_search_button()->bounds().right());
}
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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/user_education/tip_marquee_view.h"
#include <memory>
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/resources_util.h"
#include "chrome/grit/theme_resources.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/view_class_properties.h"
constexpr int TipMarqueeView::kTipMarqueeIconSize;
constexpr int TipMarqueeView::kTipMarqueeIconPadding;
constexpr int TipMarqueeView::kTipMarqueeIconTotalWidth;
TipMarqueeView::TipMarqueeView(int text_context, int text_style) {
tip_text_label_ = AddChildView(std::make_unique<views::StyledLabel>());
tip_text_label_->SetTextContext(text_context);
tip_text_label_->SetDefaultTextStyle(text_style);
// TODO(dfried): Figure out how to set elide behavior.
// tip_text_label_->SetElideBehavior(gfx::ElideBehavior::ELIDE_TAIL);
// TODO(dfried): Limit to builds where GOOGLE_CHROME_BRANDING is set.
chrome_icon_ = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
IDR_PRODUCT_LOGO_16);
SetBorder(views::CreateEmptyBorder(
gfx::Insets(0, kTipMarqueeIconTotalWidth, 0, 0)));
SetVisible(false);
}
TipMarqueeView::~TipMarqueeView() = default;
bool TipMarqueeView::SetTip(
const base::string16& tip_text,
LearnMoreLinkClickedCallback learn_more_link_clicked_callback) {
tip_text_ = tip_text;
base::string16 full_tip = tip_text;
const base::string16 separator = base::ASCIIToUTF16(" - ");
const size_t tip_text_length = tip_text.length();
const bool has_learn_more_link = !learn_more_link_clicked_callback.is_null();
if (has_learn_more_link) {
full_tip.append(separator);
full_tip.append(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
}
tip_text_label_->SetText(full_tip);
if (has_learn_more_link) {
tip_text_label_->AddStyleRange(
gfx::Range(tip_text_length + separator.length(), full_tip.length()),
views::StyledLabel::RangeStyleInfo::CreateForLink(base::BindRepeating(
&TipMarqueeView::LearnMoreLinkClicked, base::Unretained(this))));
}
learn_more_link_clicked_callback_ = learn_more_link_clicked_callback;
collapsed_ = false;
SetVisible(true);
return !collapsed_;
}
void TipMarqueeView::ClearTip() {
tip_text_label_->SetText(base::string16());
tip_text_.clear();
learn_more_link_clicked_callback_.Reset();
SetVisible(false);
}
bool TipMarqueeView::OnMousePressed(const ui::MouseEvent& event) {
if (!IsPointInIcon(event.location()))
return false;
if (!CanFitInLayout() && learn_more_link_clicked_callback_) {
LearnMoreLinkClicked();
} else {
collapsed_ = !collapsed_;
InvalidateLayout();
}
return true;
}
gfx::Size TipMarqueeView::CalculatePreferredSize() const {
if (collapsed_)
return GetMinimumSize();
const gfx::Size label_size = tip_text_label_->GetPreferredSize();
const int width = label_size.width() + kTipMarqueeIconTotalWidth;
const int height = std::max(label_size.height(), kTipMarqueeIconSize);
return gfx::Size(width, height);
}
gfx::Size TipMarqueeView::GetMinimumSize() const {
return gfx::Size(kTipMarqueeIconSize, kTipMarqueeIconSize);
}
void TipMarqueeView::Layout() {
// TODO(dfried): animate label
if (collapsed_ || size().width() < GetPreferredSize().width()) {
tip_text_label_->SetVisible(false);
} else {
tip_text_label_->SetVisible(true);
gfx::Rect text_rect = GetContentsBounds();
text_rect.Inset(0,
std::max(0, (text_rect.height() -
tip_text_label_->GetPreferredSize().height()) /
2));
tip_text_label_->SetBoundsRect(text_rect);
}
}
void TipMarqueeView::OnPaint(gfx::Canvas* canvas) {
View::OnPaint(canvas);
canvas->DrawImageInt(chrome_icon_, 0, 0, kTipMarqueeIconSize,
kTipMarqueeIconSize, 0,
(height() - kTipMarqueeIconSize) / 2,
kTipMarqueeIconSize, kTipMarqueeIconSize, true);
}
base::string16 TipMarqueeView::GetTooltipText(const gfx::Point& p) const {
if (!IsPointInIcon(p))
return View::GetTooltipText(p);
if (tip_text_label_->GetVisible()) {
return base::ASCIIToUTF16("Click to hide tip");
} else if (CanFitInLayout()) {
return base::ASCIIToUTF16("Click to show tip");
} else {
base::string16 result = tip_text_;
result.append(base::ASCIIToUTF16(" - Click to learn more"));
return result;
}
}
void TipMarqueeView::LearnMoreLinkClicked() {
// TODO(dfried): in future, when we animate the tip out, this assumption may
// not be valid.
DCHECK(learn_more_link_clicked_callback_);
learn_more_link_clicked_callback_.Run(this);
}
bool TipMarqueeView::CanFitInLayout() const {
const views::SizeBounds available = parent()->GetAvailableSize(this);
if (!available.width().is_bounded())
return true;
return available.width().value() >=
tip_text_label_->GetPreferredSize().width() +
kTipMarqueeIconTotalWidth;
}
bool TipMarqueeView::IsPointInIcon(const gfx::Point& p) const {
const int pos = GetMirroredXInView(p.x());
return pos < kTipMarqueeIconTotalWidth;
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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_USER_EDUCATION_TIP_MARQUEE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_USER_EDUCATION_TIP_MARQUEE_VIEW_H_
#include "base/callback.h"
#include "base/callback_forward.h"
#include "ui/gfx/canvas.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/style/typography.h"
#include "ui/views/view.h"
namespace gfx {
class ImageSkia;
} // namespace gfx
namespace views {
class StyledLabel;
}
// Displays a tip that can scroll out from a Chrome icon to a full sentence,
// optionally with a clickable tip.
//
// 🌏 Did you know that Chrome can display web pages? [ LEARN MORE ]
// 🌏 Did you know that Chrome ca...
// 🌏
class TipMarqueeView : public views::View {
public:
using LearnMoreLinkClickedCallback =
base::RepeatingCallback<void(TipMarqueeView*)>;
// Constructs a tip marquee view which will display text with the given
// display parameters (see views::Label::Label() for usage).
explicit TipMarqueeView(int text_context = views::style::CONTEXT_LABEL,
int text_style = views::style::STYLE_PRIMARY);
~TipMarqueeView() override;
// Sets the tip and shows the view if there is adequate space. |tip_text| will
// be displayed as plain text, and if |learn_more_link_clicked_callback| is
// specified, a "learn more" link will be present that will call the callback
// when clicked.
//
// Returns true if there is sufficient space in the parent view's layout to
// display the fully expanded tip text and (if applicable) Learn More link.
bool SetTip(const base::string16& tip_text,
LearnMoreLinkClickedCallback learn_more_link_clicked_callback =
LearnMoreLinkClickedCallback());
// Clears the tip and hides the view.
void ClearTip();
// views::View:
gfx::Size GetMinimumSize() const override;
base::string16 GetTooltipText(const gfx::Point& p) const override;
void Layout() override;
bool OnMousePressed(const ui::MouseEvent& event) override;
static constexpr int kTipMarqueeIconSize = 16;
static constexpr int kTipMarqueeIconPadding = 6;
static constexpr int kTipMarqueeIconTotalWidth =
kTipMarqueeIconSize + kTipMarqueeIconPadding;
private:
// views::View:
gfx::Size CalculatePreferredSize() const override;
void OnPaint(gfx::Canvas* canvas) override;
void LearnMoreLinkClicked();
bool CanFitInLayout() const;
bool IsPointInIcon(const gfx::Point& p) const;
base::string16 tip_text_;
views::StyledLabel* tip_text_label_ = nullptr;
gfx::ImageSkia chrome_icon_;
LearnMoreLinkClickedCallback learn_more_link_clicked_callback_;
bool collapsed_ = false;
};
#endif // CHROME_BROWSER_UI_VIEWS_USER_EDUCATION_TIP_MARQUEE_VIEW_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/views/user_education/tip_marquee_view.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/tab_strip_region_view.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/test/browser_test.h"
class TipMarqueeViewBrowserTest : public InProcessBrowserTest {
public:
TabStripRegionView* tab_strip_region_view() {
return BrowserView::GetBrowserViewForBrowser(browser())
->tab_strip_region_view();
}
TipMarqueeView* tip_marquee_view() {
return tab_strip_region_view()->tip_marquee_view();
}
};
IN_PROC_BROWSER_TEST_F(TipMarqueeViewBrowserTest, MarqueeStartsInvisibile) {
EXPECT_FALSE(tip_marquee_view()->GetVisible());
}
IN_PROC_BROWSER_TEST_F(TipMarqueeViewBrowserTest,
VisibilityChangesOnSetAndClearTip) {
tip_marquee_view()->SetTip(base::ASCIIToUTF16("Tip Text"));
EXPECT_TRUE(tip_marquee_view()->GetVisible());
tip_marquee_view()->ClearTip();
EXPECT_FALSE(tip_marquee_view()->GetVisible());
}
IN_PROC_BROWSER_TEST_F(TipMarqueeViewBrowserTest, TipStartsExpanded) {
tip_marquee_view()->SetTip(base::ASCIIToUTF16("Tip Text"));
tab_strip_region_view()->Layout();
EXPECT_EQ(tip_marquee_view()->GetPreferredSize(), tip_marquee_view()->size());
}
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// 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/user_education/tip_marquee_view.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/types/event_type.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/layout/layout_types.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/widget/widget.h"
namespace {
static constexpr gfx::Size kTipMarqueeWidgetSize(1000, 60);
static constexpr gfx::Size kSpacerPreferredSize(100, 60);
class LearnMoreCallback {
public:
TipMarqueeView::LearnMoreLinkClickedCallback Callback() {
return base::BindRepeating(&LearnMoreCallback::IncrementCount,
base::Unretained(this));
}
int count() const { return count_; }
private:
void IncrementCount(TipMarqueeView*) { ++count_; }
int count_ = 0;
};
} // anonymous namespace
class TipMarqueeViewTest : public views::ViewsTestBase {
public:
TipMarqueeViewTest() = default;
~TipMarqueeViewTest() override = default;
void SetUp() override {
ViewsTestBase::SetUp();
widget_ = std::make_unique<views::Widget>();
views::Widget::InitParams params =
CreateParams(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(gfx::Point(), kTipMarqueeWidgetSize);
widget_->Init(std::move(params));
contents_ = widget_->SetContentsView(std::make_unique<views::View>());
contents_->SetLayoutManager(std::make_unique<views::FlexLayout>())
->SetOrientation(views::LayoutOrientation::kHorizontal);
spacer_ = contents_->AddChildView(std::make_unique<views::View>());
spacer_->SetPreferredSize(kSpacerPreferredSize);
spacer_->SetProperty(
views::kFlexBehaviorKey,
views::FlexSpecification(views::LayoutOrientation::kHorizontal,
views::MinimumFlexSizeRule::kPreferred,
views::MaximumFlexSizeRule::kUnbounded));
marquee_ = contents_->AddChildView(
std::make_unique<TipMarqueeView>(views::style::CONTEXT_DIALOG_TITLE));
marquee_->SetProperty(
views::kFlexBehaviorKey,
views::FlexSpecification(
views::LayoutOrientation::kHorizontal,
views::MinimumFlexSizeRule::kPreferredSnapToMinimum)
.WithOrder(2));
marquee_->SetProperty(views::kCrossAxisAlignmentKey,
views::LayoutAlignment::kCenter);
widget_->Show();
}
void TearDown() override {
widget_.reset();
contents_ = nullptr;
spacer_ = nullptr;
marquee_ = nullptr;
ViewsTestBase::TearDown();
}
// Send mouse down and mouse up event at |point| within the marquee, ensuring
// that the event is delivered to the correct view (which could be the marquee
// or a child view).
void SimulateMarqueeClick(gfx::Point point) {
point.Offset(marquee_->x(), marquee_->y());
ui::MouseEvent press(ui::ET_MOUSE_PRESSED, point, point,
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
ui::MouseEvent release(ui::ET_MOUSE_RELEASED, point, point,
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
widget_->GetRootView()->OnMouseEvent(&press);
widget_->GetRootView()->OnMouseEvent(&release);
}
protected:
std::unique_ptr<views::Widget> widget_;
views::View* contents_ = nullptr;
views::View* spacer_ = nullptr;
TipMarqueeView* marquee_ = nullptr;
};
TEST_F(TipMarqueeViewTest, NotVisibleWhenNoTip) {
widget_->LayoutRootViewIfNecessary();
EXPECT_FALSE(marquee_->GetVisible());
}
TEST_F(TipMarqueeViewTest, VisibleWhenTipSet) {
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"));
widget_->LayoutRootViewIfNecessary();
EXPECT_TRUE(marquee_->GetVisible());
}
TEST_F(TipMarqueeViewTest, ClearTipHidesView) {
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"));
widget_->LayoutRootViewIfNecessary();
EXPECT_TRUE(marquee_->GetVisible());
EXPECT_EQ(marquee_->GetPreferredSize(), marquee_->size());
marquee_->ClearTip();
widget_->LayoutRootViewIfNecessary();
EXPECT_FALSE(marquee_->GetVisible());
}
TEST_F(TipMarqueeViewTest, TipStartsExpanded) {
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"));
widget_->LayoutRootViewIfNecessary();
EXPECT_GT(marquee_->width(), marquee_->GetMinimumSize().width());
}
TEST_F(TipMarqueeViewTest, TipCollapsesWhenNotEnoughSpace) {
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"));
widget_->LayoutRootViewIfNecessary();
gfx::Size spacer_size = spacer_->size();
spacer_size.Enlarge(1, 0);
spacer_->SetPreferredSize(spacer_size);
contents_->Layout();
EXPECT_EQ(marquee_->width(), marquee_->GetMinimumSize().width());
}
TEST_F(TipMarqueeViewTest, TipCollapsesAndExpandsWhenIconIsClicked) {
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"));
widget_->LayoutRootViewIfNecessary();
// This location should be comfortably inside the icon area.
constexpr gfx::Point kPressPoint(10, 10);
// Collapse.
marquee_->OnMousePressed(ui::MouseEvent(
ui::ET_MOUSE_PRESSED, kPressPoint, kPressPoint, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
contents_->Layout();
EXPECT_EQ(marquee_->width(), marquee_->GetMinimumSize().width());
// Expand.
marquee_->OnMousePressed(ui::MouseEvent(
ui::ET_MOUSE_PRESSED, kPressPoint, kPressPoint, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
contents_->Layout();
EXPECT_GT(marquee_->width(), marquee_->GetMinimumSize().width());
}
TEST_F(TipMarqueeViewTest, TipDoesNotExpandWhenInsufficientSpace) {
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"));
widget_->LayoutRootViewIfNecessary();
gfx::Size spacer_size = spacer_->size();
spacer_size.Enlarge(1, 0);
spacer_->SetPreferredSize(spacer_size);
contents_->Layout();
EXPECT_EQ(marquee_->width(), marquee_->GetMinimumSize().width());
// This location should be comfortably inside the icon area.
constexpr gfx::Point kPressPoint(10, 10);
SimulateMarqueeClick(kPressPoint);
contents_->Layout();
EXPECT_EQ(marquee_->width(), marquee_->GetMinimumSize().width());
}
TEST_F(TipMarqueeViewTest, ClickLearnMoreLink) {
LearnMoreCallback callback;
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"), callback.Callback());
widget_->LayoutRootViewIfNecessary();
EXPECT_GT(marquee_->width(), marquee_->GetMinimumSize().width());
// This location should be comfortably inside the "learn more" link.
const gfx::Point click_point(marquee_->width() - 10, marquee_->height() / 2);
EXPECT_EQ(0, callback.count());
SimulateMarqueeClick(click_point);
EXPECT_EQ(1, callback.count());
}
TEST_F(TipMarqueeViewTest, ClickNotInLearnMoreLinkHasNoEffect) {
LearnMoreCallback callback;
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"), callback.Callback());
widget_->LayoutRootViewIfNecessary();
EXPECT_GT(marquee_->width(), marquee_->GetMinimumSize().width());
// This location should be comfortably inside the tip text but not the link.
const gfx::Point click_point(TipMarqueeView::kTipMarqueeIconTotalWidth + 10,
marquee_->height() / 2);
EXPECT_EQ(0, callback.count());
SimulateMarqueeClick(click_point);
EXPECT_EQ(0, callback.count());
}
TEST_F(TipMarqueeViewTest, ClickWhenForcedCollapsedCallsLearnMore) {
LearnMoreCallback callback;
marquee_->SetTip(base::ASCIIToUTF16("Tip Text"), callback.Callback());
widget_->LayoutRootViewIfNecessary();
gfx::Size spacer_size = spacer_->size();
spacer_size.Enlarge(1, 0);
spacer_->SetPreferredSize(spacer_size);
contents_->Layout();
EXPECT_EQ(marquee_->width(), marquee_->GetMinimumSize().width());
// This location should be comfortably inside the icon area.
constexpr gfx::Point kPressPoint(10, 10);
EXPECT_EQ(0, callback.count());
SimulateMarqueeClick(kPressPoint);
EXPECT_EQ(1, callback.count());
}
......@@ -2332,6 +2332,7 @@ if (!is_android) {
"../browser/ui/views/translate/translate_bubble_view_browsertest.cc",
"../browser/ui/views/translate/translate_language_browsertest.cc",
"../browser/ui/views/user_education/feature_promo_dialog_browsertest.cc",
"../browser/ui/views/user_education/tip_marquee_view_browsertest.cc",
"../browser/ui/views/web_apps/web_app_uninstall_dialog_browsertest.cc",
]
if (is_win) {
......@@ -6118,6 +6119,7 @@ test("unit_tests") {
"../browser/ui/views/translate/translate_bubble_view_unittest.cc",
"../browser/ui/views/user_education/feature_promo_bubble_view_unittest.cc",
"../browser/ui/views/user_education/feature_promo_controller_views_unittest.cc",
"../browser/ui/views/user_education/tip_marquee_view_unittest.cc",
"../browser/ui/views/window_name_prompt_unittest.cc",
]
if (is_linux || is_chromeos_lacros) {
......
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