#pragma once #include "../../TiledAlgorithm.hpp" #include "../../../../helpers/math/Direction.hpp" #include "ScrollTapeController.hpp" #include "../../../../helpers/signal/Signal.hpp" #include #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(std::optional width = std::nullopt); SP add(int after, std::optional width = std::nullopt); 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(eRecalculateReason reason = RECALCULATE_REASON_UNKNOWN); virtual SP getNextCandidate(SP old); virtual Config::ErrorResult 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); virtual eFullscreenRequestResult requestFullscreen(const SFullscreenRequest& request); virtual SP layoutFullscreenTarget() const; virtual bool layoutFullscreenCoversMonitor() const; void moveTape(float delta); void moveTapeNormalized(double delta); void snapToGrid(); SP snapToProjectedOffset(double projectedNormalizedOffset); void focusColumn(SP column); SP getColumnAtViewportCenter(); SP currentColumn(); double primaryViewportSize(); double normalizedTapeOffset(); CBox usableArea() const; SP dataFor(SP t) const; enum eInputMode : uint8_t { INPUT_MODE_SOFT = 0, INPUT_MODE_CLICK, INPUT_MODE_HARD }; private: SP m_scrollingData; CHyprSignalListener m_configCallback; CHyprSignalListener m_focusCallback; CHyprSignalListener m_mouseButtonCallback; struct { std::vector configuredWidths; } m_config; eScrollDirection getDynamicDirection(); struct SFullscreenScrollState { WP target; std::optional restoreColumnWidth; }; void syncFullscreenTargets(); SFullscreenScrollState* fullscreenStateForTarget(SP target); SFullscreenScrollState* fullscreenStateForData(SP target); SP fullscreenTargetDataForColumn(SP col) const; bool isFullscreenTarget(SP target) const; float fullscreenColumnWidth() const; bool fullscreenColumnCoversMonitor(SP col) const; void updateFullscreenFade(bool coversMonitor); void clearFullscreenTarget(SP target = nullptr); SP findBestNeighbor(SP pCurrent, SP pTargetCol); SP closestNode(const Vector2D& posGlobglobgabgalab); void focusTargetUpdate(SP target); void moveTargetTo(SP t, Math::eDirection dir, bool silent); void focusOnInput(SP target, eInputMode input); void expelTarget(SP tdata, SP srcCol, std::optional insertIdx); float defaultColumnWidth(); std::vector m_fullscreenTargets; bool m_lastFullscreenCover = false; friend struct SScrollingData; }; };