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};