yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
workspace_manager.cc
Go to the documentation of this file.
1#define IMGUI_DEFINE_MATH_OPERATORS
2
4
5#include "absl/strings/str_format.h"
10#include "imgui/imgui.h"
11#include "imgui/imgui_internal.h"
12#include "rom/rom.h"
13#include "util/file_util.h"
14#include "util/log.h"
15#include "util/platform_paths.h"
16
17namespace yaze {
18namespace editor {
19
20absl::Status WorkspaceManager::SaveWorkspaceLayout(const std::string& name) {
21 if (layout_manager_) {
22 const std::string layout_name = name.empty() ? "workspace" : name;
24 }
25 if (toast_manager_) {
26 toast_manager_->Show("Layout saved", ToastType::kSuccess);
27 }
28 return absl::OkStatus();
29}
30
31absl::Status WorkspaceManager::LoadWorkspaceLayout(const std::string& name) {
32 bool loaded = false;
33 if (layout_manager_) {
34 const std::string layout_name = name.empty() ? "workspace" : name;
35 if (layout_manager_->HasLayout(layout_name)) {
36 layout_manager_->LoadLayout(layout_name);
37 loaded = true;
38 } else if (toast_manager_) {
39 toast_manager_->Show("Layout not found", ToastType::kWarning);
40 }
41 }
42 if (toast_manager_ && loaded) {
43 toast_manager_->Show("Layout loaded", ToastType::kSuccess);
44 }
45 return absl::OkStatus();
46}
47
48void WorkspaceManager::SaveWorkspacePreset(const std::string& name) {
49 if (name.empty())
50 return;
51
52 std::filesystem::path workspace_dir = std::filesystem::current_path();
53 auto workspace_dir_status =
55 if (workspace_dir_status.ok()) {
56 workspace_dir = *workspace_dir_status;
57 }
58
59 if (layout_manager_) {
61 } else {
62 std::filesystem::path ini_path =
63 workspace_dir / absl::StrFormat("workspace_%s.ini", name.c_str());
64 ImGui::SaveIniSettingsToDisk(ini_path.string().c_str());
65 }
66
68 // RefreshWorkspacePresets(); // This will be implemented next
69 }
70
71 if (std::find(workspace_presets_.begin(), workspace_presets_.end(), name) ==
72 workspace_presets_.end()) {
73 workspace_presets_.emplace_back(name);
74 try {
75 std::ostringstream ss;
76 for (const auto& n : workspace_presets_)
77 ss << n << "\n";
78 std::filesystem::path presets_path =
79 workspace_dir / "workspace_presets.txt";
80 util::SaveFile(presets_path.string(), ss.str());
81 } catch (const std::exception& e) {
82 // LOG_WARN("WorkspaceManager", "Failed to save presets: %s", e.what());
83 }
84 }
86 if (toast_manager_) {
87 toast_manager_->Show(absl::StrFormat("Preset '%s' saved", name),
89 }
90}
91
92void WorkspaceManager::LoadWorkspacePreset(const std::string& name) {
93 if (name.empty())
94 return;
95
96 if (layout_manager_) {
97 if (layout_manager_->HasLayout(name)) {
100 if (toast_manager_) {
101 toast_manager_->Show(absl::StrFormat("Preset '%s' loaded", name),
103 }
104 return;
105 }
106 }
107 std::filesystem::path workspace_dir = std::filesystem::current_path();
108 auto workspace_dir_status =
110 if (workspace_dir_status.ok()) {
111 workspace_dir = *workspace_dir_status;
112 }
113 std::filesystem::path ini_path =
114 workspace_dir / absl::StrFormat("workspace_%s.ini", name.c_str());
115 ImGui::LoadIniSettingsFromDisk(ini_path.string().c_str());
117 if (toast_manager_) {
118 toast_manager_->Show(absl::StrFormat("Preset '%s' loaded", name),
120 }
121}
122
124 try {
125 std::vector<std::string> new_presets;
126 auto workspace_dir =
128 if (workspace_dir.ok()) {
129 std::filesystem::path presets_path =
130 *workspace_dir / "workspace_presets.txt";
131 auto data = util::LoadFile(presets_path.string());
132 if (!data.empty()) {
133 std::istringstream ss(data);
134 std::string name;
135 while (std::getline(ss, name)) {
136 name.erase(0, name.find_first_not_of(" \t\r\n"));
137 name.erase(name.find_last_not_of(" \t\r\n") + 1);
138 if (!name.empty() && name.length() < 256) {
139 new_presets.emplace_back(std::move(name));
140 }
141 }
142 }
143 }
144 workspace_presets_ = std::move(new_presets);
146 } catch (const std::exception& e) {
147 // LOG_ERROR("WorkspaceManager", "Error refreshing presets: %s", e.what());
148 workspace_presets_.clear();
150 }
151}
152
155 apply_preset_callback_("Developer");
156 } else if (toast_manager_) {
157 toast_manager_->Show("Layout presets not available", ToastType::kWarning);
158 }
159}
160
163 apply_preset_callback_("Designer");
164 } else if (toast_manager_) {
165 toast_manager_->Show("Layout presets not available", ToastType::kWarning);
166 }
167}
168
171 apply_preset_callback_("Modder");
172 } else if (toast_manager_) {
173 toast_manager_->Show("Layout presets not available", ToastType::kWarning);
174 }
175}
176
178 if (window_manager_) {
180 }
181 if (toast_manager_) {
182 toast_manager_->Show("All windows shown", ToastType::kInfo);
183 }
184}
185
187 if (window_manager_) {
189 }
190 if (toast_manager_) {
191 toast_manager_->Show("All windows hidden", ToastType::kInfo);
192 }
193}
194
196 // Use ImGui internal API to maximize current window
197 ImGuiWindow* window = ImGui::GetCurrentWindowRead();
198 if (window && window->DockNode && layout_manager_) {
199 if (ImGuiDockNode* central = ImGui::DockBuilderGetCentralNode(
201 ImGui::DockBuilderDockWindow(window->Name, central->ID);
202 }
203 }
204 if (toast_manager_) {
205 toast_manager_->Show("Window maximized", ToastType::kInfo);
206 }
207}
208
210 // Reset all window sizes - ImGui will auto-restore based on docking
211 ImGuiContext* ctx = ImGui::GetCurrentContext();
212 if (ctx) {
213 for (ImGuiWindow* window : ctx->Windows) {
214 if (window && !window->Collapsed) {
215 ImGui::SetWindowSize(window->Name, ImVec2(0, 0)); // Auto-size
216 }
217 }
218 }
219 if (toast_manager_) {
220 toast_manager_->Show("All windows restored", ToastType::kInfo);
221 }
222}
223
225 // Close all windows that are not docked
226 ImGuiContext* ctx = ImGui::GetCurrentContext();
227 if (ctx) {
228 for (ImGuiWindow* window : ctx->Windows) {
229 if (window && !window->DockNode && !window->Collapsed) {
230 window->Hidden = true;
231 }
232 }
233 }
234 if (toast_manager_) {
235 toast_manager_->Show("Floating windows closed", ToastType::kInfo);
236 }
237}
238
240 if (!sessions_)
241 return 0;
242
243 size_t count = 0;
244 for (const auto& session : *sessions_) {
245 if (session.rom && session.rom->is_loaded()) {
246 count++;
247 }
248 }
249 return count;
250}
251
252bool WorkspaceManager::HasDuplicateSession(const std::string& filepath) const {
253 if (!sessions_)
254 return false;
255
256 for (const auto& session : *sessions_) {
257 if (session.filepath == filepath && session.rom &&
258 session.rom->is_loaded()) {
259 return true;
260 }
261 }
262 return false;
263}
264
265// Window navigation operations
267 ImGuiContext* ctx = ImGui::GetCurrentContext();
268 if (ctx && ctx->NavWindow) {
269 ImGui::FocusWindow(ImGui::FindWindowByName(ctx->NavWindow->Name));
270 }
271 // TODO: Implement proper window cycling
272}
273
275 // TODO: Implement window cycling backward
276}
277
279 ImGuiWindow* window = ImGui::GetCurrentWindowRead();
280 if (window && window->DockNode) {
281 ImGuiID node_id = window->DockNode->ID;
282 ImGuiID out_id_at_dir = 0;
283 ImGuiID out_id_at_opposite_dir = 0;
284 ImGui::DockBuilderSplitNode(node_id, ImGuiDir_Down, 0.5f, &out_id_at_dir,
285 &out_id_at_opposite_dir);
286 }
287}
288
290 ImGuiWindow* window = ImGui::GetCurrentWindowRead();
291 if (window && window->DockNode) {
292 ImGuiID node_id = window->DockNode->ID;
293 ImGuiID out_id_at_dir = 0;
294 ImGuiID out_id_at_opposite_dir = 0;
295 ImGui::DockBuilderSplitNode(node_id, ImGuiDir_Right, 0.5f, &out_id_at_dir,
296 &out_id_at_opposite_dir);
297 }
298}
299
301 ImGuiWindow* window = ImGui::GetCurrentWindowRead();
302 if (window) {
303 window->Hidden = true;
304 }
305}
306
307} // namespace editor
308} // namespace yaze
void LoadLayout(const std::string &name)
Load a saved layout by name.
void SaveCurrentLayout(const std::string &name, bool persist=true)
Save the current layout with a custom name.
bool HasLayout(const std::string &name) const
Check if a layout exists.
ImGuiID GetMainDockspaceId() const
Get the cached main dockspace ID.
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f, std::string action_label={}, std::function< void()> on_action=nullptr)
void SaveWorkspacePreset(const std::string &name)
bool HasDuplicateSession(const std::string &filepath) const
std::function< void(const std::string &) apply_preset_callback_)
std::vector< std::string > workspace_presets_
std::deque< SessionInfo > * sessions_
void LoadWorkspacePreset(const std::string &name)
absl::Status SaveWorkspaceLayout(const std::string &name="")
WorkspaceWindowManager * window_manager_
absl::Status LoadWorkspaceLayout(const std::string &name="")
static absl::StatusOr< std::filesystem::path > GetAppDataSubdirectory(const std::string &subdir)
Get a subdirectory within the app data folder.
void SaveFile(const std::string &filename, const std::string &contents)
Definition file_util.cc:96
std::string LoadFile(const std::string &filename)
Loads the entire contents of a file into a string.
Definition file_util.cc:63