blob: 31b00d8ed151a8b16365ef2826745701240d0d3d [file] [log] [blame]
// Copyright 2017 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/scroll_snap_data.h"
namespace cc {
SnapContainerData::SnapContainerData() = default;
SnapContainerData::SnapContainerData(ScrollSnapType type)
: scroll_snap_type_(type) {}
SnapContainerData::SnapContainerData(ScrollSnapType type, gfx::ScrollOffset max)
: scroll_snap_type_(type), max_position_(max) {}
SnapContainerData::SnapContainerData(const SnapContainerData& other) = default;
SnapContainerData::SnapContainerData(SnapContainerData&& other)
: scroll_snap_type_(other.scroll_snap_type_),
max_position_(other.max_position_),
snap_area_list_(std::move(other.snap_area_list_)) {}
SnapContainerData::~SnapContainerData() = default;
SnapContainerData& SnapContainerData::operator=(
const SnapContainerData& other) = default;
SnapContainerData& SnapContainerData::operator=(SnapContainerData&& other) {
scroll_snap_type_ = other.scroll_snap_type_;
max_position_ = other.max_position_;
snap_area_list_ = std::move(other.snap_area_list_);
return *this;
}
void SnapContainerData::AddSnapAreaData(SnapAreaData snap_area_data) {
snap_area_list_.push_back(snap_area_data);
}
gfx::ScrollOffset SnapContainerData::FindSnapPosition(
const gfx::ScrollOffset& current_position,
bool should_snap_on_x,
bool should_snap_on_y) const {
SnapAxis axis = scroll_snap_type_.axis;
should_snap_on_x &= (axis == SnapAxis::kX || axis == SnapAxis::kBoth);
should_snap_on_y &= (axis == SnapAxis::kY || axis == SnapAxis::kBoth);
if (!should_snap_on_x && !should_snap_on_y)
return current_position;
float smallest_distance_x = std::numeric_limits<float>::max();
float smallest_distance_y = std::numeric_limits<float>::max();
gfx::ScrollOffset snap_position = current_position;
for (const SnapAreaData& snap_area_data : snap_area_list_) {
// TODO(sunyunjia): We should consider visiblity when choosing snap offset.
if (should_snap_on_x && (snap_area_data.snap_axis == SnapAxis::kX ||
snap_area_data.snap_axis == SnapAxis::kBoth)) {
float offset = snap_area_data.snap_position.x();
if (offset == SnapAreaData::kInvalidScrollPosition)
continue;
float distance = std::abs(current_position.x() - offset);
if (distance < smallest_distance_x) {
smallest_distance_x = distance;
snap_position.set_x(offset);
}
}
if (should_snap_on_y && (snap_area_data.snap_axis == SnapAxis::kY ||
snap_area_data.snap_axis == SnapAxis::kBoth)) {
float offset = snap_area_data.snap_position.y();
if (offset == SnapAreaData::kInvalidScrollPosition)
continue;
float distance = std::abs(current_position.y() - offset);
if (distance < smallest_distance_y) {
smallest_distance_y = distance;
snap_position.set_y(offset);
}
}
}
return snap_position;
}
std::ostream& operator<<(std::ostream& ostream, const SnapAreaData& area_data) {
return ostream << area_data.snap_position.x() << ", "
<< area_data.snap_position.y();
}
std::ostream& operator<<(std::ostream& ostream,
const SnapContainerData& container_data) {
for (size_t i = 0; i < container_data.size(); ++i) {
ostream << container_data.at(i) << "\n";
}
return ostream;
}
} // namespace cc