blob: c02ce31374479664e2eebcd497bbe4ceaccb3a9a [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/touch_selection/touch_selection_magnifier_aura.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
namespace ui {
namespace {
class TouchSelectionMagnifierAuraTest : public testing::Test {
public:
TouchSelectionMagnifierAuraTest()
: disable_animations_(ScopedAnimationDurationScaleMode::ZERO_DURATION) {}
TouchSelectionMagnifierAuraTest(const TouchSelectionMagnifierAuraTest&) =
delete;
TouchSelectionMagnifierAuraTest& operator=(
const TouchSelectionMagnifierAuraTest&) = delete;
~TouchSelectionMagnifierAuraTest() override = default;
private:
ScopedAnimationDurationScaleMode disable_animations_;
};
// Tests that the magnifier is horizontally centered above a vertical caret.
TEST_F(TouchSelectionMagnifierAuraTest, BoundsForVerticalCaret) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
magnifier_parent.SetBounds(gfx::Rect(500, 400));
// Show the magnifier at a vertical caret.
constexpr gfx::Point kCaretTop(300, 200);
constexpr gfx::Point kCaretBottom(300, 210);
magnifier.ShowFocusBound(&magnifier_parent, kCaretTop, kCaretBottom);
// Magnifier should be horizontally centered above the caret.
const gfx::Rect magnifier_bounds = magnifier.GetMagnifierBoundsForTesting();
EXPECT_EQ(magnifier_bounds.CenterPoint().x(), kCaretTop.x());
EXPECT_LT(magnifier_bounds.bottom(), kCaretBottom.y());
// Zoomed content bounds should be centered on the caret.
const gfx::Rect zoomed_contents_bounds =
magnifier.GetZoomedContentsBoundsForTesting();
EXPECT_EQ(zoomed_contents_bounds.CenterPoint().x(), kCaretTop.x());
EXPECT_EQ(zoomed_contents_bounds.CenterPoint().y(),
(kCaretTop.y() + kCaretBottom.y()) / 2);
}
// Tests that the magnifier bounds are updated as a caret moves.
TEST_F(TouchSelectionMagnifierAuraTest, BoundsUpdate) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
magnifier_parent.SetBounds(gfx::Rect(500, 400));
// Show the magnifier at a caret.
constexpr gfx::Point kCaretTop(300, 200);
constexpr gfx::Point kCaretBottom(300, 210);
magnifier.ShowFocusBound(&magnifier_parent, kCaretTop, kCaretBottom);
// Move and resize the caret.
constexpr gfx::Point kUpdatedCaretTop(310, 190);
constexpr gfx::Point kUpdatedCaretBottom(310, 220);
magnifier.ShowFocusBound(&magnifier_parent, kUpdatedCaretTop,
kUpdatedCaretBottom);
// Magnifier should be horizontally centered above the caret.
const gfx::Rect magnifier_bounds = magnifier.GetMagnifierBoundsForTesting();
EXPECT_EQ(magnifier_bounds.CenterPoint().x(), kUpdatedCaretTop.x());
EXPECT_LT(magnifier_bounds.bottom(), kUpdatedCaretBottom.y());
// Zoomed content bounds should be centered on the caret.
const gfx::Rect zoomed_contents_bounds =
magnifier.GetZoomedContentsBoundsForTesting();
EXPECT_EQ(zoomed_contents_bounds.CenterPoint().x(), kUpdatedCaretTop.x());
EXPECT_EQ(zoomed_contents_bounds.CenterPoint().y(),
(kUpdatedCaretTop.y() + kUpdatedCaretBottom.y()) / 2);
}
// Tests that the magnifier is adjusted to stay inside the parent layer when
// showing a caret close to the left edge of the parent.
TEST_F(TouchSelectionMagnifierAuraTest, StaysInsideParentLeftEdge) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
constexpr gfx::Rect kParentBounds(500, 400);
magnifier_parent.SetBounds(kParentBounds);
// Show the magnifier at a caret near the left edge of the parent.
magnifier.ShowFocusBound(&magnifier_parent, gfx::Point(10, 200),
gfx::Point(10, 210));
// Magnifier (and what's zoomed) should be contained in the parent bounds.
EXPECT_TRUE(kParentBounds.Contains(magnifier.GetMagnifierBoundsForTesting()));
EXPECT_TRUE(
kParentBounds.Contains(magnifier.GetZoomedContentsBoundsForTesting()));
}
// Tests that the magnifier is adjusted to stay inside the parent layer when
// showing a caret close to the right edge of the parent.
TEST_F(TouchSelectionMagnifierAuraTest, StaysInsideParentRightEdge) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
constexpr gfx::Rect kParentBounds(500, 400);
magnifier_parent.SetBounds(kParentBounds);
// Show the magnifier at a caret near the right edge of the parent.
magnifier.ShowFocusBound(&magnifier_parent, gfx::Point(495, 200),
gfx::Point(495, 210));
// Magnifier (and what's zoomed) should be contained in the parent bounds.
EXPECT_TRUE(kParentBounds.Contains(magnifier.GetMagnifierBoundsForTesting()));
EXPECT_TRUE(
kParentBounds.Contains(magnifier.GetZoomedContentsBoundsForTesting()));
}
// Tests that the magnifier is adjusted to stay inside the parent layer when
// showing a caret close to the top edge of the parent.
TEST_F(TouchSelectionMagnifierAuraTest, StaysInsideParentTopEdge) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
constexpr gfx::Rect kParentBounds(500, 400);
magnifier_parent.SetBounds(kParentBounds);
// Show the magnifier at a caret near the top edge of the parent.
magnifier.ShowFocusBound(&magnifier_parent, gfx::Point(200, 2),
gfx::Point(200, 12));
// Magnifier (and what's zoomed) should be contained in the parent bounds.
EXPECT_TRUE(kParentBounds.Contains(magnifier.GetMagnifierBoundsForTesting()));
EXPECT_TRUE(
kParentBounds.Contains(magnifier.GetZoomedContentsBoundsForTesting()));
}
// Tests that the magnifier remains the same size even at the edge of the
// parent layer.
TEST_F(TouchSelectionMagnifierAuraTest, Size) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
magnifier_parent.SetBounds(gfx::Rect(500, 400));
// Show magnifier.
magnifier.ShowFocusBound(&magnifier_parent, gfx::Point(300, 200),
gfx::Point(300, 210));
const gfx::Size magnifier_size =
magnifier.GetMagnifierBoundsForTesting().size();
const gfx::Size zoom_content_size =
magnifier.GetZoomedContentsBoundsForTesting().size();
// Move the caret near the edge of the parent container.
magnifier.ShowFocusBound(&magnifier_parent, gfx::Point(10, 3),
gfx::Point(10, 13));
// Magnifier should remain the same size.
EXPECT_EQ(magnifier.GetMagnifierBoundsForTesting().size(), magnifier_size);
EXPECT_EQ(magnifier.GetZoomedContentsBoundsForTesting().size(),
zoom_content_size);
}
// Tests that the magnifier can be reparented to a different layer if needed.
TEST_F(TouchSelectionMagnifierAuraTest, SwitchesParentLayer) {
TouchSelectionMagnifierAura magnifier;
Layer magnifier_parent;
magnifier_parent.SetBounds(gfx::Rect(500, 400));
magnifier.ShowFocusBound(&magnifier_parent, gfx::Point(10, 20),
gfx::Point(10, 30));
// Reparent the magnifier.
Layer new_parent;
new_parent.SetBounds(gfx::Rect(600, 400));
magnifier.ShowFocusBound(&new_parent, gfx::Point(200, 20),
gfx::Point(200, 30));
// Magnifier should have the updated parent.
EXPECT_EQ(magnifier.GetMagnifierParentForTesting(), &new_parent);
}
} // namespace
} // namespace ui