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