Repository navigation
Expand file tree
/
Copy pathDropIndicator.cpp
More file actions
142 lines (107 loc) · 5.44 KB
/
Copy pathDropIndicator.cpp
File metadata and controls
142 lines (107 loc) · 5.44 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "DropIndicator.hpp"
#include <algorithm>
#include <cmath>
#include <sstream>
#define private public
#include <hyprland/src/desktop/view/Window.hpp>
#include <hyprland/src/layout/algorithm/Algorithm.hpp>
#include <hyprland/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp>
#include <hyprland/src/render/Renderer.hpp>
#include <hyprland/src/render/pass/RectPassElement.hpp>
#undef private
namespace {
static constexpr float INDICATOR_BASE_SIZE_PX = 200.F;
static constexpr float INDICATOR_ALPHA = 0.3F;
static CHyprColor indicatorColor() {
auto* const ACTIVEBORDER = sc<Config::CGradientValueData*>(ScrollOverview::Config::valueRef<Config::IComplexConfigValue>("general:col.active_border").ptr());
if (!ACTIVEBORDER || ACTIVEBORDER->m_colors.empty())
return Colors::WHITE.modifyA(INDICATOR_ALPHA);
return ACTIVEBORDER->m_colors[0].modifyA(INDICATOR_ALPHA);
}
static bool isHorizontalSide(const std::string& side) {
return side == "l" || side == "r";
}
static bool isVerticalSide(const std::string& side) {
return side == "u" || side == "d";
}
static Layout::Tiled::CScrollingAlgorithm* scrollingAlgorithmForWorkspace(const PHLWORKSPACE& workspace) {
if (!workspace || !workspace->m_space || !workspace->m_space->algorithm())
return nullptr;
return dc<Layout::Tiled::CScrollingAlgorithm*>(workspace->m_space->algorithm()->m_tiled.get());
}
static bool scrollingPrimaryHorizontal(const PHLWORKSPACE& workspace) {
const auto ALGO = scrollingAlgorithmForWorkspace(workspace);
if (!ALGO || !ALGO->m_scrollingData || !ALGO->m_scrollingData->controller)
return true;
return ALGO->m_scrollingData->controller->isPrimaryHorizontal();
}
static CBox scrollingIndicatorBox(const CDropIndicator::SRenderParams& params) {
if (!params.anchor.window)
return params.workspaceUsableBox;
const bool HORIZONTALSIDE = isHorizontalSide(params.anchor.direction);
const bool PRIMARYHORIZONTAL = scrollingPrimaryHorizontal(params.workspace);
const float MONITOR_SCALE = std::max<float>(params.monitor ? params.monitor->m_scale : 1.F, 0.01F);
const float SIZE = INDICATOR_BASE_SIZE_PX * std::max(params.renderScale, 0.01F) * MONITOR_SCALE;
const auto& EDGEBOX = params.anchor.logicalBox.empty() ? params.anchor.box : params.anchor.logicalBox;
CBox box;
if (HORIZONTALSIDE) {
const float CENTERX = params.anchor.direction == "l" ? EDGEBOX.x : EDGEBOX.x + EDGEBOX.width;
box.width = SIZE;
box.height = PRIMARYHORIZONTAL ? params.workspaceUsableBox.height : params.anchor.box.height;
box.x = CENTERX - SIZE / 2.F;
box.y = PRIMARYHORIZONTAL ? params.workspaceUsableBox.y : params.anchor.box.y;
} else {
const float CENTERY = params.anchor.direction == "u" ? EDGEBOX.y : EDGEBOX.y + EDGEBOX.height;
box.width = PRIMARYHORIZONTAL ? params.anchor.box.width : params.workspaceUsableBox.width;
box.height = SIZE;
box.x = PRIMARYHORIZONTAL ? params.anchor.box.x : params.workspaceUsableBox.x;
box.y = CENTERY - SIZE / 2.F;
}
box.round();
return box;
}
static CBox indicatorBox(const CDropIndicator::SRenderParams& params) {
if (!params.anchor.window)
return params.workspaceUsableBox;
if (params.anchor.direction.empty())
return params.anchor.box;
if (!scrollingAlgorithmForWorkspace(params.workspace))
return params.anchor.box;
return scrollingIndicatorBox(params);
}
static CBox clipScrollingIndicatorBox(CBox box, const CDropIndicator::SRenderParams& params) {
if (!scrollingAlgorithmForWorkspace(params.workspace))
return box;
const bool PRIMARYHORIZONTAL = scrollingPrimaryHorizontal(params.workspace);
if (PRIMARYHORIZONTAL)
return box.intersection({{box.x, params.workspaceUsableBox.y}, {box.width, params.workspaceUsableBox.height}});
return box.intersection({{params.workspaceUsableBox.x, box.y}, {params.workspaceUsableBox.width, box.height}});
}
static int indicatorRounding(const CDropIndicator::SRenderParams& params) {
const float ROUNDING = params.anchor.window ? params.anchor.window->rounding() : ScrollOverview::Config::getValue<int>("decoration:rounding");
const float SCALE = std::max(params.renderScale, 0.01F) * std::max<float>(params.monitor ? params.monitor->m_scale : 1.F, 0.01F);
return std::max(0, sc<int>(std::round(ROUNDING * SCALE)));
}
static float indicatorRoundingPower(const CDropIndicator::SRenderParams& params) {
if (params.anchor.window)
return params.anchor.window->roundingPower();
return ScrollOverview::Config::getValue<float>("decoration:rounding_power");
}
}
void CDropIndicator::renderDropIndicator(const SRenderParams& params) {
if (!params.monitor || !params.workspace)
return;
if (!params.anchor.window && params.floating && params.workspaceFullyVisible)
return;
if (params.anchor.window && !params.anchor.direction.empty() && !isHorizontalSide(params.anchor.direction) && !isVerticalSide(params.anchor.direction))
return;
const auto BOX = clipScrollingIndicatorBox(indicatorBox(params), params);
if (BOX.empty())
return;
CRectPassElement::SRectData data;
data.box = BOX;
data.color = indicatorColor();
data.round = indicatorRounding(params);
data.roundingPower = indicatorRoundingPower(params);
g_pHyprRenderer->m_renderPass.add(makeUnique<CRectPassElement>(data));
}