Parent directory

Hy3Node.hpp

4515 bytes
  1#pragma once
  2
  3struct Hy3Node;
  4struct Hy3TargetNode;
  5struct Hy3GroupNode;
  6struct Hy3RootNode;
  7enum class Hy3GroupLayout;
  8
  9#include <generator>
 10
 11#include <hyprland/src/defines.hpp>
 12#include <hyprland/src/desktop/view/window/Window.hpp>
 13#include <hyprland/src/layout/target/Target.hpp>
 14
 15#include "Hy3Layout.hpp"
 16#include "TabGroup.hpp"
 17
 18enum class Hy3GroupLayout {
 19	Root,
 20	SplitH,
 21	SplitV,
 22	Tabbed,
 23};
 24
 25enum class Hy3NodeType {
 26	Target,
 27	Group,
 28};
 29
 30enum class ExpandFocusType {
 31	NotExpanded,
 32	Latch,
 33	Stack,
 34};
 35
 36enum class Ephemeral {
 37	Off,
 38	Staged,
 39	Active,
 40};
 41
 42enum class CollapsePolicy {
 43	InvalidOnly,
 44	EmptySplits,
 45	SingleNodeGroups,
 46};
 47
 48struct Hy3Node {
 49	WP<Hy3Node> parent;
 50	WP<Hy3Node> self; // set from owning UP at creation time
 51	CBox logicalBox;
 52	CBox visualBox;
 53	float size_ratio = 1.0;
 54	bool hidden = false;
 55
 56	virtual ~Hy3Node() = default;
 57	Hy3Node(const Hy3Node&) = delete;
 58	Hy3Node& operator=(const Hy3Node&) = delete;
 59
 60	template<typename T> bool is() const { return dynamic_cast<const T*>(this) != nullptr; }
 61	template<typename T> T& as() { return dynamic_cast<T&>(*this); }
 62	template<typename T> const T& as() const { return dynamic_cast<const T&>(*this); }
 63
 64	bool valid() const;
 65	Hy3NodeType type() const;
 66	bool is_target() const;
 67	bool is_group() const;
 68	Hy3GroupNode& as_group();
 69	SP<Layout::ITarget> as_target();
 70	PHLWINDOW as_window();
 71
 72	bool operator==(const Hy3Node&) const;
 73	bool is_root();
 74	bool is_root_group();
 75	void assertNotRoot();
 76	Hy3RootNode* root();
 77	Hy3Layout* layout();
 78
 79	static UP<Hy3Node> create(SP<Layout::ITarget> target);
 80	static UP<Hy3Node> create(Hy3GroupLayout group_layout);
 81
 82	void focus(bool warp, Desktop::eFocusReason reason);
 83	void markFocused();
 84	Hy3Node& getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
 85	Hy3Node* findNeighbor(ShiftDirection);
 86	Hy3Node* getImmediateSibling(ShiftDirection);
 87	void resize(ShiftDirection, double, bool no_animation = false);
 88	bool isIndirectlyFocused();
 89	Hy3Node& getExpandActor();
 90	Hy3Node& getPlacementActor();
 91
 92	void recalcSizePosRecursive(CBox offsets, bool no_animation = false);
 93	void updateTabBar(bool no_animation = false);
 94	void updateTabBarRecursive();
 95	void updateDecos();
 96
 97	std::string getTitle();
 98	bool isUrgent();
 99	void setHidden(bool);
100
101	Hy3Node* findNodeForTabGroup(Hy3TabGroup&);
102	std::generator<Hy3Node&> ancestors();
103	std::generator<Desktop::View::CWindow&> windows(bool visibleOnly = false);
104	std::string debugNode();
105
106	Hy3Node* collapseParents(CollapsePolicy policy);
107	UP<Hy3Node> extractAndMerge(
108	    Hy3Node& child,
109	    Hy3Node** out_parent = nullptr,
110	    CollapsePolicy policy = CollapsePolicy::EmptySplits
111	);
112
113	void insertAndMerge(
114	    std::list<UP<Hy3Node>>::iterator pos,
115	    UP<Hy3Node> child,
116	    CollapsePolicy policy = CollapsePolicy::EmptySplits
117	);
118	void insertAndMerge(UP<Hy3Node> child, CollapsePolicy policy = CollapsePolicy::EmptySplits);
119
120	void wrap(Hy3GroupLayout, GroupEphemeralityOption, bool change = true);
121
122protected:
123	Hy3Node() = default;
124};
125
126struct Hy3TargetNode : Hy3Node {
127	WP<Layout::ITarget> target;
128};
129
130struct Hy3GroupNode : Hy3Node {
131	Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
132	Hy3GroupLayout previous_nontab_layout = Hy3GroupLayout::SplitH;
133	std::list<UP<Hy3Node>> children;
134	bool group_focused = true;
135	Hy3Node* focused_child = nullptr; // non-owning observer, always valid while parent group lives
136	ExpandFocusType expand_focused = ExpandFocusType::NotExpanded;
137	Ephemeral ephemeral = Ephemeral::Off;
138	bool locked = false;
139	bool containment = false;
140	Hy3TabGroupWrapper tab_bar;
141
142	Hy3GroupNode(Hy3GroupLayout layout);
143	~Hy3GroupNode() override = default;
144
145	bool isSplit() const { return layout == Hy3GroupLayout::SplitH || layout == Hy3GroupLayout::SplitV; }
146	bool isTab() const { return layout == Hy3GroupLayout::Tabbed; }
147
148	bool hasChild(Hy3Node& child);
149	void collapseExpansions();
150	void setLayout(Hy3GroupLayout layout);
151	void setEphemeral(GroupEphemeralityOption ephemeral);
152
153	auto findChild(Hy3Node& child) -> std::list<UP<Hy3Node>>::iterator;
154	void insertChild(std::list<UP<Hy3Node>>::iterator pos, UP<Hy3Node> child);
155	void insertChild(UP<Hy3Node> child);
156	UP<Hy3Node> extractChildRaw(std::list<UP<Hy3Node>>::iterator it);
157	UP<Hy3Node> extractChildRaw(Hy3Node& child);
158	UP<Hy3Node> replaceChild(std::list<UP<Hy3Node>>::iterator it, UP<Hy3Node> replacement);
159	UP<Hy3Node> extractChild(Hy3Node& child);
160
161	friend struct Hy3Node;
162};
163
164struct Hy3RootNode : Hy3GroupNode {
165	Hy3Layout* algo = nullptr;
166	Hy3RootNode(Hy3Layout* layout);
167};