yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
widget_code_generator.cc
Go to the documentation of this file.
2
3#include "absl/strings/str_format.h"
4#include "absl/strings/str_replace.h"
5
6namespace yaze {
7namespace editor {
8namespace layout_designer {
9
11 const PanelDesign& design) {
12 std::string code;
13
14 code += absl::StrFormat("// Generated by YAZE Layout Designer\n");
15 code += absl::StrFormat("// Panel: %s\n", design.panel_name);
16 code += absl::StrFormat("// Generated: <timestamp>\n\n");
17
18 code +=
19 absl::StrFormat("void %sPanel::Draw(bool* p_open) {\n", design.panel_id);
20
21 // Generate code for all root widgets
22 for (const auto& widget : design.widgets) {
23 code += GenerateWidgetCode(*widget, 1);
24 }
25
26 code += "}\n";
27
28 return code;
29}
30
32 const WidgetDefinition& widget, int indent_level) {
33 std::string code;
34 std::string indent = GetIndent(indent_level);
35
36 // Add comment with widget ID
37 code += indent + absl::StrFormat("// Widget: %s\n", widget.id);
38
39 // Generate code based on widget type
40 switch (widget.type) {
45 code += GenerateTextCode(widget, indent_level);
46 break;
47
50 code += GenerateButtonCode(widget, indent_level);
51 break;
52
60 code += GenerateInputCode(widget, indent_level);
61 break;
62
67 code += GenerateTableCode(widget, indent_level);
68 break;
69
71 code += GenerateCanvasCode(widget, indent_level);
72 break;
73
75 code += indent + "ImGui::Separator();\n";
76 break;
77
79 code += indent + "ImGui::SameLine();\n";
80 break;
81
83 code += indent + "ImGui::Spacing();\n";
84 break;
85
87 code += indent + "ImGui::NewLine();\n";
88 break;
89
95 code += GenerateContainerCode(widget, indent_level);
96 break;
97
98 default:
99 code += indent + absl::StrFormat("// TODO: Generate code for %s\n",
100 GetWidgetTypeName(widget.type));
101 break;
102 }
103
104 // Add same line directive if needed
105 if (widget.same_line) {
106 code += indent + "ImGui::SameLine();\n";
107 }
108
109 code += "\n";
110 return code;
111}
112
114 const PanelDesign& design) {
115 std::string code;
116 code += " // Widget state variables\n";
117
118 for (const auto& widget : design.widgets) {
119 std::string var_name = GetVariableName(*widget);
120
121 switch (widget->type) {
123 code += absl::StrFormat(" bool %s = false;\n", var_name);
124 break;
125 }
127 auto* buffer_size_prop =
128 const_cast<WidgetDefinition&>(*widget).GetProperty("buffer_size");
129 int size = buffer_size_prop ? buffer_size_prop->int_value : 256;
130 code += absl::StrFormat(" char %s[%d] = {};\n", var_name, size);
131 break;
132 }
135 code += absl::StrFormat(" int %s = 0;\n", var_name);
136 break;
137 }
140 code += absl::StrFormat(" float %s = 0.0f;\n", var_name);
141 break;
142 }
145 code += absl::StrFormat(" ImVec4 %s = ImVec4(1,1,1,1);\n", var_name);
146 break;
147 }
148 default:
149 break;
150 }
151 }
152
153 return code;
154}
155
157 const PanelDesign& design) {
158 std::string code;
159
160 // Generate initialization for input text buffers, etc.
161 for (const auto& widget : design.widgets) {
162 if (widget->type == WidgetType::InputText) {
163 auto* hint_prop =
164 const_cast<WidgetDefinition&>(*widget).GetProperty("hint");
165 if (hint_prop && !hint_prop->string_value.empty()) {
166 std::string var_name = GetVariableName(*widget);
167 code += absl::StrFormat(" // Initialize %s hint\n", var_name);
168 }
169 }
170 }
171
172 return code;
173}
174
175// Private helper methods
176
177std::string WidgetCodeGenerator::GetIndent(int level) {
178 return std::string(level * 2, ' ');
179}
180
181std::string WidgetCodeGenerator::EscapeString(const std::string& str) {
182 return absl::StrReplaceAll(str, {{"\\", "\\\\"}, {"\"", "\\\""}});
183}
184
186 const WidgetDefinition& widget, int indent) {
187 std::string code;
188 std::string ind = GetIndent(indent);
189
190 auto* label_prop = const_cast<WidgetDefinition&>(widget).GetProperty("label");
191 std::string label = label_prop ? label_prop->string_value : "Button";
192
193 auto* size_prop = const_cast<WidgetDefinition&>(widget).GetProperty("size");
194 ImVec2 size = size_prop ? size_prop->vec2_value : ImVec2(0, 0);
195
196 if (widget.type == WidgetType::SmallButton) {
197 code += ind + absl::StrFormat("if (ImGui::SmallButton(\"%s\")) {\n",
198 EscapeString(label));
199 } else if (size.x != 0 || size.y != 0) {
200 code += ind + absl::StrFormat(
201 "if (ImGui::Button(\"%s\", ImVec2(%.1f, %.1f))) {\n",
202 EscapeString(label), size.x, size.y);
203 } else {
204 code += ind + absl::StrFormat("if (ImGui::Button(\"%s\")) {\n",
205 EscapeString(label));
206 }
207
208 code += ind + " // TODO: Button callback\n";
209 if (!widget.callback_name.empty()) {
210 code += ind + absl::StrFormat(" %s();\n", widget.callback_name);
211 }
212 code += ind + "}\n";
213
214 if (!widget.tooltip.empty()) {
215 code += ind + "if (ImGui::IsItemHovered()) {\n";
216 code += ind + absl::StrFormat(" ImGui::SetTooltip(\"%s\");\n",
217 EscapeString(widget.tooltip));
218 code += ind + "}\n";
219 }
220
221 return code;
222}
223
225 const WidgetDefinition& widget, int indent) {
226 std::string code;
227 std::string ind = GetIndent(indent);
228
229 auto* text_prop = const_cast<WidgetDefinition&>(widget).GetProperty("text");
230 std::string text = text_prop ? text_prop->string_value : "Text";
231
232 switch (widget.type) {
233 case WidgetType::Text:
234 code +=
235 ind + absl::StrFormat("ImGui::Text(\"%s\");\n", EscapeString(text));
236 break;
238 code += ind + absl::StrFormat("ImGui::TextWrapped(\"%s\");\n",
239 EscapeString(text));
240 break;
242 code += ind + absl::StrFormat("ImGui::BulletText(\"%s\");\n",
243 EscapeString(text));
244 break;
246 auto* color_prop =
247 const_cast<WidgetDefinition&>(widget).GetProperty("color");
248 ImVec4 color = color_prop ? color_prop->color_value : ImVec4(1, 1, 1, 1);
249 code +=
250 ind +
251 absl::StrFormat(
252 "ImGui::TextColored(ImVec4(%.2f, %.2f, %.2f, %.2f), \"%s\");\n",
253 color.x, color.y, color.z, color.w, EscapeString(text));
254 break;
255 }
256 default:
257 break;
258 }
259
260 return code;
261}
262
264 const WidgetDefinition& widget, int indent) {
265 std::string code;
266 std::string ind = GetIndent(indent);
267 std::string var_name = GetVariableName(widget);
268
269 auto* label_prop = const_cast<WidgetDefinition&>(widget).GetProperty("label");
270 std::string label = label_prop ? label_prop->string_value : "Input";
271
272 switch (widget.type) {
274 code += ind + absl::StrFormat("ImGui::Checkbox(\"%s\", &%s);\n",
275 EscapeString(label), var_name);
276 break;
277
279 auto* hint_prop =
280 const_cast<WidgetDefinition&>(widget).GetProperty("hint");
281 if (hint_prop && !hint_prop->string_value.empty()) {
282 code +=
283 ind +
284 absl::StrFormat(
285 "ImGui::InputTextWithHint(\"%s\", \"%s\", %s, sizeof(%s));\n",
286 EscapeString(label), EscapeString(hint_prop->string_value),
287 var_name, var_name);
288 } else {
289 code +=
290 ind + absl::StrFormat("ImGui::InputText(\"%s\", %s, sizeof(%s));\n",
291 EscapeString(label), var_name, var_name);
292 }
293 break;
294 }
295
297 code += ind + absl::StrFormat("ImGui::InputInt(\"%s\", &%s);\n",
298 EscapeString(label), var_name);
299 break;
300
302 auto* min_prop = const_cast<WidgetDefinition&>(widget).GetProperty("min");
303 auto* max_prop = const_cast<WidgetDefinition&>(widget).GetProperty("max");
304 int min_val = min_prop ? min_prop->int_value : 0;
305 int max_val = max_prop ? max_prop->int_value : 100;
306 code += ind + absl::StrFormat("ImGui::SliderInt(\"%s\", &%s, %d, %d);\n",
307 EscapeString(label), var_name, min_val,
308 max_val);
309 break;
310 }
311
312 default:
313 break;
314 }
315
316 return code;
317}
318
320 const WidgetDefinition& widget, int indent) {
321 std::string code;
322 std::string ind = GetIndent(indent);
323
324 switch (widget.type) {
326 auto* id_prop = const_cast<WidgetDefinition&>(widget).GetProperty("id");
327 auto* columns_prop =
328 const_cast<WidgetDefinition&>(widget).GetProperty("columns");
329 std::string id = id_prop ? id_prop->string_value : "table";
330 int columns = columns_prop ? columns_prop->int_value : 2;
331
332 code += ind + absl::StrFormat("if (ImGui::BeginTable(\"%s\", %d)) {\n",
333 id, columns);
334
335 // Generate children
336 for (const auto& child : widget.children) {
337 code += GenerateWidgetCode(*child, indent + 1);
338 }
339
340 code += ind + " ImGui::EndTable();\n";
341 code += ind + "}\n";
342 break;
343 }
344
346 code += ind + "ImGui::TableNextRow();\n";
347 break;
348
350 code += ind + "ImGui::TableNextColumn();\n";
351 break;
352
353 default:
354 break;
355 }
356
357 return code;
358}
359
361 const WidgetDefinition& widget, int indent) {
362 std::string code;
363 std::string ind = GetIndent(indent);
364
365 auto* size_prop = const_cast<WidgetDefinition&>(widget).GetProperty("size");
366 ImVec2 size = size_prop ? size_prop->vec2_value : ImVec2(300, 200);
367
368 code += ind + absl::StrFormat("// Custom canvas - size: %.0fx%.0f\n", size.x,
369 size.y);
370 code += ind + "ImVec2 canvas_pos = ImGui::GetCursorScreenPos();\n";
371 code += ind + absl::StrFormat("ImVec2 canvas_size = ImVec2(%.0ff, %.0ff);\n",
372 size.x, size.y);
373 code += ind + "ImDrawList* draw_list = ImGui::GetWindowDrawList();\n";
374 code += ind + "// TODO: Add custom drawing code here\n";
375 code += ind + "ImGui::Dummy(canvas_size);\n";
376
377 return code;
378}
379
381 const WidgetDefinition& widget, int indent) {
382 std::string code;
383 std::string ind = GetIndent(indent);
384
385 // TODO: Implement container code generation
386 code += ind + absl::StrFormat("// TODO: Container widget: %s\n",
387 GetWidgetTypeName(widget.type));
388
389 return code;
390}
391
393 const WidgetDefinition& widget) {
394 // Convert widget ID to valid C++ variable name
395 std::string var_name = widget.id;
396 std::replace(var_name.begin(), var_name.end(), '.', '_');
397 std::replace(var_name.begin(), var_name.end(), '-', '_');
398 var_name += "_";
399 return var_name;
400}
401
402} // namespace layout_designer
403} // namespace editor
404} // namespace yaze
static std::string EscapeString(const std::string &str)
static std::string GenerateWidgetCode(const WidgetDefinition &widget, int indent_level=0)
Generate code for a single widget.
static std::string GenerateButtonCode(const WidgetDefinition &widget, int indent)
static std::string GenerateMemberVariables(const PanelDesign &design)
Generate member variable declarations for panel.
static std::string GenerateTableCode(const WidgetDefinition &widget, int indent)
static std::string GenerateTextCode(const WidgetDefinition &widget, int indent)
static std::string GenerateContainerCode(const WidgetDefinition &widget, int indent)
static std::string GenerateInputCode(const WidgetDefinition &widget, int indent)
static std::string GeneratePanelDrawMethod(const PanelDesign &design)
Generate complete panel Draw() method code.
static std::string GenerateInitializationCode(const PanelDesign &design)
Generate initialization code for panel constructor.
static std::string GenerateCanvasCode(const WidgetDefinition &widget, int indent)
static std::string GetVariableName(const WidgetDefinition &widget)
const char * GetWidgetTypeName(WidgetType type)
Get human-readable name for widget type.
Complete design definition for a panel's internal layout.
std::vector< std::unique_ptr< WidgetDefinition > > widgets
Defines a widget instance in a panel layout.
WidgetProperty * GetProperty(const std::string &name)
std::vector< std::unique_ptr< WidgetDefinition > > children