INSTINCT Code Coverage Report


Directory: src/
File: internal/gui/panels/BlueprintNodeBuilder.cpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 0 165 0.0%
Functions: 0 13 0.0%
Branches: 0 97 0.0%

Line Branch Exec Source
1 //------------------------------------------------------------------------------
2 // LICENSE
3 // This software is dual-licensed to the public domain and under the following
4 // license: you are granted a perpetual, irrevocable license to copy, modify,
5 // publish, and distribute this file as you see fit.
6 //
7 // CREDITS
8 // Written by Michal Cichon
9 //------------------------------------------------------------------------------
10 #include "BlueprintNodeBuilder.hpp"
11 #include <imgui_internal.h>
12
13 //------------------------------------------------------------------------------
14
15 ax::NodeEditor::Utilities::BlueprintNodeBuilder::BlueprintNodeBuilder(ImTextureID texture, int textureWidth, int textureHeight)
16 : HeaderTextureId(texture), HeaderTextureWidth(textureWidth), HeaderTextureHeight(textureHeight) {}
17
18 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::Begin(ax::NodeEditor::NodeId id)
19 {
20 HasHeader = false;
21 HeaderMin = HeaderMax = ImVec2();
22
23 ax::NodeEditor::PushStyleVar(StyleVar_NodePadding, ImVec4(8, 4, 8, 8));
24
25 ax::NodeEditor::BeginNode(id);
26
27 ImGui::PushID(id.AsPointer());
28 CurrentNodeId = id;
29
30 SetStage(Stage::Begin);
31 }
32
33 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::End()
34 {
35 SetStage(Stage::End);
36
37 ax::NodeEditor::EndNode();
38
39 if (ImGui::IsItemVisible())
40 {
41 auto alpha = static_cast<int>(255 * ImGui::GetStyle().Alpha);
42
43 auto* drawList = ax::NodeEditor::GetNodeBackgroundDrawList(CurrentNodeId);
44
45 const auto halfBorderWidth = ax::NodeEditor::GetStyle().NodeBorderWidth * 0.5F;
46
47 auto headerColor = IM_COL32(0, 0, 0, alpha) | (HeaderColor & IM_COL32(255, 255, 255, 0));
48 if ((HeaderMax.x > HeaderMin.x) && (HeaderMax.y > HeaderMin.y) && HeaderTextureId)
49 {
50 const auto uv = ImVec2(
51 (HeaderMax.x - HeaderMin.x) / (4.0F * static_cast<float>(HeaderTextureWidth)),
52 (HeaderMax.y - HeaderMin.y) / (4.0F * static_cast<float>(HeaderTextureHeight)));
53
54 drawList->AddImageRounded(HeaderTextureId,
55 HeaderMin - ImVec2(8 - halfBorderWidth, 4 - halfBorderWidth),
56 HeaderMax + ImVec2(8 - halfBorderWidth, 0),
57 ImVec2(0.0F, 0.0F), uv,
58 headerColor, GetStyle().NodeRounding, 1 | 2);
59
60 auto headerSeparatorMin = ImVec2(HeaderMin.x, HeaderMax.y);
61 auto headerSeparatorMax = ImVec2(HeaderMax.x, HeaderMin.y);
62
63 if ((headerSeparatorMax.x > headerSeparatorMin.x) && (headerSeparatorMax.y > headerSeparatorMin.y))
64 {
65 drawList->AddLine(
66 headerSeparatorMin + ImVec2(-(8 - halfBorderWidth), -0.5F),
67 headerSeparatorMax + ImVec2((8 - halfBorderWidth), -0.5F),
68 ImColor(255, 255, 255, 96 * alpha / (3 * 255)), 1.0F);
69 }
70 }
71 }
72
73 CurrentNodeId = 0;
74
75 ImGui::PopID();
76
77 ax::NodeEditor::PopStyleVar();
78
79 SetStage(Stage::Invalid);
80 }
81
82 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::Header(const ImVec4& color)
83 {
84 HeaderColor = ImColor(color);
85 SetStage(Stage::Header);
86 }
87
88 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::EndHeader()
89 {
90 SetStage(Stage::Content);
91 }
92
93 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::Input(ax::NodeEditor::PinId id)
94 {
95 if (CurrentStage == Stage::Begin)
96 {
97 SetStage(Stage::Content);
98 }
99
100 const auto applyPadding = (CurrentStage == Stage::Input);
101
102 SetStage(Stage::Input);
103
104 if (applyPadding)
105 {
106 ImGui::Spring(0);
107 }
108
109 Pin(id, PinKind::Input);
110
111 ImGui::BeginHorizontal(id.AsPointer());
112 }
113
114 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::EndInput()
115 {
116 ImGui::EndHorizontal();
117
118 EndPin();
119 }
120
121 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::Middle()
122 {
123 if (CurrentStage == Stage::Begin)
124 {
125 SetStage(Stage::Content);
126 }
127
128 SetStage(Stage::Middle);
129 }
130
131 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::Output(ax::NodeEditor::PinId id)
132 {
133 if (CurrentStage == Stage::Begin)
134 {
135 SetStage(Stage::Content);
136 }
137
138 const auto applyPadding = (CurrentStage == Stage::Output);
139
140 SetStage(Stage::Output);
141
142 if (applyPadding)
143 {
144 ImGui::Spring(0);
145 }
146
147 Pin(id, PinKind::Output);
148
149 ImGui::BeginHorizontal(id.AsPointer());
150 }
151
152 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::EndOutput()
153 {
154 ImGui::EndHorizontal();
155
156 EndPin();
157 }
158
159 bool ax::NodeEditor::Utilities::BlueprintNodeBuilder::SetStage(Stage stage)
160 {
161 if (stage == CurrentStage)
162 {
163 return false;
164 }
165
166 auto oldStage = CurrentStage;
167 CurrentStage = stage;
168
169 switch (oldStage)
170 {
171 case Stage::Begin:
172 break;
173
174 case Stage::Header:
175 ImGui::EndHorizontal();
176 HeaderMin = ImGui::GetItemRectMin();
177 HeaderMax = ImGui::GetItemRectMax();
178
179 // spacing between header and content
180 ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.y * 2.0F);
181
182 break;
183
184 case Stage::Content:
185 break;
186
187 case Stage::Input:
188 ax::NodeEditor::PopStyleVar(2);
189
190 ImGui::Spring(1, 0);
191 ImGui::EndVertical();
192
193 // #debug
194 // ImGui::GetWindowDrawList()->AddRect(
195 // ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 0, 0, 255));
196
197 break;
198
199 case Stage::Middle:
200 ImGui::EndVertical();
201
202 // #debug
203 // ImGui::GetWindowDrawList()->AddRect(
204 // ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 0, 0, 255));
205
206 break;
207
208 case Stage::Output:
209 ax::NodeEditor::PopStyleVar(2);
210
211 ImGui::Spring(1, 0);
212 ImGui::EndVertical();
213
214 // #debug
215 // ImGui::GetWindowDrawList()->AddRect(
216 // ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 0, 0, 255));
217
218 break;
219
220 case Stage::End:
221 // break;
222
223 case Stage::Invalid:
224 break;
225 }
226
227 switch (stage)
228 {
229 case Stage::Begin:
230 ImGui::BeginVertical("node");
231 break;
232
233 case Stage::Header:
234 HasHeader = true;
235
236 ImGui::BeginHorizontal("header");
237 break;
238
239 case Stage::Content:
240 if (oldStage == Stage::Begin)
241 {
242 ImGui::Spring(0);
243 }
244
245 ImGui::BeginHorizontal("content");
246 ImGui::Spring(0, 0);
247 break;
248
249 case Stage::Input:
250 ImGui::BeginVertical("inputs", ImVec2(0, 0), 0.0F);
251
252 ax::NodeEditor::PushStyleVar(ax::NodeEditor::StyleVar_PivotAlignment, ImVec2(0, 0.5F));
253 ax::NodeEditor::PushStyleVar(ax::NodeEditor::StyleVar_PivotSize, ImVec2(0, 0));
254
255 if (!HasHeader)
256 {
257 ImGui::Spring(1, 0);
258 }
259 break;
260
261 case Stage::Middle:
262 ImGui::Spring(1);
263 ImGui::BeginVertical("middle", ImVec2(0, 0), 1.0F);
264 break;
265
266 case Stage::Output:
267 if (oldStage == Stage::Middle || oldStage == Stage::Input)
268 {
269 ImGui::Spring(1);
270 }
271 else
272 {
273 ImGui::Spring(1, 0);
274 }
275 ImGui::BeginVertical("outputs", ImVec2(0, 0), 1.0F);
276
277 ax::NodeEditor::PushStyleVar(ax::NodeEditor::StyleVar_PivotAlignment, ImVec2(1.0F, 0.5F));
278 ax::NodeEditor::PushStyleVar(ax::NodeEditor::StyleVar_PivotSize, ImVec2(0, 0));
279
280 if (!HasHeader)
281 {
282 ImGui::Spring(1, 0);
283 }
284 break;
285
286 case Stage::End:
287 if (oldStage == Stage::Input)
288 {
289 ImGui::Spring(1, 0);
290 }
291 if (oldStage != Stage::Begin)
292 {
293 ImGui::EndHorizontal();
294 }
295 ContentMin = ImGui::GetItemRectMin();
296 ContentMax = ImGui::GetItemRectMax();
297
298 // ImGui::Spring(0);
299 ImGui::EndVertical();
300 NodeMin = ImGui::GetItemRectMin();
301 NodeMax = ImGui::GetItemRectMax();
302 break;
303
304 case Stage::Invalid:
305 break;
306 }
307
308 return true;
309 }
310
311 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::Pin(ax::NodeEditor::PinId id, ax::NodeEditor::PinKind kind)
312 {
313 ax::NodeEditor::BeginPin(id, kind);
314 }
315
316 void ax::NodeEditor::Utilities::BlueprintNodeBuilder::EndPin()
317 {
318 ax::NodeEditor::EndPin();
319
320 // #debug
321 // ImGui::GetWindowDrawList()->AddRectFilled(
322 // ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 0, 0, 64));
323 }
324