Parent directory

TabGroup.hpp

4473 bytes
  1#pragma once
  2
  3#include <optional>
  4#include <utility>
  5#include "render/pass/PassElement.hpp"
  6class Hy3TabGroup;
  7class Hy3TabBar;
  8
  9#include <list>
 10#include <vector>
 11
 12#include <hyprland/src/plugins/PluginAPI.hpp>
 13#include <hyprland/src/render/Renderer.hpp>
 14#include <hyprland/src/render/Texture.hpp>
 15
 16struct Hy3TabGroupWrapper {
 17	UP<Hy3TabGroup> inner;
 18
 19	Hy3TabGroupWrapper();
 20	Hy3TabGroupWrapper(UP<Hy3TabGroup> tg);
 21	Hy3TabGroupWrapper(Hy3TabGroupWrapper&&);
 22	Hy3TabGroupWrapper& operator=(Hy3TabGroupWrapper&&);
 23	~Hy3TabGroupWrapper();
 24
 25	void release();
 26	Hy3TabGroupWrapper& operator=(UP<Hy3TabGroup> tg);
 27
 28	Hy3TabGroup* operator->() { return inner.get(); }
 29	Hy3TabGroup* get() { return inner.get(); }
 30	operator bool() const { return inner.get() != nullptr; }
 31};
 32
 33#include "Hy3Node.hpp"
 34
 35struct Hy3TabBarEntry {
 36	std::string window_title;
 37	bool destroying = false;
 38	SP<Render::ITexture> texture;
 39	PHLANIMVAR<float> active;
 40	PHLANIMVAR<float> focused;
 41	PHLANIMVAR<float> urgent;
 42	PHLANIMVAR<float> active_monitor;
 43	PHLANIMVAR<float> offset;       // 0.0-1.0 of total bar
 44	PHLANIMVAR<float> width;        // 0.0-1.0 of total bar
 45	PHLANIMVAR<float> vertical_pos; // 0.0-1.0, user specified direction
 46	PHLANIMVAR<float> fade_opacity; // 0.0-1.0
 47	Hy3TabBar& tab_bar;
 48	Hy3Node* node; // only used for comparison. do not deref.
 49	int lastIndex = -1;
 50
 51	struct {
 52		float scale = 0.0;
 53		std::string window_title;
 54		int full_logical_width = 0;
 55		float render_width = 0;
 56
 57		std::string text_font;
 58		int font_height = 0;
 59
 60		int texture_x_offset = 0;
 61		int texture_y_offset = 0;
 62		int texture_width = 0;
 63		int texture_height = 0;
 64
 65		int logical_width = 0;
 66		int logical_height = 0;
 67	} last_render;
 68
 69	Hy3TabBarEntry(Hy3TabBar&, Hy3Node&);
 70	bool operator==(const Hy3Node&) const;
 71	bool operator==(const Hy3TabBarEntry&) const;
 72
 73	void setActive(bool);
 74	void setFocused(bool);
 75	void setUrgent(bool);
 76	void setWindowTitle(std::string);
 77	void setMonitorActive(bool);
 78	void beginDestroy();
 79	void unDestroy();
 80	bool shouldRemove();
 81	void render(float scale, CBox& box, float opacity_mul);
 82
 83private:
 84	void renderText(float scale, CBox& box, float opacity);
 85	CHyprColor mergeColors(
 86	    const CHyprColor& active,
 87	    const CHyprColor& focused,
 88	    const CHyprColor& urgent,
 89	    const CHyprColor& locked,
 90	    const CHyprColor& inactiveMonitor,
 91	    const CHyprColor& inactive
 92	);
 93};
 94
 95class Hy3TabBar {
 96public:
 97	bool destroy = false;
 98	bool dirty = true;
 99	bool damaged = true;
100	PHLANIMVAR<float> fade_opacity;
101	PHLANIMVAR<float> locked;
102	// The monitor this bar resides on
103	MONITORID monitor_id = MONITOR_INVALID;
104
105	Hy3TabBar();
106	void beginDestroy();
107	void damageBox(const Vector2D* position, const Vector2D* size);
108
109	void tick();
110	void updateNodeList(std::list<UP<Hy3Node>>& nodes);
111	void updateAnimations(bool warp = false);
112	void setSize(Vector2D);
113
114	std::list<Hy3TabBarEntry> entries;
115
116private:
117	Vector2D size;
118
119	// Tab bar entries take a reference to `this`.
120	Hy3TabBar(Hy3TabBar&&) = delete;
121	Hy3TabBar(const Hy3TabBar&) = delete;
122};
123
124class Hy3TabPassElement: public IPassElement {
125public:
126	Hy3TabPassElement(Hy3TabGroup* group): group(group) {}
127
128	const char* passName() override { return "Hy3TabPassElement"; }
129	std::vector<UP<IPassElement>> draw() override;
130	bool needsLiveBlur() override { return false; }
131	ePassElementType type() override { return EK_CUSTOM; }
132	bool needsPrecomputeBlur() override;
133	std::optional<CBox> boundingBox() override;
134
135private:
136	Hy3TabGroup* group;
137};
138
139class Hy3TabGroup {
140public:
141	PHLWINDOW target_window = nullptr;
142	PHLWORKSPACE workspace = nullptr;
143	bool hidden = false;
144	Hy3TabBar bar;
145	PHLANIMVAR<Vector2D> pos;
146	PHLANIMVAR<Vector2D> size;
147	WP<Hy3TabGroup> self;
148
149	// Factory: creates a tab group, sets self WP, registers in g_tabGroups.
150	static UP<Hy3TabGroup> create(Hy3Node& node);
151
152	// initialize a group with the given node. UB if node is not a group.
153	Hy3TabGroup(Hy3Node&);
154
155	// update tab bar with node position and data. UB if node is not a group.
156	void updateWithGroup(Hy3Node&, bool warp);
157	void tick();
158	std::pair<CBox, CBox> getRenderBB() const;
159	// render the scaled tab bar on the current monitor.
160	void renderTabBar();
161
162private:
163	std::vector<PHLWINDOWREF> stencil_windows;
164	Vector2D last_workspace_offset;
165	Vector2D last_pos;
166	Vector2D last_size;
167
168	Hy3TabGroup();
169
170	// moving a Hy3TabGroup will unregister any active animations
171	Hy3TabGroup(Hy3TabGroup&&) = delete;
172
173	// UB if node is not a group.
174	void updateStencilWindows(Hy3Node&);
175};