1#define IMGUI_DEFINE_MATH_OPERATORS
10#include "absl/strings/str_format.h"
21#include "imgui/imgui.h"
22#include "imgui/imgui_internal.h"
32WindowDescriptor BuildDescriptorFromPanel(
const WindowContent& panel) {
33 WindowDescriptor descriptor;
34 auto* panel_ptr =
const_cast<WindowContent*
>(&panel);
35 descriptor.
card_id = panel.GetId();
36 descriptor.display_name = panel.GetDisplayName();
37 descriptor.icon = panel.GetIcon();
38 descriptor.category = panel.GetEditorCategory();
39 descriptor.priority = panel.GetPriority();
40 descriptor.workflow_group = panel.GetWorkflowGroup();
41 descriptor.workflow_label = panel.GetWorkflowLabel();
42 descriptor.workflow_description = panel.GetWorkflowDescription();
43 descriptor.workflow_priority = panel.GetWorkflowPriority();
44 descriptor.shortcut_hint = panel.GetShortcutHint();
45 descriptor.scope = panel.GetScope();
46 descriptor.window_lifecycle = panel.GetWindowLifecycle();
47 descriptor.context_scope = panel.GetContextScope();
48 descriptor.enabled_condition = [panel_ptr]() {
49 return panel_ptr->IsEnabled();
51 descriptor.disabled_tooltip = panel.GetDisabledTooltip();
52 descriptor.visibility_flag =
nullptr;
53 descriptor.window_title = panel.GetIcon() +
" " + panel.GetDisplayName();
64 const std::string& category) {
65 if (category ==
"Dungeon")
67 if (category ==
"Overworld")
69 if (category ==
"Graphics")
71 if (category ==
"Palette")
73 if (category ==
"Sprite")
75 if (category ==
"Music")
77 if (category ==
"Message")
79 if (category ==
"Screen")
81 if (category ==
"Emulator")
83 if (category ==
"Assembly")
85 if (category ==
"Settings")
87 if (category ==
"Memory")
89 if (category ==
"Agent")
99 const std::string& category) {
103 if (category ==
"Dungeon") {
105 return {0.95f, 0.75f, 0.20f, 1.0f, 0.95f, 0.75f, 0.20f};
107 if (category ==
"Overworld") {
109 return {0.30f, 0.85f, 0.45f, 1.0f, 0.30f, 0.85f, 0.45f};
111 if (category ==
"Graphics") {
113 return {0.40f, 0.70f, 0.95f, 1.0f, 0.40f, 0.70f, 0.95f};
115 if (category ==
"Palette") {
117 return {0.90f, 0.40f, 0.70f, 1.0f, 0.90f, 0.40f, 0.70f};
119 if (category ==
"Sprite") {
121 return {0.30f, 0.85f, 0.85f, 1.0f, 0.30f, 0.85f, 0.85f};
123 if (category ==
"Music") {
125 return {0.70f, 0.40f, 0.90f, 1.0f, 0.70f, 0.40f, 0.90f};
127 if (category ==
"Message") {
129 return {0.95f, 0.90f, 0.40f, 1.0f, 0.95f, 0.90f, 0.40f};
131 if (category ==
"Screen") {
133 return {0.90f, 0.92f, 0.95f, 1.0f, 0.90f, 0.92f, 0.95f};
135 if (category ==
"Emulator") {
137 return {0.90f, 0.35f, 0.40f, 1.0f, 0.90f, 0.35f, 0.40f};
139 if (category ==
"Assembly") {
141 return {0.40f, 0.90f, 0.50f, 1.0f, 0.40f, 0.90f, 0.50f};
143 if (category ==
"Settings") {
145 return {0.60f, 0.70f, 0.80f, 1.0f, 0.60f, 0.70f, 0.80f};
147 if (category ==
"Memory") {
149 return {0.95f, 0.60f, 0.25f, 1.0f, 0.95f, 0.60f, 0.25f};
151 if (category ==
"Agent") {
153 return {0.60f, 0.40f, 0.95f, 1.0f, 0.60f, 0.40f, 0.95f};
157 return {0.50f, 0.60f, 0.80f, 1.0f, 0.50f, 0.60f, 0.80f};
160WorkspaceWindowManager::SidePanelWidthBounds
163 if (viewport_width <= 0.0f) {
164 SidePanelWidthBounds bounds{};
165 bounds.min_width = 220.0f;
166 bounds.max_width = std::max(520.0f, fallback);
170 const float min_width = std::max(220.0f, viewport_width * 0.18f);
171 const float max_width = std::max(min_width + 20.0f, viewport_width * 0.62f);
172 SidePanelWidthBounds bounds{};
173 bounds.min_width = min_width;
174 bounds.max_width = max_width;
179 float viewport_width)
const {
182 return default_width;
190 float viewport_width,
201 const float clamped = std::clamp(width, bounds.min_width, bounds.max_width);
223 const float fallback = GetDefaultPanelBrowserCategoryWidth();
224 const float clamped = std::max(180.0f, width > 0.0f ? width : fallback);
236 const std::string& prefixed_id) {
242 const std::string& prefixed_id)
const {
254 size_t session_id)
const {
259std::unordered_map<std::string, std::string>*
266const std::unordered_map<std::string, std::string>*
273std::unordered_map<std::string, std::string>*
280const std::unordered_map<std::string, std::string>*
282 size_t session_id)
const {
289 size_t session_id,
const std::string& prefixed_window_id,
290 const std::string& base_window_id,
const std::string& category,
291 bool visible)
const {
294 prefixed_window_id, base_window_id, category, visible, session_id));
299 const std::string& resource_type)
const {
300 if (resource_type ==
"room") {
303 if (resource_type ==
"song") {
306 if (resource_type ==
"sheet") {
309 if (resource_type ==
"map") {
316 const std::string& panel_id, ResourceWindowContent* resource_panel) {
317 if (!resource_panel) {
320 const std::string resource_type = resource_panel->GetResourceType();
326 const std::string& panel_id) {
332 const std::string resource_type = type_it->second;
335 panels_it->second.remove(panel_id);
336 if (panels_it->second.empty()) {
344 const std::list<std::string>& panel_ids)
const {
345 for (
const auto& panel_id : panel_ids) {
351 return panel_ids.empty() ? std::string{} : panel_ids.front();
363 const WindowDescriptor& base_info) {
366 WindowDescriptor canonical_info = base_info;
369 std::string panel_id =
370 MakeWindowId(session_id, canonical_info.card_id, canonical_info.scope);
372 bool already_registered = (
cards_.find(panel_id) !=
cards_.end());
375 "Panel '%s' already registered, skipping duplicate",
379 if (!already_registered) {
381 WindowDescriptor panel_info = canonical_info;
382 panel_info.card_id = panel_id;
385 if (!panel_info.visibility_flag) {
391 cards_[panel_id] = panel_info;
394 "Registered card %s -> %s for session %zu",
395 canonical_info.card_id.c_str(), panel_id.c_str(), session_id);
409 size_t session_id,
const std::string& card_id,
410 const std::string& display_name,
const std::string& icon,
411 const std::string& category,
const std::string& shortcut_hint,
int priority,
412 std::function<
void()> on_show, std::function<
void()> on_hide,
413 bool visible_by_default) {
414 WindowDescriptor info;
416 info.display_name = display_name;
418 info.category = category;
419 info.shortcut_hint = shortcut_hint;
420 info.priority = priority;
421 info.visibility_flag =
nullptr;
422 info.on_show = on_show;
423 info.on_hide = on_hide;
428 if (visible_by_default) {
434 const std::string& base_card_id) {
437 if (prefixed_id.empty()) {
441 auto it =
cards_.find(prefixed_id);
443 LOG_INFO(
"WorkspaceWindowManager",
"Unregistered card: %s",
444 prefixed_id.c_str());
455 std::remove(card_list.begin(), card_list.end(), prefixed_id),
459 mapping.erase(canonical_base_id);
461 for (
auto& [mapped_session, reverse_mapping] :
463 reverse_mapping.erase(prefixed_id);
470 session_card_list.erase(std::remove(session_card_list.begin(),
471 session_card_list.end(), prefixed_id),
472 session_card_list.end());
479 const std::string& prefix) {
481 std::string prefixed_id;
482 size_t session_id = 0;
485 std::vector<RemovalInfo> to_remove;
488 for (
const auto& [card_id, card_info] :
cards_) {
490 if (card_id.find(prefix) == 0) {
492 info.prefixed_id = card_id;
493 for (
const auto& [session_id, reverse_mapping] :
495 auto reverse_it = reverse_mapping.find(card_id);
496 if (reverse_it != reverse_mapping.end()) {
497 info.session_id = session_id;
498 info.base_id = reverse_it->second;
502 to_remove.push_back(std::move(info));
507 for (
const auto& info : to_remove) {
508 if (!info.base_id.empty()) {
513 cards_.erase(info.prefixed_id);
516 LOG_INFO(
"WorkspaceWindowManager",
"Unregistered card with prefix '%s': %s",
517 prefix.c_str(), info.prefixed_id.c_str());
522 card_list.erase(std::remove_if(card_list.begin(), card_list.end(),
523 [&prefix](
const std::string&
id) {
524 return id.find(prefix) == 0;
544 LOG_INFO(
"WorkspaceWindowManager",
"Cleared all cards");
552 std::unique_ptr<WindowContent> panel) {
555 "Attempted to register null WindowContent");
559 auto* resource_panel =
dynamic_cast<ResourceWindowContent*
>(panel.get());
560 if (resource_panel) {
564 std::string panel_id = panel->GetId();
569 "WindowContent '%s' already registered, skipping registry add",
584 LOG_INFO(
"WorkspaceWindowManager",
"Registered registry WindowContent: %s",
601 std::unique_ptr<WindowContent> panel) {
604 "Attempted to register null WindowContent");
608 auto* resource_panel =
dynamic_cast<ResourceWindowContent*
>(panel.get());
609 if (resource_panel) {
613 std::string panel_id = panel->GetId();
618 "WindowContent '%s' already registered, skipping",
624 WindowDescriptor descriptor = BuildDescriptorFromPanel(*panel);
627 bool visible_by_default = panel->IsVisibleByDefault();
633 if (visible_by_default) {
642 LOG_INFO(
"WorkspaceWindowManager",
"Registered WindowContent: %s (%s)",
643 panel_id.c_str(), descriptor.display_name.c_str());
651 const std::string& resource_type) {
656 auto& panel_list = it->second;
660 while (panel_list.size() >= limit) {
662 if (panel_to_evict.empty()) {
667 panel_list.remove(panel_to_evict);
678 std::string type = type_it->second;
683 list.remove(panel_id);
684 list.push_back(panel_id);
688 const std::string& panel_id) {
693 it->second->OnClose();
698 LOG_INFO(
"WorkspaceWindowManager",
"Unregistered WindowContent: %s",
707 const std::string& panel_id) {
710 return it->second.get();
716 const std::string& prefixed_panel_id,
const std::string& base_panel_id) {
719 return prefixed_it->second.get();
723 return base_it->second.get();
729 const std::string& prefixed_panel_id,
730 const std::string& base_panel_id)
const {
733 return prefixed_it->second.get();
737 return base_it->second.get();
756 bool animations_enabled = animator.IsEnabled();
759 const auto resolve_switch_speed = [&](
float snappy,
float standard,
761 switch (animator.motion_profile()) {
771 const float category_transition_speed =
772 resolve_switch_speed(8.5f, 6.0f, 4.5f);
773 const float panel_fade_speed = resolve_switch_speed(11.0f, 8.0f, 6.0f);
776 float global_alpha = 1.0f;
777 if (animations_enabled) {
778 global_alpha = animator.Animate(
"global",
"category_transition", 1.0f,
779 category_transition_speed);
782 for (
const auto& prefixed_panel_id : session_it->second) {
783 auto descriptor_it =
cards_.find(prefixed_panel_id);
784 if (descriptor_it ==
cards_.end()) {
787 WindowDescriptor& descriptor = descriptor_it->second;
789 std::string base_panel_id =
791 if (base_panel_id.empty()) {
792 base_panel_id = prefixed_panel_id;
800 bool is_visible = descriptor.visibility_flag && *descriptor.visibility_flag;
805 bool should_draw =
false;
816 float target_alpha = should_draw ? 1.0f : 0.0f;
819 float current_alpha = 1.0f;
820 if (animations_enabled) {
821 current_alpha = animator.Animate(prefixed_panel_id,
"panel_alpha",
822 target_alpha, panel_fade_speed);
823 current_alpha *= global_alpha;
825 current_alpha = target_alpha;
829 if (current_alpha < 0.01f) {
834 bool* visibility_flag = descriptor.visibility_flag;
838 std::string display_name = descriptor.display_name.empty()
839 ? panel->GetDisplayName()
840 : descriptor.display_name;
842 descriptor.icon.empty() ? panel->GetIcon() : descriptor.icon;
851 gui::PanelWindow window(display_name.c_str(), icon.c_str(),
853 window.SetStableId(prefixed_panel_id);
859 float preferred_width = panel->GetPreferredWidth();
860 if (preferred_width > 0.0f) {
861 window.SetDefaultSize(preferred_width, 0);
865 window.SetPinnable(
true);
869 window.SetPinChangedCallback([
this, base_panel_id](
bool pinned) {
874 std::optional<gui::StyleVarGuard> alpha_guard;
875 if (current_alpha < 1.0f) {
876 alpha_guard.emplace(ImGuiStyleVar_Alpha, current_alpha);
879 animator.ApplyPanelTransitionPre(prefixed_panel_id);
880 if (window.Begin(visibility_flag)) {
881 panel->DrawWithLazyInit(visibility_flag);
884 animator.ApplyPanelTransitionPost(prefixed_panel_id);
889 if (visibility_flag && !*visibility_flag) {
896 const std::string& to_category) {
897 if (from_category == to_category) {
901 LOG_INFO(
"WorkspaceWindowManager",
"Switching from category '%s' to '%s'",
902 from_category.c_str(), to_category.c_str());
924 const auto incoming =
926 for (
const auto& descriptor : incoming) {
927 if (descriptor.visibility_flag && *descriptor.visibility_flag) {
943 const std::string& base_card_id) {
946 if (prefixed_id.empty()) {
952 const bool was_visible =
953 (descriptor->visibility_flag && *descriptor->visibility_flag);
954 if (descriptor->visibility_flag) {
955 *descriptor->visibility_flag =
true;
957 if (descriptor->on_show) {
958 descriptor->on_show();
961 if (WindowContent* panel =
968 descriptor->category,
true);
975 const std::string& base_card_id) {
978 if (prefixed_id.empty()) {
984 const bool was_visible =
985 (descriptor->visibility_flag && *descriptor->visibility_flag);
986 if (descriptor->visibility_flag) {
987 *descriptor->visibility_flag =
false;
989 if (descriptor->on_hide) {
990 descriptor->on_hide();
993 if (WindowContent* panel =
1000 descriptor->category,
false);
1007 const std::string& base_card_id) {
1010 if (prefixed_id.empty()) {
1015 if (descriptor && descriptor->visibility_flag) {
1016 bool new_state = !(*descriptor->visibility_flag);
1017 *descriptor->visibility_flag = new_state;
1019 if (new_state && descriptor->on_show) {
1020 descriptor->on_show();
1021 }
else if (!new_state && descriptor->on_hide) {
1022 descriptor->on_hide();
1024 if (WindowContent* panel =
1034 descriptor->category, new_state);
1041 size_t session_id,
const std::string& base_card_id)
const {
1044 if (prefixed_id.empty()) {
1049 if (descriptor && descriptor->visibility_flag) {
1050 return *descriptor->visibility_flag;
1056 size_t session_id,
const std::string& base_card_id) {
1059 if (prefixed_id.empty()) {
1065 return descriptor->visibility_flag;
1076 for (
const auto& prefixed_card_id : *session_windows) {
1078 if (descriptor->visibility_flag) {
1079 *descriptor->visibility_flag =
true;
1081 if (descriptor->on_show) {
1082 descriptor->on_show();
1091 for (
const auto& prefixed_card_id : *session_windows) {
1093 if (descriptor->visibility_flag) {
1094 *descriptor->visibility_flag =
false;
1096 if (descriptor->on_hide) {
1097 descriptor->on_hide();
1105 size_t session_id,
const std::string& category) {
1107 for (
const auto& prefixed_card_id : *session_windows) {
1109 if (descriptor->category != category) {
1112 if (descriptor->visibility_flag) {
1113 *descriptor->visibility_flag =
true;
1115 if (descriptor->on_show) {
1116 descriptor->on_show();
1124 size_t session_id,
const std::string& category) {
1126 for (
const auto& prefixed_card_id : *session_windows) {
1128 if (descriptor->category != category) {
1131 if (descriptor->visibility_flag) {
1132 *descriptor->visibility_flag =
false;
1134 if (descriptor->on_hide) {
1135 descriptor->on_hide();
1143 const std::string& base_card_id) {
1146 if (prefixed_id.empty()) {
1155 std::string category = target->category;
1169 size_t session_id)
const {
1170 std::vector<std::string> result;
1172 result.reserve(session_windows->size());
1173 for (
const auto& prefixed_window_id : *session_windows) {
1174 const std::string base_window_id =
1176 result.push_back(base_window_id.empty() ? prefixed_window_id
1184 size_t session_id,
const std::string& category)
const {
1185 std::vector<WindowDescriptor> result;
1188 for (
const auto& prefixed_window_id : *session_windows) {
1189 if (
const auto* descriptor =
1191 if (descriptor->category == category) {
1192 WindowDescriptor window = *descriptor;
1193 const std::string base_window_id =
1195 if (!base_window_id.empty()) {
1196 window.card_id = base_window_id;
1198 result.push_back(std::move(window));
1205 std::sort(result.begin(), result.end(),
1206 [](
const WindowDescriptor& a,
const WindowDescriptor& b) {
1207 return a.priority < b.priority;
1214 size_t session_id)
const {
1215 std::vector<std::string> categories;
1218 for (
const auto& prefixed_window_id : *session_windows) {
1219 if (
const auto* descriptor =
1221 if (std::find(categories.begin(), categories.end(),
1222 descriptor->category) == categories.end()) {
1223 categories.push_back(descriptor->category);
1232 size_t session_id,
const std::string& base_card_id)
const {
1235 if (prefixed_id.empty()) {
1243 std::vector<std::string> categories;
1245 if (std::find(categories.begin(), categories.end(), card_info.category) ==
1247 categories.push_back(card_info.category);
1258 size_t session_id)
const {
1259 std::vector<std::string> visible_panels;
1262 if (!window_mapping) {
1263 return visible_panels;
1266 for (
const auto& [base_id, prefixed_id] : *window_mapping) {
1268 if (descriptor->visibility_flag && *descriptor->visibility_flag) {
1269 visible_panels.push_back(base_id);
1274 return visible_panels;
1282 const std::string& description) {
1283 WorkspacePreset preset;
1285 preset.description = description;
1288 for (
const auto& [card_id, card_info] :
cards_) {
1289 if (card_info.visibility_flag && *card_info.visibility_flag) {
1290 preset.visible_cards.push_back(card_id);
1296 LOG_INFO(
"WorkspaceWindowManager",
"Saved preset: %s (%zu cards)",
1297 name.c_str(), preset.visible_cards.size());
1307 for (
auto& [card_id, card_info] :
cards_) {
1308 if (card_info.visibility_flag) {
1309 *card_info.visibility_flag =
false;
1314 for (
const auto& card_id : it->second.visible_cards) {
1315 auto card_it =
cards_.find(card_id);
1316 if (card_it !=
cards_.end() && card_it->second.visibility_flag) {
1317 *card_it->second.visibility_flag =
true;
1318 if (card_it->second.on_show) {
1319 card_it->second.on_show();
1324 LOG_INFO(
"WorkspaceWindowManager",
"Loaded preset: %s", name.c_str());
1333std::vector<WorkspaceWindowManager::WorkspacePreset>
1335 std::vector<WorkspacePreset> result;
1336 for (
const auto& [name, preset] :
presets_) {
1337 result.push_back(preset);
1359 LOG_INFO(
"WorkspaceWindowManager",
"Reset to defaults for session %zu",
1367 if (category.empty()) {
1369 "No category found for editor type %d, skipping reset",
1370 static_cast<int>(editor_type));
1381 for (
const auto& card_id : default_panels) {
1383 LOG_INFO(
"WorkspaceWindowManager",
"Showing default card: %s",
1389 "Reset %s editor to defaults (%zu cards visible)", category.c_str(),
1390 default_panels.size());
1398 size_t session_id,
const std::string& base_id)
const {
1403 const std::string& base_id,
1407 return canonical_base_id;
1410 return absl::StrFormat(
"s%zu.%s", session_id, canonical_base_id);
1412 return canonical_base_id;
static std::string GetEditorCategory(EditorType type)
static std::vector< std::string > GetDefaultPanels(EditorType type)
Get default visible panels for an editor.
void ResetSidePanelWidth(bool notify=true)
void RegisterPanel(size_t session_id, const WindowDescriptor &base_info)
bool IsWindowPinnedImpl(size_t session_id, const std::string &base_card_id) const
void SavePreset(const std::string &name, const std::string &description="")
std::vector< std::string > GetWindowsInSessionImpl(size_t session_id) const
void SetActiveSidePanelWidth(float width, float viewport_width=0.0f, bool notify=true)
void HideAllWindowsInCategory(size_t session_id, const std::string &category)
bool CloseWindowImpl(size_t session_id, const std::string &base_card_id)
size_t GetResourceWindowLimit(const std::string &resource_type) const
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > & session_reverse_card_mapping_
static SidePanelWidthBounds GetSidePanelWidthBounds(float viewport_width)
void DeletePreset(const std::string &name)
std::vector< WorkspacePreset > GetPresets() const
void ResetToDefaults(size_t session_id)
void UnregisterWindowContent(const std::string &window_id)
Unregister and destroy a WindowContent instance.
std::unordered_map< std::string, std::string > * FindSessionWindowMapping(size_t session_id)
std::string SelectResourceWindowForEviction(const std::list< std::string > &panel_ids) const
bool * GetVisibilityFlag(size_t session_id, const std::string &base_card_id)
void UntrackResourceWindow(const std::string &panel_id)
std::string ResolveBaseWindowId(const std::string &panel_id) const
std::unordered_map< std::string, WindowDescriptor > & cards_
WindowBrowserState browser_state_
std::string GetPrefixedWindowId(size_t session_id, const std::string &base_id) const
bool LoadPreset(const std::string &name)
static float GetSidePanelWidthForViewport(float viewport_width)
std::vector< std::string > * FindSessionWindowIds(size_t session_id)
const WindowDescriptor * GetWindowDescriptorImpl(size_t session_id, const std::string &base_card_id) const
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
static CategoryTheme GetCategoryTheme(const std::string &category)
std::unordered_map< std::string, std::string > & panel_resource_types_
std::vector< WindowDescriptor > GetWindowsInCategoryImpl(size_t session_id, const std::string &category) const
std::unordered_map< std::string, bool > & centralized_visibility_
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > & session_card_mapping_
void MarkPanelUsed(const std::string &panel_id)
Mark a panel as recently used (for LRU)
void TrackPanelForSession(size_t session_id, const std::string &base_id, const std::string &panel_id)
std::unordered_map< std::string, std::list< std::string > > & resource_panels_
WindowSessionState session_state_
void TrackResourceWindow(const std::string &panel_id, ResourceWindowContent *resource_panel)
std::vector< std::string > GetAllCategories() const
void SetActiveCategory(const std::string &category, bool notify=true)
void RegisterRegistryWindowContent(std::unique_ptr< WindowContent > window)
Register a ContentRegistry-managed WindowContent instance.
static std::string GetCategoryIcon(const std::string &category)
void UnregisterPanel(size_t session_id, const std::string &base_card_id)
void ShowOnlyWindow(size_t session_id, const std::string &base_window_id)
void RegisterWindowContent(std::unique_ptr< WindowContent > window)
Register a WindowContent instance for central drawing.
std::function< Editor *(const std::string &) editor_resolver_)
static constexpr const char * kDashboardCategory
std::unordered_map< std::string, WorkspacePreset > presets_
void EnforceResourceLimits(const std::string &resource_type)
Enforce limits on resource panels (LRU eviction)
WindowDescriptor * FindDescriptorByPrefixedId(const std::string &prefixed_id)
void SetPanelBrowserCategoryWidth(float width, bool notify=true)
bool IsWindowVisibleImpl(size_t session_id, const std::string &base_card_id) const
void DrawAllVisiblePanels()
Draw all visible WindowContent instances (central drawing)
std::unordered_map< std::string, std::unique_ptr< WindowContent > > & panel_instances_
std::unordered_set< std::string > & registry_panel_ids_
std::vector< std::string > GetVisibleWindowIdsImpl(size_t session_id) const
void SetWindowPinnedImpl(size_t session_id, const std::string &base_card_id, bool pinned)
bool ToggleWindowImpl(size_t session_id, const std::string &base_card_id)
std::unordered_map< size_t, std::vector< std::string > > & session_cards_
void EnforceResourceWindowLimits(const std::string &resource_type)
std::unordered_map< std::string, std::string > * FindSessionReverseWindowMapping(size_t session_id)
float GetActiveSidePanelWidth(float viewport_width) const
std::string MakeWindowId(size_t session_id, const std::string &base_id) const
bool ShouldPrefixPanels() const
void OnEditorSwitch(const std::string &from_category, const std::string &to_category)
Handle editor/category switching for panel visibility.
void HideAllWindowsInSession(size_t session_id)
std::unordered_map< std::string, bool > & pinned_panels_
void RegisterSession(size_t session_id)
void ShowAllWindowsInSession(size_t session_id)
WindowContent * GetWindowContent(const std::string &window_id)
Get a WindowContent instance by ID.
void RegisterRegistryWindowContentsForSession(size_t session_id)
Register descriptors for all registry window contents in a session.
std::unordered_map< size_t, std::unordered_map< WindowContextScope, std::string, WindowContextScopeHash > > & session_context_keys_
WindowContent * FindPanelInstance(const std::string &prefixed_panel_id, const std::string &base_panel_id)
WindowRegistryState registry_state_
void UnregisterPanelsWithPrefix(const std::string &prefix)
void PublishWindowVisibilityChanged(size_t session_id, const std::string &prefixed_window_id, const std::string &base_window_id, const std::string &category, bool visible) const
void RegisterPanelDescriptorForSession(size_t session_id, const WindowContent &panel)
bool OpenWindowImpl(size_t session_id, const std::string &base_card_id)
void ShowAllWindowsInCategory(size_t session_id, const std::string &category)
std::unordered_set< std::string > & global_panel_ids_
void ClearAnimationsForPanel(const std::string &panel_id)
void BeginPanelTransition(const std::string &panel_id, TransitionType type)
static bool IsTouchDevice()
#define ICON_MD_VIDEOGAME_ASSET
#define ICON_MD_MUSIC_NOTE
#define ICON_MD_SMART_TOY
#define LOG_ERROR(category, format,...)
#define LOG_WARN(category, format,...)
#define LOG_INFO(category, format,...)
::yaze::EventBus * event_bus()
Get the current EventBus instance.
void SetCurrentEditor(Editor *editor)
Set the currently active editor.
constexpr size_t kMaxTotalResourcePanels
Maximum total resource panels across all types.
constexpr size_t kMaxSongPanels
Maximum open song panels (music editor)
constexpr size_t kMaxSheetPanels
Maximum open graphics sheet panels.
constexpr size_t kMaxRoomPanels
Maximum open room panels (dungeon editor)
constexpr size_t kMaxMapPanels
Maximum open map panels (overworld editor)
WindowScope
Defines whether a window is session-scoped or global.
static PanelVisibilityChangedEvent Create(const std::string &id, const std::string &base_id, const std::string &cat, bool vis, size_t session=0)
std::function< void(float width)> on_window_browser_width_changed
std::string active_category
float window_browser_category_width
std::function< void(float width)> on_sidebar_width_changed
std::unordered_map< std::string, WindowDescriptor > descriptors
std::unordered_map< size_t, std::vector< std::string > > session_windows
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > session_reverse_window_mapping
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > session_window_mapping