/* * Copyright (c) 2024-2025, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include namespace Web::Painting { class ScrollStateSnapshot { public: static ScrollStateSnapshot create(Vector> const& scroll_frames); CSSPixelPoint cumulative_offset_for_frame_with_id(size_t id) const { if (id >= entries.size()) return {}; return entries[id].cumulative_offset; } CSSPixelPoint own_offset_for_frame_with_id(size_t id) const { if (id >= entries.size()) return {}; return entries[id].own_offset; } private: struct Entry { CSSPixelPoint cumulative_offset; CSSPixelPoint own_offset; }; Vector entries; }; class ScrollState { public: NonnullRefPtr create_scroll_frame_for(PaintableBox const& paintable_box, RefPtr parent) { auto scroll_frame = adopt_ref(*new ScrollFrame(paintable_box, m_scroll_frames.size(), false, move(parent))); m_scroll_frames.append(scroll_frame); return scroll_frame; } NonnullRefPtr create_sticky_frame_for(PaintableBox const& paintable_box, RefPtr parent) { auto scroll_frame = adopt_ref(*new ScrollFrame(paintable_box, m_scroll_frames.size(), true, move(parent))); m_scroll_frames.append(scroll_frame); return scroll_frame; } CSSPixelPoint cumulative_offset_for_frame_with_id(size_t id) const { return m_scroll_frames[id]->cumulative_offset(); } CSSPixelPoint own_offset_for_frame_with_id(size_t id) const { return m_scroll_frames[id]->own_offset(); } template void for_each_scroll_frame(Callback callback) const { for (auto const& scroll_frame : m_scroll_frames) { if (scroll_frame->is_sticky()) continue; callback(scroll_frame); } } template void for_each_sticky_frame(Callback callback) const { for (auto const& scroll_frame : m_scroll_frames) { if (!scroll_frame->is_sticky()) continue; callback(scroll_frame); } } ScrollStateSnapshot snapshot() const { return ScrollStateSnapshot::create(m_scroll_frames); } private: Vector> m_scroll_frames; }; }