Commit 2a5dd6cd authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Part 1 of the arrow button implementation

This CL is the first part of code to implement the arrow button in
the overflow bubble view.
See more details from the below doc link:
https://docs.google.com/document/d/1dO4H_4T6ttWFc75nCNi2Uh18k-3_M8-eOHcfMTcNwd0/edit?usp=sharing

Bug: 918024
Change-Id: I6f8bf2dfe4871e2457947468696834adbd5d264d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1686782
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676253}
parent ed15e91e
......@@ -105,6 +105,8 @@ aggregate_vector_icons("ash_vector_icons") {
"notification_timer.icon",
"overview_window_close.icon",
"overview_drop_target_plus.icon",
"overflow_shelf_left.icon",
"overflow_shelf_right.icon",
"palette_action_capture_region.icon",
"palette_action_capture_screen.icon",
"palette_action_create_note.icon",
......
// Copyright 2019 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.
CANVAS_DIMENSIONS, 20,
MOVE_TO, 13.34f, 13.83f,
LINE_TO, 12.07f, 15,
LINE_TO, 6.67f, 10,
R_LINE_TO, 5.4f, -5,
R_LINE_TO, 1.27f, 1.18f,
LINE_TO, 9.22f, 10,
CLOSE
// Copyright 2019 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.
CANVAS_DIMENSIONS, 20,
MOVE_TO, 6.67f, 13.83f,
LINE_TO, 10.79f, 10,
LINE_TO, 6.67f, 6.18f,
LINE_TO, 7.94f, 5,
R_LINE_TO, 5.4f, 5,
R_LINE_TO, -5.4f, 5,
CLOSE
......@@ -7,6 +7,7 @@
#include <algorithm>
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_constants.h"
#include "ash/shelf/shelf_view.h"
......@@ -17,13 +18,20 @@
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
// Padding at the two ends of the bubble.
constexpr int kEndPadding = 16;
// Padding at the two ends of the shelf in overflow mode.
constexpr int kEndPadding = 4;
// Padding between the end of the shelf in overview mode and the arrow button
// (if any).
constexpr int kDistanceToArrowButton = kShelfButtonSpacing;
// Distance between overflow bubble and the main shelf.
constexpr int kDistanceToMainShelf = 4;
......@@ -31,14 +39,110 @@ constexpr int kDistanceToMainShelf = 4;
// Minimum margin around the bubble so that it doesn't hug the screen edges.
constexpr int kMinimumMargin = 8;
// Size of the arrow button.
constexpr int kArrowButtonSize = kShelfControlSize;
// Sum of the shelf button size and the gap between shelf buttons.
constexpr int kUnit = kShelfButtonSize + kShelfButtonSpacing;
} // namespace
////////////////////////////////////////////////////////////////////////////////
// ScrollArrowView
OverflowBubbleView::ScrollArrowView::ScrollArrowView(
ArrowType arrow_type,
bool is_horizontal_alignment)
: arrow_type_(arrow_type),
is_horizontal_alignment_(is_horizontal_alignment) {
SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
}
void OverflowBubbleView::ScrollArrowView::OnPaint(gfx::Canvas* canvas) {
gfx::ImageSkia img = CreateVectorIcon(
arrow_type_ == LEFT ? kOverflowShelfLeftIcon : kOverflowShelfRightIcon,
SK_ColorWHITE);
if (!is_horizontal_alignment_) {
img = gfx::ImageSkiaOperations::CreateRotatedImage(
img, SkBitmapOperations::ROTATION_90_CW);
}
gfx::PointF center_point(width() / 2.f, height() / 2.f);
canvas->DrawImageInt(img, center_point.x() - img.width() / 2,
center_point.y() - img.height() / 2);
float ring_radius_dp = kArrowButtonSize / 2;
{
gfx::PointF circle_center(center_point);
gfx::ScopedCanvas scoped_canvas(canvas);
const float dsf = canvas->UndoDeviceScaleFactor();
circle_center.Scale(dsf);
cc::PaintFlags fg_flags;
fg_flags.setAntiAlias(true);
fg_flags.setColor(kShelfControlPermanentHighlightBackground);
const float radius = std::ceil(ring_radius_dp * dsf);
canvas->DrawCircle(circle_center, radius, fg_flags);
}
}
const char* OverflowBubbleView::ScrollArrowView::GetClassName() const {
return "ScrollArrowView";
}
////////////////////////////////////////////////////////////////////////////////
// OverflowShelfContainerView impl
OverflowBubbleView::OverflowShelfContainerView::OverflowShelfContainerView(
ShelfView* shelf_view)
: shelf_view_(shelf_view) {}
void OverflowBubbleView::OverflowShelfContainerView::Initialize() {
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
layer()->SetMasksToBounds(true);
shelf_view_->SetPaintToLayer();
shelf_view_->layer()->SetFillsBoundsOpaquely(false);
AddChildView(shelf_view_);
}
gfx::Size
OverflowBubbleView::OverflowShelfContainerView::CalculatePreferredSize() const {
return shelf_view_->CalculatePreferredSize();
}
void OverflowBubbleView::OverflowShelfContainerView::ChildPreferredSizeChanged(
views::View* child) {
PreferredSizeChanged();
}
void OverflowBubbleView::OverflowShelfContainerView::Layout() {
shelf_view_->SetBoundsRect(
gfx::Rect(gfx::Point(), shelf_view_->GetPreferredSize()));
}
const char* OverflowBubbleView::OverflowShelfContainerView::GetClassName()
const {
return "OverflowShelfContainerView";
}
void OverflowBubbleView::OverflowShelfContainerView::TranslateShelfView(
const gfx::Vector2d& offset) {
gfx::Transform transform_matrix;
transform_matrix.Translate(-offset);
shelf_view_->SetTransform(transform_matrix);
}
////////////////////////////////////////////////////////////////////////////////
// OverflowBubbleView
OverflowBubbleView::OverflowBubbleView(ShelfView* shelf_view,
views::View* anchor,
SkColor background_color)
: ShelfBubble(anchor, shelf_view->shelf()->alignment(), background_color),
shelf_(shelf_view->shelf()),
shelf_view_(shelf_view) {
shelf_(shelf_view->shelf()) {
DCHECK(shelf_);
set_border_radius(ShelfConstants::shelf_size() / 2);
......@@ -47,20 +151,29 @@ OverflowBubbleView::OverflowBubbleView(ShelfView* shelf_view,
set_shadow(views::BubbleBorder::NO_ASSETS);
set_close_on_deactivate(false);
set_accept_events(true);
if (shelf_->IsHorizontalAlignment())
set_margins(gfx::Insets(0, kEndPadding));
else
set_margins(gfx::Insets(kEndPadding, 0));
set_margins(gfx::Insets(0, 0));
// Makes bubble view has a layer and clip its children layers.
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
layer()->SetMasksToBounds(true);
CreateBubble();
// Initialize the left arrow button.
left_arrow_ = new ScrollArrowView(ScrollArrowView::LEFT,
shelf_->IsHorizontalAlignment());
AddChildView(left_arrow_);
AddChildView(shelf_view_);
// Initialize the right arrow button.
right_arrow_ = new ScrollArrowView(ScrollArrowView::RIGHT,
shelf_->IsHorizontalAlignment());
AddChildView(right_arrow_);
// Initialize the shelf container view.
shelf_container_view_ = new OverflowShelfContainerView(shelf_view);
shelf_container_view_->Initialize();
AddChildView(shelf_container_view_);
CreateBubble();
}
OverflowBubbleView::~OverflowBubbleView() = default;
......@@ -83,55 +196,184 @@ bool OverflowBubbleView::ProcessGestureEvent(const ui::GestureEvent& event) {
}
int OverflowBubbleView::ScrollByXOffset(int x_offset) {
const gfx::Rect visible_bounds(GetContentsBounds());
const gfx::Size contents_size(shelf_view_->GetPreferredSize());
DCHECK_GE(contents_size.width(), visible_bounds.width());
const int old_x = scroll_offset_.x();
const int x = std::min(contents_size.width() - visible_bounds.width(),
std::max(0, old_x + x_offset));
const int x = CalculateLayoutStrategyAfterScroll(x_offset);
scroll_offset_.set_x(x);
Layout();
return x - old_x;
}
int OverflowBubbleView::ScrollByYOffset(int y_offset) {
const gfx::Rect visible_bounds(GetContentsBounds());
const gfx::Size contents_size(shelf_view_->GetPreferredSize());
DCHECK_GE(contents_size.height(), visible_bounds.height());
const int old_y = scroll_offset_.y();
const int y = std::min(contents_size.height() - visible_bounds.height(),
std::max(0, old_y + y_offset));
const int y = CalculateLayoutStrategyAfterScroll(y_offset);
scroll_offset_.set_y(y);
Layout();
return y - old_y;
}
gfx::Size OverflowBubbleView::CalculatePreferredSize() const {
gfx::Size preferred_size = shelf_view_->GetPreferredSize();
int OverflowBubbleView::CalculateScrollUpperBound() const {
const bool is_horizontal = shelf_->IsHorizontalAlignment();
// Calculate the length of the available space.
const gfx::Rect content_size = GetContentsBounds();
const int available_length =
(is_horizontal ? content_size.width() : content_size.height()) -
2 * kEndPadding;
// Calculate the length of the preferred size.
const gfx::Size shelf_preferred_size(
shelf_container_view_->GetPreferredSize());
const int preferred_length = (is_horizontal ? shelf_preferred_size.width()
: shelf_preferred_size.height());
DCHECK_GE(preferred_length, available_length);
return preferred_length - available_length;
}
int OverflowBubbleView::CalculateLayoutStrategyAfterScroll(int scroll) {
const int old_scroll =
shelf_->IsHorizontalAlignment() ? scroll_offset_.x() : scroll_offset_.y();
const int scroll_upper_bound = CalculateScrollUpperBound();
scroll = std::min(scroll_upper_bound, std::max(0, old_scroll + scroll));
if (layout_strategy_ != NOT_SHOW_ARROW_BUTTON) {
if (scroll <= 0)
layout_strategy_ = SHOW_RIGHT_ARROW_BUTTON;
else if (scroll >= scroll_upper_bound)
layout_strategy_ = SHOW_LEFT_ARROW_BUTTON;
else
layout_strategy_ = SHOW_BUTTONS;
}
return scroll;
}
void OverflowBubbleView::AdjustToEnsureIconsFullyVisible(
gfx::Rect* bubble_bounds) const {
if (layout_strategy_ == NOT_SHOW_ARROW_BUTTON)
return;
int width = shelf_->IsHorizontalAlignment() ? bubble_bounds->width()
: bubble_bounds->height();
const int rd = width % kUnit;
width -= rd;
// Offset to ensure that the bubble view is shown at the center of the screen.
if (shelf_->IsHorizontalAlignment()) {
bubble_bounds->set_width(width);
bubble_bounds->Offset(rd / 2, 0);
} else {
bubble_bounds->set_height(width);
bubble_bounds->Offset(0, rd / 2);
}
}
const gfx::Rect monitor_rect =
gfx::Size OverflowBubbleView::CalculatePreferredSize() const {
gfx::Rect monitor_rect =
display::Screen::GetScreen()
->GetDisplayNearestPoint(GetAnchorRect().CenterPoint())
.work_area();
if (!monitor_rect.IsEmpty()) {
if (shelf_->IsHorizontalAlignment()) {
preferred_size.set_width(std::min(
preferred_size.width(), monitor_rect.width() - 2 * kEndPadding));
} else {
preferred_size.set_height(std::min(
preferred_size.height(), monitor_rect.height() - 2 * kEndPadding));
}
monitor_rect.Inset(gfx::Insets(kMinimumMargin));
int available_length = shelf_->IsHorizontalAlignment()
? monitor_rect.width()
: monitor_rect.height();
gfx::Size preferred_size = shelf_container_view_->GetPreferredSize();
int preferred_length = shelf_->IsHorizontalAlignment()
? preferred_size.width()
: preferred_size.height();
preferred_length += 2 * kEndPadding;
int scroll_length =
shelf_->IsHorizontalAlignment() ? scroll_offset_.x() : scroll_offset_.y();
if (preferred_length <= available_length) {
// Enough space to accommodate all of shelf buttons. So hide arrow buttons.
layout_strategy_ = NOT_SHOW_ARROW_BUTTON;
} else if (scroll_length == 0) {
// No invisible shelf buttons at the left side. So hide the left button.
layout_strategy_ = SHOW_RIGHT_ARROW_BUTTON;
} else if (scroll_length == CalculateScrollUpperBound()) {
// If there is no invisible shelf button at the right side, hide the right
// button.
layout_strategy_ = SHOW_LEFT_ARROW_BUTTON;
} else {
// There are invisible shelf buttons at both sides. So show two buttons.
layout_strategy_ = SHOW_BUTTONS;
}
if (shelf_->IsHorizontalAlignment()) {
preferred_size.set_width(std::min(preferred_length, monitor_rect.width()));
} else {
preferred_size.set_height(
std::min(preferred_length, monitor_rect.height()));
}
return preferred_size;
}
void OverflowBubbleView::Layout() {
shelf_view_->SetBoundsRect(
gfx::Rect(gfx::PointAtOffsetFromOrigin(-scroll_offset_),
shelf_view_->GetPreferredSize()));
constexpr gfx::Size shelf_button_size(kShelfButtonSize, kShelfButtonSize);
constexpr gfx::Size arrow_button_size(kArrowButtonSize, kArrowButtonSize);
bool is_horizontal = shelf_->IsHorizontalAlignment();
gfx::Rect shelf_container_bounds = bounds();
// Transpose and layout as if it is horizontal.
if (!is_horizontal)
shelf_container_bounds.Transpose();
// The bounds of |left_arrow_| and |right_arrow_| in the parent coordinates.
gfx::Rect left_arrow_bounds, right_arrow_bounds;
// Calculates the bounds of the left arrow button. If the left arrow button
// should not show, |left_arrow_bounds| should be empty.
if (layout_strategy_ == SHOW_LEFT_ARROW_BUTTON ||
layout_strategy_ == SHOW_BUTTONS) {
left_arrow_bounds = gfx::Rect(shelf_button_size);
left_arrow_bounds.ClampToCenteredSize(arrow_button_size);
shelf_container_bounds.Inset(kShelfButtonSize + kDistanceToArrowButton, 0,
0, 0);
}
if (layout_strategy_ == SHOW_RIGHT_ARROW_BUTTON ||
layout_strategy_ == SHOW_BUTTONS) {
shelf_container_bounds.Inset(0, 0, kShelfButtonSize, 0);
right_arrow_bounds =
gfx::Rect(shelf_container_bounds.top_right(), shelf_button_size);
right_arrow_bounds.ClampToCenteredSize(arrow_button_size);
shelf_container_bounds.Inset(0, 0, kDistanceToArrowButton, 0);
}
shelf_container_bounds.Inset(kEndPadding, 0, kEndPadding, 0);
// Adjust the bounds when not showing in the horizontal alignment.
if (!shelf_->IsHorizontalAlignment()) {
left_arrow_bounds.Transpose();
right_arrow_bounds.Transpose();
shelf_container_bounds.Transpose();
}
// Draw |left_arrow| if it should show.
left_arrow_->SetVisible(!left_arrow_bounds.IsEmpty());
if (left_arrow_->GetVisible())
left_arrow_->SetBoundsRect(left_arrow_bounds);
// Draw |right_arrow| if it should show.
right_arrow_->SetVisible(!right_arrow_bounds.IsEmpty());
if (right_arrow_->GetVisible())
right_arrow_->SetBoundsRect(right_arrow_bounds);
// Draw |shelf_container_view_|.
shelf_container_view_->SetBoundsRect(shelf_container_bounds);
// When the left button shows, the origin of |shelf_container_view_| changes.
// So translate |shelf_container_view| to show the shelf view correctly.
gfx::Vector2d translate_vector;
if (!left_arrow_bounds.IsEmpty()) {
translate_vector = shelf_->IsHorizontalAlignment()
? gfx::Vector2d(shelf_container_bounds.x(), 0)
: gfx::Vector2d(0, shelf_container_bounds.y());
}
shelf_container_view_->TranslateShelfView(scroll_offset_ + translate_vector);
}
void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) {
......@@ -184,31 +426,32 @@ gfx::Rect OverflowBubbleView::GetBubbleBounds() {
// Make sure no part of the bubble touches a screen edge.
monitor_rect.Inset(gfx::Insets(kMinimumMargin));
gfx::Rect bounds;
if (shelf_->IsHorizontalAlignment()) {
gfx::Rect bounds(
base::i18n::IsRTL()
? anchor_rect.x() - kEndPadding
: anchor_rect.right() - content_size.width() - kEndPadding,
bounds = gfx::Rect(
base::i18n::IsRTL() ? anchor_rect.x()
: anchor_rect.right() - content_size.width(),
anchor_rect.y() - distance_to_overflow_button - content_size.height(),
content_size.width() + 2 * kEndPadding, content_size.height());
content_size.width(), content_size.height());
if (bounds.x() < monitor_rect.x())
bounds.Offset(monitor_rect.x() - bounds.x(), 0);
if (bounds.right() > monitor_rect.right())
bounds.set_width(monitor_rect.right() - bounds.x());
return bounds;
} else {
bounds = gfx::Rect(0, anchor_rect.bottom() - content_size.height(),
content_size.width(), content_size.height());
if (shelf_->alignment() == SHELF_ALIGNMENT_LEFT)
bounds.set_x(anchor_rect.right() + distance_to_overflow_button);
else
bounds.set_x(anchor_rect.x() - distance_to_overflow_button -
content_size.width());
if (bounds.y() < monitor_rect.y())
bounds.Offset(0, monitor_rect.y() - bounds.y());
if (bounds.bottom() > monitor_rect.bottom())
bounds.set_height(monitor_rect.bottom() - bounds.y());
}
gfx::Rect bounds(
0, anchor_rect.bottom() - content_size.height() - kEndPadding,
content_size.width(), content_size.height() + 2 * kEndPadding);
if (shelf_->alignment() == SHELF_ALIGNMENT_LEFT)
bounds.set_x(anchor_rect.right() + distance_to_overflow_button);
else
bounds.set_x(anchor_rect.x() - distance_to_overflow_button -
content_size.width());
if (bounds.y() < monitor_rect.y())
bounds.Offset(0, monitor_rect.y() - bounds.y());
if (bounds.bottom() > monitor_rect.bottom())
bounds.set_height(monitor_rect.bottom() - bounds.y());
AdjustToEnsureIconsFullyVisible(&bounds);
return bounds;
}
......
......@@ -17,6 +17,21 @@ class ShelfView;
// Exports to access this class from OverflowBubbleViewTestAPI.
class ASH_EXPORT OverflowBubbleView : public ShelfBubble {
public:
enum LayoutStrategy {
// The arrow buttons are not shown. It means that there is enough space to
// accommodate all of shelf icons.
NOT_SHOW_ARROW_BUTTON,
// Only the left arrow button is shown.
SHOW_LEFT_ARROW_BUTTON,
// Only the right arrow button is shown.
SHOW_RIGHT_ARROW_BUTTON,
// Both buttons are shown.
SHOW_BUTTONS
};
// |anchor| is the overflow button on the main shelf. |shelf_view| is the
// ShelfView containing the overflow items.
OverflowBubbleView(ShelfView* shelf_view,
......@@ -36,7 +51,10 @@ class ASH_EXPORT OverflowBubbleView : public ShelfBubble {
gfx::Rect GetBubbleBounds() override;
bool CanActivate() const override;
ShelfView* shelf_view() { return shelf_view_; }
ShelfView* shelf_view() { return shelf_container_view_->shelf_view(); }
View* left_arrow() { return left_arrow_; }
View* right_arrow() { return right_arrow_; }
LayoutStrategy layout_strategy() { return layout_strategy_; }
// ShelfBubble:
bool ShouldCloseOnPressDown() override;
......@@ -45,6 +63,56 @@ class ASH_EXPORT OverflowBubbleView : public ShelfBubble {
private:
friend class OverflowBubbleViewTestAPI;
class ScrollArrowView : public views::View {
public:
enum ArrowType { LEFT, RIGHT };
ScrollArrowView(ArrowType arrow_type, bool is_horizontal_alignment);
~ScrollArrowView() override = default;
// Overridden from views::View:
void OnPaint(gfx::Canvas* canvas) override;
const char* GetClassName() const override;
private:
ArrowType arrow_type_;
bool is_horizontal_alignment_;
};
class OverflowShelfContainerView : public views::View {
public:
explicit OverflowShelfContainerView(ShelfView* shelf_view);
~OverflowShelfContainerView() override = default;
void Initialize();
// Translate |shelf_view_| by |offset|.
void TranslateShelfView(const gfx::Vector2d& offset);
// views::View:
gfx::Size CalculatePreferredSize() const override;
void ChildPreferredSizeChanged(views::View* child) override;
void Layout() override;
const char* GetClassName() const override;
ShelfView* shelf_view() { return shelf_view_; }
private:
ShelfView* shelf_view_;
};
// Returns the maximum scroll distance.
int CalculateScrollUpperBound() const;
// Updates the overflow bubble view's layout strategy after scrolling by the
// distance of |scroll|. Returns the adapted scroll offset.
int CalculateLayoutStrategyAfterScroll(int scroll);
// Ensures that the width of |bubble_bounds| (if it is not horizontally
// aligned, adjust |bubble_bounds|'s height) is the multiple of the sum
// between kShelfButtonSize and kShelfButtonSpacing. It helps that all of
// shelf icons are fully visible.
void AdjustToEnsureIconsFullyVisible(gfx::Rect* bubble_bounds) const;
// views::View:
gfx::Size CalculatePreferredSize() const override;
void Layout() override;
......@@ -55,8 +123,14 @@ class ASH_EXPORT OverflowBubbleView : public ShelfBubble {
// ui::EventHandler:
void OnScrollEvent(ui::ScrollEvent* event) override;
mutable LayoutStrategy layout_strategy_;
// Child views Owned by views hierarchy.
ScrollArrowView* left_arrow_ = nullptr;
ScrollArrowView* right_arrow_ = nullptr;
OverflowShelfContainerView* shelf_container_view_ = nullptr;
Shelf* shelf_;
ShelfView* shelf_view_; // Owned by views hierarchy.
gfx::Vector2d scroll_offset_;
DISALLOW_COPY_AND_ASSIGN(OverflowBubbleView);
......
......@@ -16,7 +16,7 @@ OverflowBubbleViewTestAPI::OverflowBubbleViewTestAPI(
OverflowBubbleViewTestAPI::~OverflowBubbleViewTestAPI() = default;
gfx::Size OverflowBubbleViewTestAPI::GetContentsSize() {
return bubble_view_->shelf_view_->GetPreferredSize();
return bubble_view_->shelf_view()->GetPreferredSize();
}
void OverflowBubbleViewTestAPI::ScrollByXOffset(int x_offset) {
......
......@@ -1654,12 +1654,13 @@ TEST_F(ShelfViewTest, CheckDragInsertBoundsOfScrolledOverflowBubble) {
ASSERT_TRUE(shelf_view_->IsShowingOverflowBubble());
ShelfViewTestAPI test_for_overflow_view(
test_api_->overflow_bubble()->bubble_view()->shelf_view());
ShelfViewTestAPI test_for_overflow_view(bubble_view->shelf_view());
const ShelfView* overflow_shelf_view = shelf_view_->overflow_shelf();
int first_index = overflow_shelf_view->first_visible_index();
int last_index = overflow_shelf_view->last_visible_index();
views::View* left_arrow_button = bubble_view->left_arrow();
views::View* right_arrow_button = bubble_view->right_arrow();
ShelfAppButton* first_button = test_for_overflow_view.GetButton(first_index);
ShelfAppButton* last_button = test_for_overflow_view.GetButton(last_index);
gfx::Point first_point = first_button->GetBoundsInScreen().CenterPoint();
......@@ -1669,6 +1670,20 @@ TEST_F(ShelfViewTest, CheckDragInsertBoundsOfScrolledOverflowBubble) {
EXPECT_TRUE(drag_reinsert_bounds.Contains(first_point));
EXPECT_FALSE(drag_reinsert_bounds.Contains(last_point));
// Verfies that at the beginning, the left button is invisible while the right
// button shows.
EXPECT_EQ(OverflowBubbleView::SHOW_RIGHT_ARROW_BUTTON,
bubble_view->layout_strategy());
EXPECT_FALSE(left_arrow_button->GetVisible());
EXPECT_TRUE(right_arrow_button->GetVisible());
// Scroll the overflow shelf view a little bit. Then verifies that both arrow
// buttons show.
bubble_view_api.ScrollByXOffset(item_width);
EXPECT_EQ(OverflowBubbleView::SHOW_BUTTONS, bubble_view->layout_strategy());
EXPECT_TRUE(left_arrow_button->GetVisible());
EXPECT_TRUE(right_arrow_button->GetVisible());
// Scroll sufficiently to completely show last item.
bubble_view_api.ScrollByXOffset(bubble_view_api.GetContentsSize().width() -
bubble_view->GetContentsBounds().width());
......@@ -1678,6 +1693,13 @@ TEST_F(ShelfViewTest, CheckDragInsertBoundsOfScrolledOverflowBubble) {
last_point = last_button->GetBoundsInScreen().CenterPoint();
EXPECT_FALSE(drag_reinsert_bounds.Contains(first_point));
EXPECT_TRUE(drag_reinsert_bounds.Contains(last_point));
// Verifies that when the last item shows, the right arrow button is invisible
// while the left one shows.
EXPECT_EQ(OverflowBubbleView::SHOW_LEFT_ARROW_BUTTON,
bubble_view->layout_strategy());
EXPECT_TRUE(left_arrow_button->GetVisible());
EXPECT_FALSE(right_arrow_button->GetVisible());
}
// Check the drag insertion bounds of shelf view in multi monitor environment.
......
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