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
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(ImVec4(0.5f, 0.8f, 1.0f, 1.0f),
120 "Space > %s", current_prefix_.c_str());
121 ImGui::Separator();
122 } else {
123 ImGui::TextColored(ImVec4(0.5f, 0.8f, 1.0f, 1.0f), "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, ImGuiTableFlags_SizingStretchProp)) {
141 int colorIndex = 0;
142 for (const auto &[shortcut, group] : commands_) {
143 ImGui::TableNextColumn();
144 ImGui::TextColored(colors[colorIndex % 6],
145 "%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],
165 "%c: %s",
166 cmd.mnemonic,
167 cmd.name.c_str());
168 colorIndex++;
169 }
170 ImGui::EndTable();
171 }
172 } else {
173 ImGui::TextDisabled("No subcommands available");
174 }
175 }
176 }
177
178 ImGui::EndPopup();
179 } else {
180 whichkey_active_ = false;
181 current_prefix_.clear();
182 }
183}
184
185// Handle keyboard input for WhichKey navigation
187 if (!whichkey_active_) return;
188
189 // Check for prefix keys (w, l, f, b, s, t, etc.)
190 for (const auto& [shortcut, group] : commands_) {
191 ImGuiKey key = gui::MapKeyToImGuiKey(group.main_command.mnemonic);
192 if (key != ImGuiKey_COUNT && ImGui::IsKeyPressed(key)) {
193 if (current_prefix_.empty()) {
194 // Enter submenu
195 current_prefix_ = shortcut;
196 whichkey_timer_ = 0.0f;
197 return;
198 } else {
199 // Execute subcommand
200 auto it = commands_.find(current_prefix_);
201 if (it != commands_.end()) {
202 for (const auto& [subkey, cmd] : it->second.subcommands) {
203 if (cmd.mnemonic == group.main_command.mnemonic) {
204 if (cmd.command) {
205 cmd.command();
206 }
207 whichkey_active_ = false;
208 current_prefix_.clear();
209 ImGui::CloseCurrentPopup();
210 return;
211 }
212 }
213 }
214 }
215 }
216 }
217}
218
219} // namespace editor
220} // 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:343
Main namespace for the application.
Definition controller.cc:20