yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
command_manager.cc
Go to the documentation of this file.
1#include "command_manager.h"
2
3#include <fstream>
4
7#include "imgui/imgui.h"
8
9namespace yaze {
10namespace editor {
11
12// When the player presses Space, a popup will appear fixed to the bottom of the
13// ImGui window with a list of the available key commands which can be used.
15 if (ImGui::IsKeyPressed(ImGuiKey_Space)) {
16 ImGui::OpenPopup("WhichKey");
17 }
18
19 ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 100),
20 ImGuiCond_Always);
21 ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, 100),
22 ImGuiCond_Always);
23 if (ImGui::BeginPopup("WhichKey")) {
24 // ESC to close the popup
25 if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
26 ImGui::CloseCurrentPopup();
27 }
28
29 const ImVec4 colors[] = {
30 ImVec4(0.8f, 0.2f, 0.2f, 1.0f), // Soft Red
31 ImVec4(0.2f, 0.8f, 0.2f, 1.0f), // Soft Green
32 ImVec4(0.2f, 0.2f, 0.8f, 1.0f), // Soft Blue
33 ImVec4(0.8f, 0.8f, 0.2f, 1.0f), // Soft Yellow
34 ImVec4(0.8f, 0.2f, 0.8f, 1.0f), // Soft Magenta
35 ImVec4(0.2f, 0.8f, 0.8f, 1.0f) // Soft Cyan
36 };
37 const int numColors = sizeof(colors) / sizeof(colors[0]);
38 int colorIndex = 0;
39
40 if (ImGui::BeginTable("CommandsTable", commands_.size(),
41 ImGuiTableFlags_SizingStretchProp)) {
42 for (const auto& [shortcut, group] : commands_) {
43 ImGui::TableNextColumn();
44 ImGui::TextColored(colors[colorIndex], "%c: %s",
45 group.main_command.mnemonic,
46 group.main_command.name.c_str());
47 colorIndex = (colorIndex + 1) % numColors;
48 }
49 ImGui::EndTable();
50 }
51 ImGui::EndPopup();
52 }
53}
54
55void CommandManager::SaveKeybindings(const std::string& filepath) {
56 std::ofstream out(filepath);
57 if (out.is_open()) {
58 for (const auto& [shortcut, group] : commands_) {
59 out << shortcut << " " << group.main_command.mnemonic << " "
60 << group.main_command.name << " " << group.main_command.desc << "\n";
61 }
62 out.close();
63 }
64}
65
66void CommandManager::LoadKeybindings(const std::string& filepath) {
67 std::ifstream in(filepath);
68 if (in.is_open()) {
69 commands_.clear();
70 std::string shortcut, name, desc;
71 char mnemonic;
72 while (in >> shortcut >> mnemonic >> name >> desc) {
73 commands_[shortcut].main_command = {nullptr, mnemonic, name, desc};
74 }
75 in.close();
76 }
77}
78
79// Enhanced hierarchical WhichKey with Spacemacs-style navigation
81 // Activate on Space key
82 if (ImGui::IsKeyPressed(ImGuiKey_Space) && current_prefix_.empty()) {
83 whichkey_active_ = true;
84 whichkey_timer_ = 0.0f;
85 ImGui::OpenPopup("WhichKeyHierarchical");
86 }
87
88 // ESC to close or go back
89 if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
90 if (!current_prefix_.empty()) {
91 current_prefix_.clear(); // Go back to root
92 } else {
93 whichkey_active_ = false;
94 ImGui::CloseCurrentPopup();
95 }
96 }
97
98 // Position at bottom of screen
99 ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 150),
100 ImGuiCond_Always);
101 ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, 150),
102 ImGuiCond_Always);
103
104 if (ImGui::BeginPopup("WhichKeyHierarchical")) {
105 whichkey_active_ = true;
106
107 // Update timer for auto-close
108 whichkey_timer_ += ImGui::GetIO().DeltaTime;
109 if (whichkey_timer_ > 5.0f) { // Auto-close after 5 seconds
110 whichkey_active_ = false;
111 current_prefix_.clear();
112 ImGui::CloseCurrentPopup();
113 ImGui::EndPopup();
114 return;
115 }
116
117 // Show breadcrumb navigation
118 if (!current_prefix_.empty()) {
119 ImGui::TextColored(gui::GetInfoColor(), "Space > %s",
120 current_prefix_.c_str());
121 ImGui::Separator();
122 } else {
123 ImGui::TextColored(gui::GetInfoColor(), "Space > ...");
124 ImGui::Separator();
125 }
126
127 // Color palette for visual grouping
128 const ImVec4 colors[] = {
129 ImVec4(0.8f, 0.2f, 0.2f, 1.0f), // Red - Window
130 ImVec4(0.2f, 0.8f, 0.2f, 1.0f), // Green - Buffer
131 ImVec4(0.2f, 0.2f, 0.8f, 1.0f), // Blue - File
132 ImVec4(0.8f, 0.8f, 0.2f, 1.0f), // Yellow - Session
133 ImVec4(0.8f, 0.2f, 0.8f, 1.0f), // Magenta - Layout
134 ImVec4(0.2f, 0.8f, 0.8f, 1.0f) // Cyan - Theme
135 };
136
137 // Show commands based on current navigation level
138 if (current_prefix_.empty()) {
139 // Root level - show main groups
140 if (ImGui::BeginTable("RootCommands", 6,
141 ImGuiTableFlags_SizingStretchProp)) {
142 int colorIndex = 0;
143 for (const auto& [shortcut, group] : commands_) {
144 ImGui::TableNextColumn();
145 ImGui::TextColored(colors[colorIndex % 6], "%c: %s",
146 group.main_command.mnemonic,
147 group.main_command.name.c_str());
148 colorIndex++;
149 }
150 ImGui::EndTable();
151 }
152 } else {
153 // Submenu level - show subcommands
154 auto it = commands_.find(current_prefix_);
155 if (it != commands_.end()) {
156 const auto& group = it->second;
157 if (!group.subcommands.empty()) {
158 if (ImGui::BeginTable("Subcommands",
159 std::min(6, (int)group.subcommands.size()),
160 ImGuiTableFlags_SizingStretchProp)) {
161 int colorIndex = 0;
162 for (const auto& [key, cmd] : group.subcommands) {
163 ImGui::TableNextColumn();
164 ImGui::TextColored(colors[colorIndex % 6], "%c: %s", cmd.mnemonic,
165 cmd.name.c_str());
166 colorIndex++;
167 }
168 ImGui::EndTable();
169 }
170 } else {
171 ImGui::TextDisabled("No subcommands available");
172 }
173 }
174 }
175
176 ImGui::EndPopup();
177 } else {
178 whichkey_active_ = false;
179 current_prefix_.clear();
180 }
181}
182
183// Handle keyboard input for WhichKey navigation
185 if (!whichkey_active_)
186 return;
187
188 // Check for prefix keys (w, l, f, b, s, t, etc.)
189 for (const auto& [shortcut, group] : commands_) {
190 ImGuiKey key = gui::MapKeyToImGuiKey(group.main_command.mnemonic);
191 if (key != ImGuiKey_COUNT && ImGui::IsKeyPressed(key)) {
192 if (current_prefix_.empty()) {
193 // Enter submenu
194 current_prefix_ = shortcut;
195 whichkey_timer_ = 0.0f;
196 return;
197 } else {
198 // Execute subcommand
199 auto it = commands_.find(current_prefix_);
200 if (it != commands_.end()) {
201 for (const auto& [subkey, cmd] : it->second.subcommands) {
202 if (cmd.mnemonic == group.main_command.mnemonic) {
203 if (cmd.command) {
204 cmd.command();
205 }
206 whichkey_active_ = false;
207 current_prefix_.clear();
208 ImGui::CloseCurrentPopup();
209 return;
210 }
211 }
212 }
213 }
214 }
215 }
216}
217
218} // namespace editor
219} // namespace yaze
void LoadKeybindings(const std::string &filepath)
std::unordered_map< std::string, CommandGroup > commands_
void SaveKeybindings(const std::string &filepath)
ImVec4 GetInfoColor()
Definition ui_helpers.cc:63
ImGuiKey MapKeyToImGuiKey(char key)
Definition input.cc:577