123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- // Copyright 2018 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 "cc/input/snap_selection_strategy.h"
- #include <cmath>
- namespace cc {
- std::unique_ptr<SnapSelectionStrategy>
- SnapSelectionStrategy::CreateForEndPosition(
- const gfx::PointF& current_position,
- bool scrolled_x,
- bool scrolled_y,
- SnapTargetsPrioritization prioritization) {
- return std::make_unique<EndPositionStrategy>(current_position, scrolled_x,
- scrolled_y, prioritization);
- }
- std::unique_ptr<SnapSelectionStrategy>
- SnapSelectionStrategy::CreateForDirection(gfx::PointF current_position,
- gfx::Vector2dF step,
- bool use_fractional_offsets,
- SnapStopAlwaysFilter filter) {
- return std::make_unique<DirectionStrategy>(current_position, step, filter,
- use_fractional_offsets);
- }
- std::unique_ptr<SnapSelectionStrategy>
- SnapSelectionStrategy::CreateForEndAndDirection(gfx::PointF current_position,
- gfx::Vector2dF displacement,
- bool use_fractional_offsets) {
- return std::make_unique<EndAndDirectionStrategy>(
- current_position, displacement, use_fractional_offsets);
- }
- std::unique_ptr<SnapSelectionStrategy>
- SnapSelectionStrategy::CreateForTargetElement(gfx::PointF current_position) {
- return std::make_unique<EndPositionStrategy>(
- current_position, true /* scrolled_x */, true /* scrolled_y */,
- SnapTargetsPrioritization::kRequire);
- }
- bool SnapSelectionStrategy::HasIntendedDirection() const {
- return true;
- }
- bool SnapSelectionStrategy::ShouldRespectSnapStop() const {
- return false;
- }
- bool SnapSelectionStrategy::IsValidSnapArea(SearchAxis axis,
- const SnapAreaData& area) const {
- return axis == SearchAxis::kX
- ? area.scroll_snap_align.alignment_inline != SnapAlignment::kNone
- : area.scroll_snap_align.alignment_block != SnapAlignment::kNone;
- }
- bool SnapSelectionStrategy::ShouldPrioritizeSnapTargets() const {
- return false;
- }
- bool SnapSelectionStrategy::UsingFractionalOffsets() const {
- return false;
- }
- bool EndPositionStrategy::ShouldSnapOnX() const {
- return scrolled_x_;
- }
- bool EndPositionStrategy::ShouldSnapOnY() const {
- return scrolled_y_;
- }
- gfx::PointF EndPositionStrategy::intended_position() const {
- return current_position_;
- }
- gfx::PointF EndPositionStrategy::base_position() const {
- return current_position_;
- }
- // |position| is unused in this method.
- bool EndPositionStrategy::IsValidSnapPosition(SearchAxis axis,
- float position) const {
- return (scrolled_x_ && axis == SearchAxis::kX) ||
- (scrolled_y_ && axis == SearchAxis::kY);
- }
- bool EndPositionStrategy::HasIntendedDirection() const {
- return false;
- }
- bool EndPositionStrategy::ShouldPrioritizeSnapTargets() const {
- return snap_targets_prioritization_ == SnapTargetsPrioritization::kRequire;
- }
- const absl::optional<SnapSearchResult>& EndPositionStrategy::PickBestResult(
- const absl::optional<SnapSearchResult>& closest,
- const absl::optional<SnapSearchResult>& covering) const {
- return covering.has_value() ? covering : closest;
- }
- bool DirectionStrategy::ShouldSnapOnX() const {
- return step_.x() != 0;
- }
- bool DirectionStrategy::ShouldSnapOnY() const {
- return step_.y() != 0;
- }
- gfx::PointF DirectionStrategy::intended_position() const {
- return current_position_ + step_;
- }
- gfx::PointF DirectionStrategy::base_position() const {
- return current_position_;
- }
- bool DirectionStrategy::IsValidSnapPosition(SearchAxis axis,
- float position) const {
- // If not using fractional offsets then it is possible for the currently
- // snapped area's offset, which is fractional, to not be equal to the current
- // scroll offset, which is not fractional. Therefore we truncate the offsets
- // so that any position within 1 of the current position is ignored.
- if (axis == SearchAxis::kX) {
- float delta = position - current_position_.x();
- if (!use_fractional_offsets_)
- delta = delta > 0 ? std::floor(delta) : std::ceil(delta);
- return (step_.x() > 0 && delta > 0) || // "Right" arrow
- (step_.x() < 0 && delta < 0); // "Left" arrow
- } else {
- float delta = position - current_position_.y();
- if (!use_fractional_offsets_)
- delta = delta > 0 ? std::floor(delta) : std::ceil(delta);
- return (step_.y() > 0 && delta > 0) || // "Down" arrow
- (step_.y() < 0 && delta < 0); // "Up" arrow
- }
- }
- bool DirectionStrategy::IsValidSnapArea(SearchAxis axis,
- const SnapAreaData& area) const {
- return SnapSelectionStrategy::IsValidSnapArea(axis, area) &&
- (snap_stop_always_filter_ == SnapStopAlwaysFilter::kIgnore ||
- area.must_snap);
- }
- const absl::optional<SnapSearchResult>& DirectionStrategy::PickBestResult(
- const absl::optional<SnapSearchResult>& closest,
- const absl::optional<SnapSearchResult>& covering) const {
- // We choose the |closest| result only if the default landing position (using
- // the default step) is not a valid snap position (not making a snap area
- // covering the snapport), or the |closest| is closer than the default landing
- // position.
- if (!closest.has_value())
- return covering;
- if (!covering.has_value())
- return closest;
- // "Right" or "Down" arrow.
- if ((step_.x() > 0 || step_.y() > 0) &&
- closest.value().snap_offset() < covering.value().snap_offset()) {
- return closest;
- }
- // "Left" or "Up" arrow.
- if ((step_.x() < 0 || step_.y() < 0) &&
- closest.value().snap_offset() > covering.value().snap_offset()) {
- return closest;
- }
- return covering;
- }
- bool DirectionStrategy::UsingFractionalOffsets() const {
- return use_fractional_offsets_;
- }
- bool EndAndDirectionStrategy::ShouldSnapOnX() const {
- return displacement_.x() != 0;
- }
- bool EndAndDirectionStrategy::ShouldSnapOnY() const {
- return displacement_.y() != 0;
- }
- gfx::PointF EndAndDirectionStrategy::intended_position() const {
- return current_position_ + displacement_;
- }
- gfx::PointF EndAndDirectionStrategy::base_position() const {
- return current_position_ + displacement_;
- }
- bool EndAndDirectionStrategy::IsValidSnapPosition(SearchAxis axis,
- float position) const {
- // If not using fractional offsets then it is possible for the currently
- // snapped area's offset, which is fractional, to not be equal to the current
- // scroll offset, which is not fractional. Therefore we round the offsets so
- // that any position within 0.5 of the current position is ignored.
- if (axis == SearchAxis::kX) {
- float delta = position - current_position_.x();
- if (!use_fractional_offsets_)
- delta = std::round(delta);
- return (displacement_.x() > 0 && delta > 0) || // Right
- (displacement_.x() < 0 && delta < 0); // Left
- } else {
- float delta = position - current_position_.y();
- if (!use_fractional_offsets_)
- delta = std::round(delta);
- return (displacement_.y() > 0 && delta > 0) || // Down
- (displacement_.y() < 0 && delta < 0); // Up
- }
- }
- bool EndAndDirectionStrategy::ShouldRespectSnapStop() const {
- return true;
- }
- const absl::optional<SnapSearchResult>& EndAndDirectionStrategy::PickBestResult(
- const absl::optional<SnapSearchResult>& closest,
- const absl::optional<SnapSearchResult>& covering) const {
- return covering.has_value() ? covering : closest;
- }
- bool EndAndDirectionStrategy::UsingFractionalOffsets() const {
- return use_fractional_offsets_;
- }
- } // namespace cc
|