#pragma once #include "../../TiledAlgorithm.hpp" #include "../../../../helpers/math/Direction.hpp" #include "ScrollTapeController.hpp" #include "../../../../helpers/signal/Signal.hpp" #include namespace Layout::Tiled { class CScrollingAlgorithm; struct SColumnData; struct SScrollingData; struct SScrollingTargetData { SScrollingTargetData(SP t, SP col) : target(t), column(col) { ; } WP target; WP column; bool ignoreFullscreenChecks = false; CBox layoutBox; }; struct SColumnData { SColumnData(SP data) : scrollingData(data) { ; } void add(SP t); void add(SP t, int after); void add(SP w); void add(SP w, int after); void remove(SP t); bool has(SP t); size_t idx(SP t); // index of lowest target that is above y. size_t idxForHeight(float y); bool up(SP w); bool down(SP w); SP next(SP w); SP prev(SP w); std::vector> targetDatas; WP scrollingData; WP lastFocusedTarget; WP self; // Helper methods to access controller-managed data float getColumnWidth() const; void setColumnWidth(float width); float getTargetSize(size_t idx) const; void setTargetSize(size_t idx, float size); float getTargetSize(SP target) const; void setTargetSize(SP target, float size); }; struct SScrollingData { SScrollingData(CScrollingAlgorithm* algo); std::vector> columns; UP controller; SP add(); SP add(int after); int64_t idx(SP c); void remove(SP c); double maxWidth(); SP next(SP c); SP prev(SP c); SP atCenter(); bool visible(SP c, bool full = false); void centerCol(SP c); void fitCol(SP c); void centerOrFitCol(SP c); void recalculate(bool forceInstant = false); CScrollingAlgorithm* algorithm = nullptr; WP self; std::optional lockedCameraOffset; }; class CScrollingAlgorithm : public ITiledAlgorithm { public: CScrollingAlgorithm(); virtual ~CScrollingAlgorithm(); virtual void newTarget(SP target); virtual void movedTarget(SP target, std::optional focalPoint = std::nullopt); virtual void removeTarget(SP target); virtual void resizeTarget(const Vector2D& Δ, SP target, eRectCorner corner = CORNER_NONE); virtual void recalculate(); virtual SP getNextCandidate(SP old); virtual std::expected layoutMsg(const std::string_view& sv); virtual std::optional predictSizeForNewTarget(); virtual void swapTargets(SP a, SP b); virtual void moveTargetInDirection(SP t, Math::eDirection dir, bool silent); CBox usableArea(); enum eInputMode : uint8_t { INPUT_MODE_SOFT = 0, INPUT_MODE_CLICK, INPUT_MODE_KB }; private: SP m_scrollingData; CHyprSignalListener m_configCallback; CHyprSignalListener m_focusCallback; CHyprSignalListener m_mouseButtonCallback; struct { std::vector configuredWidths; } m_config; eScrollDirection getDynamicDirection(); SP findBestNeighbor(SP pCurrent, SP pTargetCol); SP dataFor(SP t); SP closestNode(const Vector2D& posGlobglobgabgalab); void focusTargetUpdate(SP target); void moveTargetTo(SP t, Math::eDirection dir, bool silent); void focusOnInput(SP target, eInputMode input); float defaultColumnWidth(); friend struct SScrollingData; }; };