yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
layout_manager.cc
Go to the documentation of this file.
2
5#include "imgui/imgui.h"
6#include "imgui/imgui_internal.h"
7#include "util/log.h"
8
9namespace yaze {
10namespace editor {
11
12namespace {
13
14// Helper function to show default cards from LayoutPresets
16 if (!registry) return;
17
18 auto default_panels = LayoutPresets::GetDefaultPanels(type);
19 for (const auto& panel_id : default_panels) {
20 registry->ShowPanel(panel_id);
21 }
22
23 LOG_INFO("LayoutManager", "Showing %zu default panels for editor type %d",
24 default_panels.size(), static_cast<int>(type));
25}
26
27} // namespace
28
30 ImGuiID dockspace_id) {
31 // Don't reinitialize if already set up
32 if (IsLayoutInitialized(type)) {
33 LOG_INFO("LayoutManager",
34 "Layout for editor type %d already initialized, skipping",
35 static_cast<int>(type));
36 return;
37 }
38
39 // Store dockspace ID and current editor type for potential rebuilds
40 last_dockspace_id_ = dockspace_id;
42
43 LOG_INFO("LayoutManager", "Initializing layout for editor type %d",
44 static_cast<int>(type));
45
46 // Clear existing layout for this dockspace
47 ImGui::DockBuilderRemoveNode(dockspace_id);
48 ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace);
49 ImGui::DockBuilderSetNodeSize(dockspace_id, ImGui::GetMainViewport()->WorkSize);
50
51 // Build layout based on editor type using generic builder
52 BuildLayoutFromPreset(type, dockspace_id);
53
54 // Show default cards from LayoutPresets (single source of truth)
55 ShowDefaultPanelsForEditor(panel_manager_, type);
56
57 // Finalize the layout
58 ImGui::DockBuilderFinish(dockspace_id);
59
60 // Mark as initialized
62}
63
64void LayoutManager::RebuildLayout(EditorType type, ImGuiID dockspace_id) {
65 // Validate dockspace exists
66 ImGuiDockNode* node = ImGui::DockBuilderGetNode(dockspace_id);
67 if (!node) {
68 LOG_ERROR("LayoutManager",
69 "Cannot rebuild layout: dockspace ID %u not found", dockspace_id);
70 return;
71 }
72
73 LOG_INFO("LayoutManager", "Forcing rebuild of layout for editor type %d",
74 static_cast<int>(type));
75
76 // Store dockspace ID and current editor type
77 last_dockspace_id_ = dockspace_id;
79
80 // Clear the layout initialization flag to force rebuild
81 layouts_initialized_[type] = false;
82
83 // Clear existing layout for this dockspace
84 ImGui::DockBuilderRemoveNode(dockspace_id);
85 ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace);
86 ImGui::DockBuilderSetNodeSize(dockspace_id, ImGui::GetMainViewport()->WorkSize);
87
88 // Build layout based on editor type using generic builder
89 BuildLayoutFromPreset(type, dockspace_id);
90
91 // Show default cards from LayoutPresets (single source of truth)
92 ShowDefaultPanelsForEditor(panel_manager_, type);
93
94 // Finalize the layout
95 ImGui::DockBuilderFinish(dockspace_id);
96
97 // Mark as initialized
99
100 LOG_INFO("LayoutManager", "Layout rebuild complete for editor type %d",
101 static_cast<int>(type));
102}
103
104namespace {
105
107 float left = 0.22f;
108 float right = 0.25f;
109 float bottom = 0.25f;
110 float top = 0.18f;
111 float vertical_split = 0.50f;
112};
113
115 ImGuiID center = 0;
116 ImGuiID left = 0;
117 ImGuiID right = 0;
118 ImGuiID bottom = 0;
119 ImGuiID top = 0;
120 ImGuiID left_top = 0;
121 ImGuiID left_bottom = 0;
122 ImGuiID right_top = 0;
123 ImGuiID right_bottom = 0;
124};
125
127 bool left = false;
128 bool right = false;
129 bool bottom = false;
130 bool top = false;
131 bool left_top = false;
132 bool left_bottom = false;
133 bool right_top = false;
134 bool right_bottom = false;
135};
136
138 DockSplitNeeds needs{};
139 for (const auto& [_, pos] : preset.panel_positions) {
140 switch (pos) {
142 needs.left = true;
143 break;
145 needs.right = true;
146 break;
148 needs.bottom = true;
149 break;
151 needs.top = true;
152 break;
154 needs.left = true;
155 needs.left_top = true;
156 break;
158 needs.left = true;
159 needs.left_bottom = true;
160 break;
162 needs.right = true;
163 needs.right_top = true;
164 break;
166 needs.right = true;
167 needs.right_bottom = true;
168 break;
170 default:
171 break;
172 }
173 }
174 return needs;
175}
176
177DockNodeIds BuildDockTree(ImGuiID dockspace_id, const DockSplitNeeds& needs,
178 const DockSplitConfig& cfg) {
179 DockNodeIds ids{};
180 ids.center = dockspace_id;
181
182 if (needs.left) {
183 ids.left = ImGui::DockBuilderSplitNode(ids.center, ImGuiDir_Left, cfg.left,
184 nullptr, &ids.center);
185 }
186 if (needs.right) {
187 ids.right = ImGui::DockBuilderSplitNode(ids.center, ImGuiDir_Right,
188 cfg.right, nullptr, &ids.center);
189 }
190 if (needs.bottom) {
191 ids.bottom = ImGui::DockBuilderSplitNode(ids.center, ImGuiDir_Down,
192 cfg.bottom, nullptr, &ids.center);
193 }
194 if (needs.top) {
195 ids.top = ImGui::DockBuilderSplitNode(ids.center, ImGuiDir_Up, cfg.top,
196 nullptr, &ids.center);
197 }
198
199 if (ids.left && (needs.left_top || needs.left_bottom)) {
200 ids.left_bottom = ImGui::DockBuilderSplitNode(
201 ids.left, ImGuiDir_Down, cfg.vertical_split, nullptr, &ids.left_top);
202 }
203
204 if (ids.right && (needs.right_top || needs.right_bottom)) {
205 ids.right_bottom = ImGui::DockBuilderSplitNode(
206 ids.right, ImGuiDir_Down, cfg.vertical_split, nullptr, &ids.right_top);
207 }
208
209 return ids;
210}
211
212} // namespace
213
214void LayoutManager::BuildLayoutFromPreset(EditorType type, ImGuiID dockspace_id) {
215 auto preset = LayoutPresets::GetDefaultPreset(type);
216
217 if (!panel_manager_) {
218 LOG_WARN("LayoutManager",
219 "PanelManager not available, skipping dock layout for type %d",
220 static_cast<int>(type));
221 return;
222 }
223
224 const size_t session_id =
226
227 DockSplitNeeds needs = ComputeSplitNeeds(preset);
228 DockSplitConfig cfg;
229 DockNodeIds ids = BuildDockTree(dockspace_id, needs, cfg);
230
231 auto get_dock_id = [&](DockPosition pos) -> ImGuiID {
232 switch (pos) {
234 return ids.left ? ids.left : ids.center;
236 return ids.right ? ids.right : ids.center;
238 return ids.bottom ? ids.bottom : ids.center;
240 return ids.top ? ids.top : ids.center;
242 return ids.left_top ? ids.left_top
243 : (ids.left ? ids.left : ids.center);
245 return ids.left_bottom ? ids.left_bottom
246 : (ids.left ? ids.left : ids.center);
248 return ids.right_top ? ids.right_top
249 : (ids.right ? ids.right : ids.center);
251 return ids.right_bottom ? ids.right_bottom
252 : (ids.right ? ids.right : ids.center);
254 default:
255 return ids.center;
256 }
257 };
258
259 // Iterate through positioned panels and dock them
260 for (const auto& [panel_id, position] : preset.panel_positions) {
261 const PanelDescriptor* desc =
263 ? panel_manager_->GetPanelDescriptor(session_id, panel_id)
264 : nullptr;
265 if (!desc) {
266 LOG_WARN("LayoutManager",
267 "Preset references panel '%s' that is not registered (session "
268 "%zu)",
269 panel_id.c_str(), session_id);
270 continue;
271 }
272
273 std::string window_title = desc->GetWindowTitle();
274 if (window_title.empty()) {
275 LOG_WARN("LayoutManager",
276 "Cannot dock panel '%s': missing window title (session %zu)",
277 panel_id.c_str(), session_id);
278 continue;
279 }
280
281 ImGui::DockBuilderDockWindow(window_title.c_str(), get_dock_id(position));
282 }
283}
284
285// Deprecated individual build methods - redirected to generic or kept empty
297
298void LayoutManager::SaveCurrentLayout(const std::string& name) {
299 // TODO: [EditorManagerRefactor] Implement layout saving to file
300 // Use ImGui::SaveIniSettingsToMemory() and write to custom file
301 LOG_INFO("LayoutManager", "Saving layout: %s", name.c_str());
302}
303
304void LayoutManager::LoadLayout(const std::string& name) {
305 // TODO: [EditorManagerRefactor] Implement layout loading from file
306 // Use ImGui::LoadIniSettingsFromMemory() and read from custom file
307 LOG_INFO("LayoutManager", "Loading layout: %s", name.c_str());
308}
309
311 layouts_initialized_[type] = false;
312 LOG_INFO("LayoutManager", "Reset layout for editor type %d",
313 static_cast<int>(type));
314}
315
317 auto it = layouts_initialized_.find(type);
318 return it != layouts_initialized_.end() && it->second;
319}
320
322 layouts_initialized_[type] = true;
323 LOG_INFO("LayoutManager", "Marked layout for editor type %d as initialized",
324 static_cast<int>(type));
325}
326
328 layouts_initialized_.clear();
329 LOG_INFO("LayoutManager", "Cleared all layout initialization flags");
330}
331
332std::string LayoutManager::GetWindowTitle(const std::string& card_id) const {
333 if (!panel_manager_) {
334 return "";
335 }
336
337 const size_t session_id = panel_manager_->GetActiveSessionId();
338 // Look up the panel descriptor in the manager (session 0 by default)
339 auto* info = panel_manager_->GetPanelDescriptor(session_id, card_id);
340 if (info) {
341 return info->GetWindowTitle();
342 }
343 return "";
344}
345
346} // namespace editor
347} // namespace yaze
void LoadLayout(const std::string &name)
Load a saved layout by name.
std::string GetWindowTitle(const std::string &card_id) const
Get window title for a card ID from registry.
void BuildScreenLayout(ImGuiID dockspace_id)
void BuildPaletteLayout(ImGuiID dockspace_id)
void BuildDungeonLayout(ImGuiID dockspace_id)
void BuildGraphicsLayout(ImGuiID dockspace_id)
void RebuildLayout(EditorType type, ImGuiID dockspace_id)
Force rebuild of layout for a specific editor type.
void BuildEmulatorLayout(ImGuiID dockspace_id)
void BuildAssemblyLayout(ImGuiID dockspace_id)
void ClearInitializationFlags()
Clear all initialization flags (for testing)
void BuildMessageLayout(ImGuiID dockspace_id)
std::unordered_map< EditorType, bool > layouts_initialized_
bool IsLayoutInitialized(EditorType type) const
Check if a layout has been initialized for an editor.
void BuildSettingsLayout(ImGuiID dockspace_id)
void ResetToDefaultLayout(EditorType type)
Reset the layout for an editor to its default.
void BuildOverworldLayout(ImGuiID dockspace_id)
void MarkLayoutInitialized(EditorType type)
Mark a layout as initialized.
void InitializeEditorLayout(EditorType type, ImGuiID dockspace_id)
Initialize the default layout for a specific editor type.
void BuildLayoutFromPreset(EditorType type, ImGuiID dockspace_id)
void SaveCurrentLayout(const std::string &name)
Save the current layout with a custom name.
void BuildSpriteLayout(ImGuiID dockspace_id)
void BuildMusicLayout(ImGuiID dockspace_id)
static std::vector< std::string > GetDefaultPanels(EditorType type)
Get default visible panels for an editor.
static PanelLayoutPreset GetDefaultPreset(EditorType type)
Get the default layout preset for an editor type.
Central registry for all editor cards with session awareness and dependency injection.
const PanelDescriptor * GetPanelDescriptor(size_t session_id, const std::string &base_card_id) const
bool ShowPanel(size_t session_id, const std::string &base_card_id)
size_t GetActiveSessionId() const
#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
DockSplitNeeds ComputeSplitNeeds(const PanelLayoutPreset &preset)
void ShowDefaultPanelsForEditor(PanelManager *registry, EditorType type)
DockNodeIds BuildDockTree(ImGuiID dockspace_id, const DockSplitNeeds &needs, const DockSplitConfig &cfg)
DockPosition
Preferred dock position for a card in a layout.
Metadata for an editor panel (formerly PanelInfo)
std::string GetWindowTitle() const
Get the effective window title for DockBuilder.
Defines default panel visibility for an editor type.
std::unordered_map< std::string, DockPosition > panel_positions