summaryrefslogtreecommitdiff
path: root/src/layout/LayoutManager.hpp
blob: 2660cf289b60594ce8fd30a672270fac41731a50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#pragma once

#include "../helpers/memory/Memory.hpp"
#include "../helpers/math/Math.hpp"
#include "../managers/input/InputManager.hpp"
#include "../config/shared/ConfigErrors.hpp"

#include "supplementary/DragController.hpp"

#include <optional>
#include <expected>

enum eFullscreenMode : int8_t;

namespace Layout {
    class ITarget;
    class CSpace;

    enum eRectCorner : uint8_t {
        CORNER_NONE        = 0,
        CORNER_TOPLEFT     = (1 << 0),
        CORNER_TOPRIGHT    = (1 << 1),
        CORNER_BOTTOMRIGHT = (1 << 2),
        CORNER_BOTTOMLEFT  = (1 << 3),
    };

    inline eRectCorner cornerFromBox(const CBox& box, const Vector2D& pos) {
        const auto CENTER = box.middle();

        if (pos.x < CENTER.x)
            return pos.y < CENTER.y ? CORNER_TOPLEFT : CORNER_BOTTOMLEFT;
        return pos.y < CENTER.y ? CORNER_TOPRIGHT : CORNER_BOTTOMRIGHT;
    }

    enum eSnapEdge : uint8_t {
        SNAP_INVALID = 0,
        SNAP_UP      = (1 << 0),
        SNAP_DOWN    = (1 << 1),
        SNAP_LEFT    = (1 << 2),
        SNAP_RIGHT   = (1 << 3),
    };

    class CLayoutManager {
      public:
        CLayoutManager();
        ~CLayoutManager() = default;

        void                    newTarget(SP<ITarget> target, SP<CSpace> space);
        void                    removeTarget(SP<ITarget> target);

        void                    changeFloatingMode(SP<ITarget> target);

        void                    beginDragTarget(SP<ITarget> target, eMouseBindMode mode);
        void                    moveMouse(const Vector2D& mousePos);
        void                    resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
        void                    moveTarget(const Vector2D& Δ, SP<ITarget> target);
        void                    setTargetGeom(const CBox& box, SP<ITarget> target); // floats only
        void                    endDragTarget();

        Config::ErrorResult     layoutMsg(const std::string_view& sv);

        void                    fullscreenRequestForTarget(SP<ITarget> target, eFullscreenMode currentEffectiveMode, eFullscreenMode effectiveMode);

        void                    switchTargets(SP<ITarget> a, SP<ITarget> b, bool preserveFocus = true);

        void                    moveInDirection(SP<ITarget> target, const std::string& direction, bool silent = false);

        SP<ITarget>             getNextCandidate(SP<CSpace> space, SP<ITarget> from);

        bool                    isReachable(SP<ITarget> target);

        void                    bringTargetToTop(SP<ITarget> target);

        std::optional<Vector2D> predictSizeForNewTiledTarget();

        void                    performSnap(Vector2D& sourcePos, Vector2D& sourceSize, SP<ITarget> target, eMouseBindMode mode, int corner, const Vector2D& beginSize);

        void                    invalidateMonitorGeometries(PHLMONITOR);
        void                    recalculateMonitor(PHLMONITOR);

        const UP<Supplementary::CDragStateController>& dragController();

      private:
        UP<Supplementary::CDragStateController> m_dragStateController = makeUnique<Supplementary::CDragStateController>();
    };
}

inline UP<Layout::CLayoutManager> g_layoutManager;