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