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 std::string code;
12
13 code += absl::StrFormat("// Generated by YAZE Layout Designer\n");
14 code += absl::StrFormat("// Panel: %s\n", design.panel_name);
15 code += absl::StrFormat("// Generated: <timestamp>\n\n");
16
17 code += absl::StrFormat("void %sPanel::Draw(bool* p_open) {\n", design.panel_id);
18
19 // Generate code for all root widgets
20 for (const auto& widget : design.widgets) {
21 code += GenerateWidgetCode(*widget, 1);
22 }
23
24 code += "}\n";
25
26 return code;
27}
28
30 int indent_level) {
31 std::string code;
32 std::string indent = GetIndent(indent_level);
33
34 // Add comment with widget ID
35 code += indent + absl::StrFormat("// Widget: %s\n", widget.id);
36
37 // Generate code based on widget type
38 switch (widget.type) {
43 code += GenerateTextCode(widget, indent_level);
44 break;
45
48 code += GenerateButtonCode(widget, indent_level);
49 break;
50
58 code += GenerateInputCode(widget, indent_level);
59 break;
60
65 code += GenerateTableCode(widget, indent_level);
66 break;
67
69 code += GenerateCanvasCode(widget, indent_level);
70 break;
71
73 code += indent + "ImGui::Separator();\n";
74 break;
75
77 code += indent + "ImGui::SameLine();\n";
78 break;
79
81 code += indent + "ImGui::Spacing();\n";
82 break;
83
85 code += indent + "ImGui::NewLine();\n";
86 break;
87
93 code += GenerateContainerCode(widget, indent_level);
94 break;
95
96 default:
97 code += indent + absl::StrFormat("// TODO: Generate code for %s\n",
98 GetWidgetTypeName(widget.type));
99 break;
100 }
101
102 // Add same line directive if needed
103 if (widget.same_line) {
104 code += indent + "ImGui::SameLine();\n";
105 }
106
107 code += "\n";
108 return code;
109}
110
112 std::string code;
113 code += " // Widget state variables\n";
114
115 for (const auto& widget : design.widgets) {
116 std::string var_name = GetVariableName(*widget);
117
118 switch (widget->type) {
120 code += absl::StrFormat(" bool %s = false;\n", var_name);
121 break;
122 }
124 auto* buffer_size_prop = const_cast<WidgetDefinition&>(*widget)
125 .GetProperty("buffer_size");
126 int size = buffer_size_prop ? buffer_size_prop->int_value : 256;
127 code += absl::StrFormat(" char %s[%d] = {};\n", var_name, size);
128 break;
129 }
132 code += absl::StrFormat(" int %s = 0;\n", var_name);
133 break;
134 }
137 code += absl::StrFormat(" float %s = 0.0f;\n", var_name);
138 break;
139 }
142 code += absl::StrFormat(" ImVec4 %s = ImVec4(1,1,1,1);\n", var_name);
143 break;
144 }
145 default:
146 break;
147 }
148 }
149
150 return code;
151}
152
154 std::string code;
155
156 // Generate initialization for input text buffers, etc.
157 for (const auto& widget : design.widgets) {
158 if (widget->type == WidgetType::InputText) {
159 auto* hint_prop = const_cast<WidgetDefinition&>(*widget).GetProperty("hint");
160 if (hint_prop && !hint_prop->string_value.empty()) {
161 std::string var_name = GetVariableName(*widget);
162 code += absl::StrFormat(" // Initialize %s hint\n", var_name);
163 }
164 }
165 }
166
167 return code;
168}
169
170// Private helper methods
171
172std::string WidgetCodeGenerator::GetIndent(int level) {
173 return std::string(level * 2, ' ');
174}
175
176std::string WidgetCodeGenerator::EscapeString(const std::string& str) {
177 return absl::StrReplaceAll(str, {{"\\", "\\\\"}, {"\"", "\\\""}});
178}
179
181 int indent) {
182 std::string code;
183 std::string ind = GetIndent(indent);
184
185 auto* label_prop = const_cast<WidgetDefinition&>(widget).GetProperty("label");
186 std::string label = label_prop ? label_prop->string_value : "Button";
187
188 auto* size_prop = const_cast<WidgetDefinition&>(widget).GetProperty("size");
189 ImVec2 size = size_prop ? size_prop->vec2_value : ImVec2(0, 0);
190
191 if (widget.type == WidgetType::SmallButton) {
192 code += ind + absl::StrFormat("if (ImGui::SmallButton(\"%s\")) {\n",
193 EscapeString(label));
194 } else if (size.x != 0 || size.y != 0) {
195 code += ind + absl::StrFormat(
196 "if (ImGui::Button(\"%s\", ImVec2(%.1f, %.1f))) {\n",
197 EscapeString(label), size.x, size.y);
198 } else {
199 code += ind + absl::StrFormat("if (ImGui::Button(\"%s\")) {\n",
200 EscapeString(label));
201 }
202
203 code += ind + " // TODO: Button callback\n";
204 if (!widget.callback_name.empty()) {
205 code += ind + absl::StrFormat(" %s();\n", widget.callback_name);
206 }
207 code += ind + "}\n";
208
209 if (!widget.tooltip.empty()) {
210 code += ind + "if (ImGui::IsItemHovered()) {\n";
211 code += ind + absl::StrFormat(" ImGui::SetTooltip(\"%s\");\n",
212 EscapeString(widget.tooltip));
213 code += ind + "}\n";
214 }
215
216 return code;
217}
218
220 int indent) {
221 std::string code;
222 std::string ind = GetIndent(indent);
223
224 auto* text_prop = const_cast<WidgetDefinition&>(widget).GetProperty("text");
225 std::string text = text_prop ? text_prop->string_value : "Text";
226
227 switch (widget.type) {
228 case WidgetType::Text:
229 code += ind + absl::StrFormat("ImGui::Text(\"%s\");\n", EscapeString(text));
230 break;
232 code += ind + absl::StrFormat("ImGui::TextWrapped(\"%s\");\n", EscapeString(text));
233 break;
235 code += ind + absl::StrFormat("ImGui::BulletText(\"%s\");\n", EscapeString(text));
236 break;
238 auto* color_prop = const_cast<WidgetDefinition&>(widget).GetProperty("color");
239 ImVec4 color = color_prop ? color_prop->color_value : ImVec4(1, 1, 1, 1);
240 code += ind + absl::StrFormat(
241 "ImGui::TextColored(ImVec4(%.2f, %.2f, %.2f, %.2f), \"%s\");\n",
242 color.x, color.y, color.z, color.w, EscapeString(text));
243 break;
244 }
245 default:
246 break;
247 }
248
249 return code;
250}
251
253 int indent) {
254 std::string code;
255 std::string ind = GetIndent(indent);
256 std::string var_name = GetVariableName(widget);
257
258 auto* label_prop = const_cast<WidgetDefinition&>(widget).GetProperty("label");
259 std::string label = label_prop ? label_prop->string_value : "Input";
260
261 switch (widget.type) {
263 code += ind + absl::StrFormat("ImGui::Checkbox(\"%s\", &%s);\n",
264 EscapeString(label), var_name);
265 break;
266
268 auto* hint_prop = const_cast<WidgetDefinition&>(widget).GetProperty("hint");
269 if (hint_prop && !hint_prop->string_value.empty()) {
270 code += ind + absl::StrFormat(
271 "ImGui::InputTextWithHint(\"%s\", \"%s\", %s, sizeof(%s));\n",
272 EscapeString(label), EscapeString(hint_prop->string_value),
273 var_name, var_name);
274 } else {
275 code += ind + absl::StrFormat("ImGui::InputText(\"%s\", %s, sizeof(%s));\n",
276 EscapeString(label), var_name, var_name);
277 }
278 break;
279 }
280
282 code += ind + absl::StrFormat("ImGui::InputInt(\"%s\", &%s);\n",
283 EscapeString(label), var_name);
284 break;
285
287 auto* min_prop = const_cast<WidgetDefinition&>(widget).GetProperty("min");
288 auto* max_prop = const_cast<WidgetDefinition&>(widget).GetProperty("max");
289 int min_val = min_prop ? min_prop->int_value : 0;
290 int max_val = max_prop ? max_prop->int_value : 100;
291 code += ind + absl::StrFormat("ImGui::SliderInt(\"%s\", &%s, %d, %d);\n",
292 EscapeString(label), var_name, min_val, max_val);
293 break;
294 }
295
296 default:
297 break;
298 }
299
300 return code;
301}
302
304 int indent) {
305 std::string code;
306 std::string ind = GetIndent(indent);
307
308 switch (widget.type) {
310 auto* id_prop = const_cast<WidgetDefinition&>(widget).GetProperty("id");
311 auto* columns_prop = const_cast<WidgetDefinition&>(widget).GetProperty("columns");
312 std::string id = id_prop ? id_prop->string_value : "table";
313 int columns = columns_prop ? columns_prop->int_value : 2;
314
315 code += ind + absl::StrFormat("if (ImGui::BeginTable(\"%s\", %d)) {\n",
316 id, columns);
317
318 // Generate children
319 for (const auto& child : widget.children) {
320 code += GenerateWidgetCode(*child, indent + 1);
321 }
322
323 code += ind + " ImGui::EndTable();\n";
324 code += ind + "}\n";
325 break;
326 }
327
329 code += ind + "ImGui::TableNextRow();\n";
330 break;
331
333 code += ind + "ImGui::TableNextColumn();\n";
334 break;
335
336 default:
337 break;
338 }
339
340 return code;
341}
342
344 int indent) {
345 std::string code;
346 std::string ind = GetIndent(indent);
347
348 auto* size_prop = const_cast<WidgetDefinition&>(widget).GetProperty("size");
349 ImVec2 size = size_prop ? size_prop->vec2_value : ImVec2(300, 200);
350
351 code += ind + absl::StrFormat("// Custom canvas - size: %.0fx%.0f\n",
352 size.x, size.y);
353 code += ind + "ImVec2 canvas_pos = ImGui::GetCursorScreenPos();\n";
354 code += ind + absl::StrFormat("ImVec2 canvas_size = ImVec2(%.0ff, %.0ff);\n",
355 size.x, size.y);
356 code += ind + "ImDrawList* draw_list = ImGui::GetWindowDrawList();\n";
357 code += ind + "// TODO: Add custom drawing code here\n";
358 code += ind + "ImGui::Dummy(canvas_size);\n";
359
360 return code;
361}
362
364 int indent) {
365 std::string code;
366 std::string ind = GetIndent(indent);
367
368 // TODO: Implement container code generation
369 code += ind + absl::StrFormat("// TODO: Container widget: %s\n",
370 GetWidgetTypeName(widget.type));
371
372 return code;
373}
374
376 // Convert widget ID to valid C++ variable name
377 std::string var_name = widget.id;
378 std::replace(var_name.begin(), var_name.end(), '.', '_');
379 std::replace(var_name.begin(), var_name.end(), '-', '_');
380 var_name += "_";
381 return var_name;
382}
383
384} // namespace layout_designer
385} // namespace editor
386} // namespace yaze
387
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