yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
settings_panel.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstdlib>
5#include <cstring>
6#include <filesystem>
7#include <set>
8#include <vector>
9
13#include "app/gui/core/icons.h"
14#include "app/gui/core/style.h"
16#include "rom/rom.h"
19#include "imgui/imgui.h"
20#include "imgui/misc/cpp/imgui_stdlib.h"
21#include "util/log.h"
22#include "util/platform_paths.h"
24
25namespace yaze {
26namespace editor {
27
29 if (!user_settings_) {
30 ImGui::TextDisabled("Settings not available");
31 return;
32 }
33
34 // Use collapsing headers for sections
35 // Default open the General Settings
36 if (ImGui::CollapsingHeader(ICON_MD_SETTINGS " General Settings",
37 ImGuiTreeNodeFlags_DefaultOpen)) {
38 ImGui::Indent();
40 ImGui::Unindent();
41 ImGui::Spacing();
42 }
43
44 // Add Project Settings section
45 if (ImGui::CollapsingHeader(ICON_MD_FOLDER " Project Configuration")) {
46 ImGui::Indent();
48 ImGui::Unindent();
49 ImGui::Spacing();
50 }
51
52 if (ImGui::CollapsingHeader(ICON_MD_PALETTE " Appearance")) {
53 ImGui::Indent();
55 ImGui::Unindent();
56 ImGui::Spacing();
57 }
58
59 if (ImGui::CollapsingHeader(ICON_MD_TUNE " Editor Behavior")) {
60 ImGui::Indent();
62 ImGui::Unindent();
63 ImGui::Spacing();
64 }
65
66 if (ImGui::CollapsingHeader(ICON_MD_SPEED " Performance")) {
67 ImGui::Indent();
69 ImGui::Unindent();
70 ImGui::Spacing();
71 }
72
73 if (ImGui::CollapsingHeader(ICON_MD_SMART_TOY " AI Agent")) {
74 ImGui::Indent();
76 ImGui::Unindent();
77 ImGui::Spacing();
78 }
79
80 if (ImGui::CollapsingHeader(ICON_MD_KEYBOARD " Keyboard Shortcuts")) {
81 ImGui::Indent();
83 ImGui::Unindent();
84 ImGui::Spacing();
85 }
86
87 if (ImGui::CollapsingHeader(ICON_MD_EXTENSION " ASM Patches")) {
88 ImGui::Indent();
90 ImGui::Unindent();
91 }
92}
93
95 // Refactored from table to vertical list for sidebar
96 static gui::FlagsMenu flags;
97
98 ImGui::TextDisabled("Feature Flags configuration");
99 ImGui::Spacing();
100
101 if (ImGui::TreeNode(ICON_MD_FLAG " System Flags")) {
102 flags.DrawSystemFlags();
103 ImGui::TreePop();
104 }
105
106 if (ImGui::TreeNode(ICON_MD_MAP " Overworld Flags")) {
107 flags.DrawOverworldFlags();
108 ImGui::TreePop();
109 }
110
111 if (ImGui::TreeNode(ICON_MD_EXTENSION " ZSCustomOverworld Enable Flags")) {
113 ImGui::TreePop();
114 }
115
116 if (ImGui::TreeNode(ICON_MD_CASTLE " Dungeon Flags")) {
117 flags.DrawDungeonFlags();
118 ImGui::TreePop();
119 }
120
121 if (ImGui::TreeNode(ICON_MD_FOLDER_SPECIAL " Resource Flags")) {
122 flags.DrawResourceFlags();
123 ImGui::TreePop();
124 }
125}
126
128 if (!project_) {
129 ImGui::TextDisabled("No active project.");
130 return;
131 }
132
133 ImGui::Text("%s Project Info", ICON_MD_INFO);
134 ImGui::Separator();
135
136 ImGui::Text("Name: %s", project_->name.c_str());
137 ImGui::Text("Path: %s", project_->filepath.c_str());
138
139 ImGui::Spacing();
140 ImGui::Text("%s Paths", ICON_MD_FOLDER_OPEN);
141 ImGui::Separator();
142
143 // Output Folder
144 std::string output_folder = project_->output_folder;
145 if (ImGui::InputText("Output Folder", &output_folder)) {
146 project_->output_folder = output_folder;
147 project_->Save();
148 }
149
150 // Git Repository
151 std::string git_repo = project_->git_repository;
152 if (ImGui::InputText("Git Repository", &git_repo)) {
153 project_->git_repository = git_repo;
154 project_->Save();
155 }
156
157 ImGui::Spacing();
158 ImGui::Text("%s Build", ICON_MD_BUILD);
159 ImGui::Separator();
160
161 // Build Target
162 std::string build_target = project_->build_target;
163 if (ImGui::InputText("Build Target (ROM)", &build_target)) {
164 project_->build_target = build_target;
165 project_->Save();
166 }
167
168 // Symbols File
169 std::string symbols_file = project_->symbols_filename;
170 if (ImGui::InputText("Symbols File", &symbols_file)) {
171 project_->symbols_filename = symbols_file;
172 project_->Save();
173 }
174}
175
177 auto& theme_manager = gui::ThemeManager::Get();
178
179 ImGui::Text("%s Theme Management", ICON_MD_PALETTE);
180 ImGui::Separator();
181
182 // Current theme selection
183 ImGui::Text("Current Theme:");
184 ImGui::SameLine();
185 auto current = theme_manager.GetCurrentThemeName();
186 ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), "%s", current.c_str());
187
188 ImGui::Spacing();
189
190 // Available themes list (instead of grid for sidebar)
191 ImGui::Text("Available Themes:");
192
193 if (ImGui::BeginChild("ThemeList", ImVec2(0, 150), true)) {
194 for (const auto& theme_name : theme_manager.GetAvailableThemes()) {
195 ImGui::PushID(theme_name.c_str());
196 bool is_current = (theme_name == current);
197
198 if (ImGui::Selectable(theme_name.c_str(), is_current)) {
199 theme_manager.LoadTheme(theme_name);
200 }
201
202 ImGui::PopID();
203 }
204 }
205 ImGui::EndChild();
206
207 ImGui::Spacing();
209
210 ImGui::Spacing();
211 ImGui::Text("%s Status Bar", ICON_MD_HORIZONTAL_RULE);
212 ImGui::Separator();
213
214 bool show_status_bar = user_settings_->prefs().show_status_bar;
215 if (ImGui::Checkbox("Show Status Bar", &show_status_bar)) {
216 user_settings_->prefs().show_status_bar = show_status_bar;
218 // Immediately apply to status bar if status_bar_ is available
219 if (status_bar_) {
220 status_bar_->SetEnabled(show_status_bar);
221 }
222 }
223 if (ImGui::IsItemHovered()) {
224 ImGui::SetTooltip("Display ROM, session, cursor, and zoom info at bottom of window");
225 }
226}
227
229 if (!user_settings_) return;
230
231 ImGui::Text("%s Auto-Save", ICON_MD_SAVE);
232 ImGui::Separator();
233
234 if (ImGui::Checkbox("Enable Auto-Save",
237 }
238
240 ImGui::Indent();
241 int interval = static_cast<int>(user_settings_->prefs().autosave_interval);
242 if (ImGui::SliderInt("Interval (sec)", &interval, 60, 600)) {
243 user_settings_->prefs().autosave_interval = static_cast<float>(interval);
245 }
246
247 if (ImGui::Checkbox("Backup Before Save",
250 }
251 ImGui::Unindent();
252 }
253
254 ImGui::Spacing();
255 ImGui::Text("%s Recent Files", ICON_MD_HISTORY);
256 ImGui::Separator();
257
258 if (ImGui::SliderInt("Limit",
261 }
262
263 ImGui::Spacing();
264 ImGui::Text("%s Default Editor", ICON_MD_EDIT);
265 ImGui::Separator();
266
267 const char* editors[] = {"None", "Overworld", "Dungeon", "Graphics"};
268 if (ImGui::Combo("##DefaultEditor", &user_settings_->prefs().default_editor,
269 editors, IM_ARRAYSIZE(editors))) {
271 }
272
273 ImGui::Spacing();
274 ImGui::Text("%s Sprite Names", ICON_MD_LABEL);
275 ImGui::Separator();
276 if (ImGui::Checkbox("Use HMagic sprite names (expanded)", &user_settings_->prefs().prefer_hmagic_sprite_names)) {
279 }
280}
281
283 if (!user_settings_) return;
284
285 ImGui::Text("%s Graphics", ICON_MD_IMAGE);
286 ImGui::Separator();
287
288 if (ImGui::Checkbox("V-Sync", &user_settings_->prefs().vsync)) {
290 }
291
292 if (ImGui::SliderInt("Target FPS", &user_settings_->prefs().target_fps, 30, 144)) {
294 }
295
296 ImGui::Spacing();
297 ImGui::Text("%s Memory", ICON_MD_MEMORY);
298 ImGui::Separator();
299
300 if (ImGui::SliderInt("Cache Size (MB)", &user_settings_->prefs().cache_size_mb,
301 128, 2048)) {
303 }
304
305 if (ImGui::SliderInt("Undo History", &user_settings_->prefs().undo_history_size,
306 10, 200)) {
308 }
309
310 ImGui::Spacing();
311 ImGui::Separator();
312 ImGui::Text("Current FPS: %.1f", ImGui::GetIO().Framerate);
313 ImGui::Text("Frame Time: %.3f ms", 1000.0f / ImGui::GetIO().Framerate);
314}
315
317 if (!user_settings_) return;
318
319 // Provider selection
320 ImGui::Text("%s Provider", ICON_MD_CLOUD);
321 ImGui::Separator();
322
323 const char* providers[] = {"Ollama (Local)", "Gemini (Cloud)", "Mock (Testing)"};
324 if (ImGui::Combo("##Provider", &user_settings_->prefs().ai_provider, providers,
325 IM_ARRAYSIZE(providers))) {
327 }
328
329 ImGui::Spacing();
330
331 if (user_settings_->prefs().ai_provider == 0) { // Ollama
332 char url_buffer[256];
333 strncpy(url_buffer, user_settings_->prefs().ollama_url.c_str(),
334 sizeof(url_buffer) - 1);
335 url_buffer[sizeof(url_buffer) - 1] = '\0';
336 if (ImGui::InputText("URL", url_buffer, IM_ARRAYSIZE(url_buffer))) {
337 user_settings_->prefs().ollama_url = url_buffer;
339 }
340 } else if (user_settings_->prefs().ai_provider == 1) { // Gemini
341 char key_buffer[128];
342 strncpy(key_buffer, user_settings_->prefs().gemini_api_key.c_str(),
343 sizeof(key_buffer) - 1);
344 key_buffer[sizeof(key_buffer) - 1] = '\0';
345 if (ImGui::InputText("API Key", key_buffer, IM_ARRAYSIZE(key_buffer),
346 ImGuiInputTextFlags_Password)) {
347 user_settings_->prefs().gemini_api_key = key_buffer;
349 }
350 }
351
352 ImGui::Spacing();
353 ImGui::Text("%s Parameters", ICON_MD_TUNE);
354 ImGui::Separator();
355
356 if (ImGui::SliderFloat("Temperature", &user_settings_->prefs().ai_temperature,
357 0.0f, 2.0f)) {
359 }
360 ImGui::TextDisabled("Higher = more creative");
361
362 if (ImGui::SliderInt("Max Tokens", &user_settings_->prefs().ai_max_tokens, 256,
363 8192)) {
365 }
366
367 ImGui::Spacing();
368 ImGui::Text("%s Behavior", ICON_MD_PSYCHOLOGY);
369 ImGui::Separator();
370
371 if (ImGui::Checkbox("Proactive Suggestions",
374 }
375
376 if (ImGui::Checkbox("Auto-Learn Preferences",
379 }
380
381 if (ImGui::Checkbox("Enable Vision",
384 }
385
386 ImGui::Spacing();
387 ImGui::Text("%s Logging", ICON_MD_TERMINAL);
388 ImGui::Separator();
389
390 const char* log_levels[] = {"Debug", "Info", "Warning", "Error", "Fatal"};
391 if (ImGui::Combo("Log Level", &user_settings_->prefs().log_level, log_levels,
392 IM_ARRAYSIZE(log_levels))) {
393 // Apply log level logic here if needed
395 }
396}
397
399 if (ImGui::TreeNodeEx(ICON_MD_KEYBOARD " Shortcuts", ImGuiTreeNodeFlags_DefaultOpen)) {
400 if (ImGui::TreeNode("Global Shortcuts")) {
402 ImGui::TreePop();
403 }
404 if (ImGui::TreeNode("Editor Shortcuts")) {
406 ImGui::TreePop();
407 }
408 if (ImGui::TreeNode("Panel Shortcuts")) {
410 ImGui::TreePop();
411 }
412 ImGui::TextDisabled("Tip: Use Cmd/Opt labels on macOS or Ctrl/Alt on Windows/Linux. Function keys and symbols (/, -) are supported.");
413 ImGui::TreePop();
414 }
415}
416
419 ImGui::TextDisabled("Not available");
420 return;
421 }
422
424 if (shortcuts.empty()) {
425 ImGui::TextDisabled("No global shortcuts registered.");
426 return;
427 }
428
429 static std::unordered_map<std::string, std::string> editing;
430
431 for (const auto& sc : shortcuts) {
432 auto it = editing.find(sc.name);
433 if (it == editing.end()) {
434 std::string current = PrintShortcut(sc.keys);
435 // Use user override if present
436 auto u = user_settings_->prefs().global_shortcuts.find(sc.name);
437 if (u != user_settings_->prefs().global_shortcuts.end()) {
438 current = u->second;
439 }
440 editing[sc.name] = current;
441 }
442
443 ImGui::PushID(sc.name.c_str());
444 ImGui::Text("%s", sc.name.c_str());
445 ImGui::SameLine();
446 ImGui::SetNextItemWidth(180);
447 std::string& value = editing[sc.name];
448 if (ImGui::InputText("##global", &value,
449 ImGuiInputTextFlags_EnterReturnsTrue |
450 ImGuiInputTextFlags_AutoSelectAll)) {
451 auto parsed = ParseShortcut(value);
452 if (!parsed.empty() || value.empty()) {
453 // Empty string clears the shortcut
454 shortcut_manager_->UpdateShortcutKeys(sc.name, parsed);
455 if (value.empty()) {
456 user_settings_->prefs().global_shortcuts.erase(sc.name);
457 } else {
458 user_settings_->prefs().global_shortcuts[sc.name] = value;
459 }
461 }
462 }
463 ImGui::PopID();
464 }
465}
466
469 ImGui::TextDisabled("Not available");
470 return;
471 }
472
474 std::map<std::string, std::vector<Shortcut>> grouped;
475 static std::unordered_map<std::string, std::string> editing;
476
477 for (const auto& sc : shortcuts) {
478 auto pos = sc.name.find(".");
479 std::string group = pos != std::string::npos ? sc.name.substr(0, pos) : "general";
480 grouped[group].push_back(sc);
481 }
482 for (const auto& [group, list] : grouped) {
483 if (ImGui::TreeNode(group.c_str())) {
484 for (const auto& sc : list) {
485 ImGui::PushID(sc.name.c_str());
486 ImGui::Text("%s", sc.name.c_str());
487 ImGui::SameLine();
488 ImGui::SetNextItemWidth(180);
489 std::string& value = editing[sc.name];
490 if (value.empty()) {
491 value = PrintShortcut(sc.keys);
492 // Apply user override if present
493 auto u = user_settings_->prefs().editor_shortcuts.find(sc.name);
494 if (u != user_settings_->prefs().editor_shortcuts.end()) {
495 value = u->second;
496 }
497 }
498 if (ImGui::InputText("##editor", &value, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
499 auto parsed = ParseShortcut(value);
500 if (!parsed.empty() || value.empty()) {
501 shortcut_manager_->UpdateShortcutKeys(sc.name, parsed);
502 if (value.empty()) {
503 user_settings_->prefs().editor_shortcuts.erase(sc.name);
504 } else {
505 user_settings_->prefs().editor_shortcuts[sc.name] = value;
506 }
508 }
509 }
510 ImGui::PopID();
511 }
512 ImGui::TreePop();
513 }
514 }
515}
516
519 ImGui::TextDisabled("Registry not available");
520 return;
521 }
522
523 // Simplified shortcut editor for sidebar
524 auto categories = panel_manager_->GetAllCategories();
525
526 for (const auto& category : categories) {
527 if (ImGui::TreeNode(category.c_str())) {
528 auto cards = panel_manager_->GetPanelsInCategory(0, category);
529
530 for (const auto& card : cards) {
531 ImGui::PushID(card.card_id.c_str());
532
533 ImGui::Text("%s %s", card.icon.c_str(), card.display_name.c_str());
534
535 std::string current_shortcut;
536 auto it = user_settings_->prefs().panel_shortcuts.find(card.card_id);
537 if (it != user_settings_->prefs().panel_shortcuts.end()) {
538 current_shortcut = it->second;
539 } else if (!card.shortcut_hint.empty()) {
540 current_shortcut = card.shortcut_hint;
541 } else {
542 current_shortcut = "None";
543 }
544
545 // Display platform-aware label
546 std::string display_shortcut = current_shortcut;
547 auto parsed = ParseShortcut(current_shortcut);
548 if (!parsed.empty()) {
549 display_shortcut = PrintShortcut(parsed);
550 }
551
552 if (is_editing_shortcut_ && editing_card_id_ == card.card_id) {
553 ImGui::SetNextItemWidth(120);
554 ImGui::SetKeyboardFocusHere();
555 if (ImGui::InputText("##Edit", shortcut_edit_buffer_,
556 sizeof(shortcut_edit_buffer_),
557 ImGuiInputTextFlags_EnterReturnsTrue)) {
558 if (strlen(shortcut_edit_buffer_) > 0) {
560 } else {
561 user_settings_->prefs().panel_shortcuts.erase(card.card_id);
562 }
564 is_editing_shortcut_ = false;
565 editing_card_id_.clear();
566 }
567 ImGui::SameLine();
568 if (ImGui::Button(ICON_MD_CLOSE)) {
569 is_editing_shortcut_ = false;
570 editing_card_id_.clear();
571 }
572 } else {
573 if (ImGui::Button(display_shortcut.c_str(), ImVec2(120, 0))) {
575 editing_card_id_ = card.card_id;
576 strncpy(shortcut_edit_buffer_, current_shortcut.c_str(), sizeof(shortcut_edit_buffer_) - 1);
577 }
578 if (ImGui::IsItemHovered()) {
579 ImGui::SetTooltip("Click to edit shortcut");
580 }
581 }
582
583 ImGui::PopID();
584 }
585
586 ImGui::TreePop();
587 }
588 }
589}
590
592 // Load patches on first access
593 if (!patches_loaded_) {
594 // Try to load from default patches location
595 auto patches_dir_status = util::PlatformPaths::FindAsset("patches");
596 if (patches_dir_status.ok()) {
597 auto status = patch_manager_.LoadPatches(patches_dir_status->string());
598 if (status.ok()) {
599 patches_loaded_ = true;
600 if (!patch_manager_.folders().empty()) {
602 }
603 }
604 }
605 }
606
607 ImGui::Text("%s ZScream Patch System", ICON_MD_EXTENSION);
608 ImGui::Separator();
609
610 if (!patches_loaded_) {
611 ImGui::TextDisabled("No patches loaded");
612 ImGui::TextDisabled("Place .asm patches in assets/patches/");
613
614 if (ImGui::Button("Browse for Patches Folder...")) {
615 // TODO: File browser for patches folder
616 }
617 return;
618 }
619
620 // Status line
621 int enabled_count = patch_manager_.GetEnabledPatchCount();
622 int total_count = static_cast<int>(patch_manager_.patches().size());
623 ImGui::Text("Loaded: %d patches (%d enabled)", total_count, enabled_count);
624
625 ImGui::Spacing();
626
627 // Folder tabs
628 if (ImGui::BeginTabBar("##PatchFolders", ImGuiTabBarFlags_FittingPolicyScroll)) {
629 for (const auto& folder : patch_manager_.folders()) {
630 if (ImGui::BeginTabItem(folder.c_str())) {
631 selected_folder_ = folder;
632 DrawPatchList(folder);
633 ImGui::EndTabItem();
634 }
635 }
636 ImGui::EndTabBar();
637 }
638
639 ImGui::Spacing();
640 ImGui::Separator();
641
642 // Selected patch details
643 if (selected_patch_) {
645 } else {
646 ImGui::TextDisabled("Select a patch to view details");
647 }
648
649 ImGui::Spacing();
650 ImGui::Separator();
651
652 // Action buttons
653 if (ImGui::Button(ICON_MD_CHECK " Apply Patches to ROM")) {
654 if (rom_ && rom_->is_loaded()) {
656 if (!status.ok()) {
657 LOG_ERROR("Settings", "Failed to apply patches: %s", status.message());
658 } else {
659 LOG_INFO("Settings", "Applied %d patches successfully", enabled_count);
660 }
661 } else {
662 LOG_WARN("Settings", "No ROM loaded");
663 }
664 }
665 if (ImGui::IsItemHovered()) {
666 ImGui::SetTooltip("Apply all enabled patches to the loaded ROM");
667 }
668
669 ImGui::SameLine();
670 if (ImGui::Button(ICON_MD_SAVE " Save All")) {
671 auto status = patch_manager_.SaveAllPatches();
672 if (!status.ok()) {
673 LOG_ERROR("Settings", "Failed to save patches: %s", status.message());
674 }
675 }
676
677 if (ImGui::Button(ICON_MD_REFRESH " Reload Patches")) {
678 patches_loaded_ = false;
679 selected_patch_ = nullptr;
680 }
681}
682
683void SettingsPanel::DrawPatchList(const std::string& folder) {
684 auto patches = patch_manager_.GetPatchesInFolder(folder);
685
686 if (patches.empty()) {
687 ImGui::TextDisabled("No patches in this folder");
688 return;
689 }
690
691 // Use a child region for scrolling
692 float available_height = std::min(200.0f, patches.size() * 25.0f + 10.0f);
693 if (ImGui::BeginChild("##PatchList", ImVec2(0, available_height), true)) {
694 for (auto* patch : patches) {
695 ImGui::PushID(patch->filename().c_str());
696
697 bool enabled = patch->enabled();
698 if (ImGui::Checkbox("##Enabled", &enabled)) {
699 patch->set_enabled(enabled);
700 }
701
702 ImGui::SameLine();
703
704 // Highlight selected patch
705 bool is_selected = (selected_patch_ == patch);
706 if (ImGui::Selectable(patch->name().c_str(), is_selected)) {
707 selected_patch_ = patch;
708 }
709
710 ImGui::PopID();
711 }
712 }
713 ImGui::EndChild();
714}
715
717 if (!selected_patch_) return;
718
719 ImGui::Text("%s %s", ICON_MD_INFO, selected_patch_->name().c_str());
720
721 if (!selected_patch_->author().empty()) {
722 ImGui::TextDisabled("by %s", selected_patch_->author().c_str());
723 }
724
725 if (!selected_patch_->version().empty()) {
726 ImGui::SameLine();
727 ImGui::TextDisabled("v%s", selected_patch_->version().c_str());
728 }
729
730 // Description
731 if (!selected_patch_->description().empty()) {
732 ImGui::Spacing();
733 ImGui::TextWrapped("%s", selected_patch_->description().c_str());
734 }
735
736 // Parameters
737 auto& params = selected_patch_->mutable_parameters();
738 if (!params.empty()) {
739 ImGui::Spacing();
740 ImGui::Text("%s Parameters", ICON_MD_TUNE);
741 ImGui::Separator();
742
743 for (auto& param : params) {
744 DrawParameterWidget(&param);
745 }
746 }
747}
748
750 if (!param) return;
751
752 ImGui::PushID(param->define_name.c_str());
753
754 switch (param->type) {
758 int value = param->value;
759 const char* format = param->use_decimal ? "%d" : "$%X";
760
761 ImGui::Text("%s", param->display_name.c_str());
762 ImGui::SetNextItemWidth(100);
763 if (ImGui::InputInt("##Value", &value, 1, 16)) {
764 param->value = std::clamp(value, param->min_value, param->max_value);
765 }
766
767 // Show range hint
768 if (param->min_value != 0 || param->max_value != 0xFF) {
769 ImGui::SameLine();
770 ImGui::TextDisabled("(%d-%d)", param->min_value, param->max_value);
771 }
772 break;
773 }
774
776 bool checked = (param->value == param->checked_value);
777 if (ImGui::Checkbox(param->display_name.c_str(), &checked)) {
778 param->value = checked ? param->checked_value : param->unchecked_value;
779 }
780 break;
781 }
782
784 ImGui::Text("%s", param->display_name.c_str());
785 for (size_t i = 0; i < param->choices.size(); ++i) {
786 bool selected = (param->value == static_cast<int>(i));
787 if (ImGui::RadioButton(param->choices[i].c_str(), selected)) {
788 param->value = static_cast<int>(i);
789 }
790 }
791 break;
792 }
793
795 ImGui::Text("%s", param->display_name.c_str());
796 for (size_t i = 0; i < param->choices.size(); ++i) {
797 if (param->choices[i].empty() || param->choices[i] == "_EMPTY") {
798 continue;
799 }
800 bool bit_set = (param->value & (1 << i)) != 0;
801 if (ImGui::Checkbox(param->choices[i].c_str(), &bit_set)) {
802 if (bit_set) {
803 param->value |= (1 << i);
804 } else {
805 param->value &= ~(1 << i);
806 }
807 }
808 }
809 break;
810 }
811
813 ImGui::Text("%s", param->display_name.c_str());
814 // TODO: Implement item dropdown using game item names
815 ImGui::SetNextItemWidth(150);
816 if (ImGui::InputInt("Item ID", &param->value)) {
817 param->value = std::clamp(param->value, 0, 255);
818 }
819 break;
820 }
821 }
822
823 ImGui::PopID();
824 ImGui::Spacing();
825}
826
827} // namespace editor
828} // namespace yaze
bool is_loaded() const
Definition rom.h:128
const std::string & version() const
Definition asm_patch.h:86
std::vector< PatchParameter > & mutable_parameters()
Definition asm_patch.h:98
const std::string & author() const
Definition asm_patch.h:85
const std::string & description() const
Definition asm_patch.h:87
const std::string & name() const
Definition asm_patch.h:84
absl::Status ApplyEnabledPatches(Rom *rom)
Apply all enabled patches to a ROM.
absl::Status SaveAllPatches()
Save all patches to their files.
const std::vector< std::string > & folders() const
Get list of patch folder names.
int GetEnabledPatchCount() const
Get count of enabled patches.
std::vector< AsmPatch * > GetPatchesInFolder(const std::string &folder)
Get all patches in a specific folder.
const std::vector< std::unique_ptr< AsmPatch > > & patches() const
Get all loaded patches.
absl::Status LoadPatches(const std::string &patches_dir)
Load all patches from a directory structure.
std::vector< std::string > GetAllCategories(size_t session_id) const
std::vector< PanelDescriptor > GetPanelsInCategory(size_t session_id, const std::string &category) const
void DrawPatchList(const std::string &folder)
ShortcutManager * shortcut_manager_
void DrawParameterWidget(core::PatchParameter *param)
core::AsmPatch * selected_patch_
core::PatchManager patch_manager_
project::YazeProject * project_
std::vector< Shortcut > GetShortcutsByScope(Shortcut::Scope scope) const
bool UpdateShortcutKeys(const std::string &name, const std::vector< ImGuiKey > &keys)
void SetEnabled(bool enabled)
Enable or disable the status bar.
Definition status_bar.h:52
static ThemeManager & Get()
static absl::StatusOr< std::filesystem::path > FindAsset(const std::string &relative_path)
Find an asset file in multiple standard locations.
#define ICON_MD_FOLDER_OPEN
Definition icons.h:813
#define ICON_MD_SETTINGS
Definition icons.h:1699
#define ICON_MD_INFO
Definition icons.h:993
#define ICON_MD_MEMORY
Definition icons.h:1195
#define ICON_MD_FOLDER_SPECIAL
Definition icons.h:815
#define ICON_MD_CHECK
Definition icons.h:397
#define ICON_MD_TUNE
Definition icons.h:2022
#define ICON_MD_REFRESH
Definition icons.h:1572
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_LABEL
Definition icons.h:1053
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_SPEED
Definition icons.h:1817
#define ICON_MD_CASTLE
Definition icons.h:380
#define ICON_MD_EXTENSION
Definition icons.h:715
#define ICON_MD_KEYBOARD
Definition icons.h:1028
#define ICON_MD_PSYCHOLOGY
Definition icons.h:1523
#define ICON_MD_IMAGE
Definition icons.h:982
#define ICON_MD_TERMINAL
Definition icons.h:1951
#define ICON_MD_FLAG
Definition icons.h:784
#define ICON_MD_BUILD
Definition icons.h:328
#define ICON_MD_HORIZONTAL_RULE
Definition icons.h:960
#define ICON_MD_SAVE
Definition icons.h:1644
#define ICON_MD_FOLDER
Definition icons.h:809
#define ICON_MD_PALETTE
Definition icons.h:1370
#define ICON_MD_CLOUD
Definition icons.h:423
#define ICON_MD_CLOSE
Definition icons.h:418
#define ICON_MD_SMART_TOY
Definition icons.h:1781
#define ICON_MD_HISTORY
Definition icons.h:946
#define LOG_ERROR(category, format,...)
Definition log.h:109
#define LOG_WARN(category, format,...)
Definition log.h:107
#define LOG_INFO(category, format,...)
Definition log.h:105
std::vector< ImGuiKey > ParseShortcut(const std::string &shortcut)
std::string PrintShortcut(const std::vector< ImGuiKey > &keys)
void DrawFontManager()
Definition style.cc:1323
void SetPreferHmagicSpriteNames(bool prefer)
Definition sprite.cc:273
Represents a configurable parameter within an ASM patch.
Definition asm_patch.h:33
PatchParameterType type
Definition asm_patch.h:36
std::vector< std::string > choices
Definition asm_patch.h:43
std::unordered_map< std::string, std::string > panel_shortcuts
std::unordered_map< std::string, std::string > editor_shortcuts
std::unordered_map< std::string, std::string > global_shortcuts
void DrawZSCustomOverworldFlags(Rom *rom)
std::string git_repository
Definition project.h:123
std::string output_folder
Definition project.h:116
std::string symbols_filename
Definition project.h:101