yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
workspace_window_manager_support.cc
Go to the documentation of this file.
1#define IMGUI_DEFINE_MATH_OPERATORS
2
4
5#include <algorithm>
6#include <filesystem>
7#include <fstream>
8
10#include "imgui/imgui.h"
11#include "imgui/imgui_internal.h"
12#include "util/json.h"
13#include "util/log.h"
14#include "util/platform_paths.h"
15
16namespace yaze {
17namespace editor {
18
20 auto config_dir_result = util::PlatformPaths::GetConfigDirectory();
21 if (!config_dir_result.ok()) {
22 LOG_ERROR("WorkspaceWindowManager", "Failed to get config directory: %s",
23 config_dir_result.status().ToString().c_str());
24 return;
25 }
26
27 std::filesystem::path presets_file =
28 *config_dir_result / "layout_presets.json";
29
30 try {
31 yaze::Json j;
32 j["version"] = 1;
33 j["presets"] = yaze::Json::object();
34
35 for (const auto& [name, preset] : presets_) {
36 yaze::Json preset_json;
37 preset_json["name"] = preset.name;
38 preset_json["description"] = preset.description;
39 preset_json["visible_cards"] = preset.visible_cards;
40 j["presets"][name] = preset_json;
41 }
42
43 std::ofstream file(presets_file);
44 if (!file.is_open()) {
45 LOG_ERROR("WorkspaceWindowManager", "Failed to open file for writing: %s",
46 presets_file.string().c_str());
47 return;
48 }
49
50 file << j.dump(2);
51 file.close();
52
53 LOG_INFO("WorkspaceWindowManager", "Saved %zu presets to %s",
54 presets_.size(), presets_file.string().c_str());
55 } catch (const std::exception& e) {
56 LOG_ERROR("WorkspaceWindowManager", "Error saving presets: %s", e.what());
57 }
58}
59
61 auto config_dir_result = util::PlatformPaths::GetConfigDirectory();
62 if (!config_dir_result.ok()) {
63 LOG_WARN("WorkspaceWindowManager", "Failed to get config directory: %s",
64 config_dir_result.status().ToString().c_str());
65 return;
66 }
67
68 std::filesystem::path presets_file =
69 *config_dir_result / "layout_presets.json";
70
71 if (!util::PlatformPaths::Exists(presets_file)) {
72 LOG_INFO("WorkspaceWindowManager", "No presets file found at %s",
73 presets_file.string().c_str());
74 return;
75 }
76
77 try {
78 std::ifstream file(presets_file);
79 if (!file.is_open()) {
80 LOG_WARN("WorkspaceWindowManager", "Failed to open presets file: %s",
81 presets_file.string().c_str());
82 return;
83 }
84
85 yaze::Json j;
86 file >> j;
87 file.close();
88
89 if (!j.contains("presets")) {
90 LOG_WARN("WorkspaceWindowManager", "Invalid presets file format");
91 return;
92 }
93
94 size_t loaded_count = 0;
95 for (auto& [name, preset_json] : j["presets"].items()) {
96 WorkspacePreset preset;
97 preset.name = preset_json.value("name", name);
98 preset.description = preset_json.value("description", "");
99
100 if (preset_json.contains("visible_cards")) {
101 yaze::Json visible_cards = preset_json["visible_cards"];
102 if (visible_cards.is_array()) {
103 for (const auto& card : visible_cards) {
104 if (card.is_string()) {
105 preset.visible_cards.push_back(card.get<std::string>());
106 }
107 }
108 }
109 }
110
111 presets_[name] = preset;
112 loaded_count++;
113 }
114
115 LOG_INFO("WorkspaceWindowManager", "Loaded %zu presets from %s",
116 loaded_count, presets_file.string().c_str());
117 } catch (const std::exception& e) {
118 LOG_ERROR("WorkspaceWindowManager", "Error loading presets: %s", e.what());
119 }
120}
121
123 const std::string& category) {
124 auto it = browser_state_.category_file_browsers.find(category);
125 if (it != browser_state_.category_file_browsers.end()) {
126 return it->second.get();
127 }
128 return nullptr;
129}
130
131void WorkspaceWindowManager::EnableFileBrowser(const std::string& category,
132 const std::string& root_path) {
133 if (browser_state_.category_file_browsers.find(category) ==
135 auto browser = std::make_unique<FileBrowser>();
136
137 browser->SetFileClickedCallback([this, category](const std::string& path) {
138 if (on_file_clicked_) {
139 on_file_clicked_(category, path);
140 }
143 }
144 });
145
146 if (!root_path.empty()) {
147 browser->SetRootPath(root_path);
148 }
149
150 if (category == "Assembly") {
151 browser->SetFileFilter({".asm", ".s", ".65c816", ".inc", ".h"});
152 }
153
154 browser_state_.category_file_browsers[category] = std::move(browser);
155 LOG_INFO("WorkspaceWindowManager", "Enabled file browser for category: %s",
156 category.c_str());
157 }
158}
159
160void WorkspaceWindowManager::DisableFileBrowser(const std::string& category) {
162}
163
164bool WorkspaceWindowManager::HasFileBrowser(const std::string& category) const {
165 return browser_state_.category_file_browsers.find(category) !=
167}
168
169void WorkspaceWindowManager::SetFileBrowserPath(const std::string& category,
170 const std::string& path) {
171 auto it = browser_state_.category_file_browsers.find(category);
172 if (it != browser_state_.category_file_browsers.end()) {
173 it->second->SetRootPath(path);
174 }
175}
176
178 size_t session_id, const std::string& base_card_id, bool pinned) {
179 const std::string canonical_base_id = ResolveBaseWindowId(base_card_id);
180 std::string prefixed_id = GetPrefixedWindowId(session_id, canonical_base_id);
181 if (prefixed_id.empty()) {
182 prefixed_id = MakeWindowId(session_id, canonical_base_id);
183 }
184 pinned_panels_[prefixed_id] = pinned;
185}
186
188 size_t session_id, const std::string& base_card_id) const {
189 const std::string canonical_base_id = ResolveBaseWindowId(base_card_id);
190 std::string prefixed_id = GetPrefixedWindowId(session_id, canonical_base_id);
191 if (prefixed_id.empty()) {
192 prefixed_id = MakeWindowId(session_id, canonical_base_id);
193 }
194 auto it = pinned_panels_.find(prefixed_id);
195 return it != pinned_panels_.end() && it->second;
196}
197
199 size_t session_id) const {
200 std::vector<std::string> result;
201 const auto* session_panels = FindSessionWindowIds(session_id);
202 if (!session_panels) {
203 return result;
204 }
205 for (const auto& [panel_id, pinned] : pinned_panels_) {
206 if (!pinned) {
207 continue;
208 }
209 if (std::find(session_panels->begin(), session_panels->end(), panel_id) !=
210 session_panels->end()) {
211 const std::string base_id = GetBaseIdForPrefixedId(session_id, panel_id);
212 result.push_back(base_id.empty() ? panel_id : base_id);
213 }
214 }
215 return result;
216}
217
219 size_t session_id, const std::string& base_card_id,
220 const std::string& prefixed_id) {
221 auto pinned_it = pinned_panels_.find(prefixed_id);
222 if (pinned_it == pinned_panels_.end()) {
223 return;
224 }
225
226 bool has_other_live_instance = false;
227 for (const auto& [mapped_session, mapping] : session_card_mapping_) {
228 (void)mapped_session;
229 auto mapping_it = mapping.find(base_card_id);
230 if (mapping_it == mapping.end()) {
231 continue;
232 }
233 if (mapping_it->second == prefixed_id) {
234 continue;
235 }
236 if (cards_.find(mapping_it->second) != cards_.end()) {
237 has_other_live_instance = true;
238 break;
239 }
240 }
241
242 if (!has_other_live_instance) {
243 pending_pinned_base_ids_[base_card_id] = pinned_it->second;
244 }
245}
246
248 const std::string& base_card_id, bool pinned) {
249 SetWindowPinnedImpl(active_session_, base_card_id, pinned);
250}
251
253 const std::string& base_card_id) const {
254 return IsWindowPinnedImpl(active_session_, base_card_id);
255}
256
257std::vector<std::string> WorkspaceWindowManager::GetPinnedWindowsImpl() const {
259}
260
262WorkspaceWindowManager::ValidateWindow(const std::string& card_id) const {
264 result.card_id = card_id;
265
266 auto it = cards_.find(card_id);
267 if (it == cards_.end()) {
268 result.expected_title = "";
269 result.found_in_imgui = false;
270 result.message = "Panel not registered";
271 return result;
272 }
273
274 const WindowDescriptor& info = it->second;
275 result.expected_title = GetWindowNameImpl(info);
276
277 if (result.expected_title.empty()) {
278 result.found_in_imgui = false;
279 result.message = "FAIL - Missing window name";
280 return result;
281 }
282
283 ImGuiWindow* window = ImGui::FindWindowByName(result.expected_title.c_str());
284 result.found_in_imgui = (window != nullptr);
285
286 if (result.found_in_imgui) {
287 result.message = "OK - Window found";
288 } else {
289 result.message = "FAIL - No window with name: " + result.expected_title;
290 }
291
292 return result;
293}
294
295std::vector<WorkspaceWindowManager::WindowValidationResult>
297 std::vector<WindowValidationResult> results;
298 results.reserve(cards_.size());
299
300 for (const auto& [card_id, info] : cards_) {
301 (void)info;
302 results.push_back(ValidateWindow(card_id));
303 }
304
305 return results;
306}
307
308} // namespace editor
309} // namespace yaze
bool is_array() const
Definition json.h:58
static Json object()
Definition json.h:34
items_view items()
Definition json.h:88
std::string dump(int=-1, char=' ', bool=false, int=0) const
Definition json.h:91
bool contains(const std::string &) const
Definition json.h:53
File system browser for the sidebar.
void EnableFileBrowser(const std::string &category, const std::string &root_path="")
bool IsWindowPinnedImpl(size_t session_id, const std::string &base_card_id) const
std::string ResolveBaseWindowId(const std::string &panel_id) const
std::unordered_map< std::string, WindowDescriptor > & cards_
std::string GetPrefixedWindowId(size_t session_id, const std::string &base_id) const
std::vector< std::string > * FindSessionWindowIds(size_t session_id)
void RememberPinnedStateForRemovedWindow(size_t session_id, const std::string &base_card_id, const std::string &prefixed_id)
std::string GetBaseIdForPrefixedId(size_t session_id, const std::string &prefixed_id) const
FileBrowser * GetFileBrowser(const std::string &category)
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > & session_card_mapping_
std::unordered_map< std::string, bool > & pending_pinned_base_ids_
std::function< void(const std::string &, const std::string &) on_file_clicked_)
std::vector< std::string > GetPinnedWindowsImpl() const
std::unordered_map< std::string, WorkspacePreset > presets_
bool HasFileBrowser(const std::string &category) const
void SetWindowPinnedImpl(size_t session_id, const std::string &base_card_id, bool pinned)
std::string GetWindowNameImpl(size_t session_id, const std::string &base_card_id) const
void SetFileBrowserPath(const std::string &category, const std::string &path)
std::string MakeWindowId(size_t session_id, const std::string &base_id) const
std::vector< WindowValidationResult > ValidateWindows() const
std::unordered_map< std::string, bool > & pinned_panels_
WindowValidationResult ValidateWindow(const std::string &card_id) const
static absl::StatusOr< std::filesystem::path > GetConfigDirectory()
Get the user-specific configuration directory for YAZE.
static bool Exists(const std::filesystem::path &path)
Check if a file or directory exists.
#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
Metadata for a dockable editor window (formerly PanelInfo)
std::unordered_map< std::string, std::unique_ptr< FileBrowser > > category_file_browsers