1#define IMGUI_DEFINE_MATH_OPERATORS
10#include "absl/strings/str_format.h"
21#include "imgui/imgui.h"
22#include "imgui/imgui_internal.h"
49 return panel_ptr->IsEnabled();
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};
163 if (viewport_width <= 0.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);
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") {
317 if (!resource_panel) {
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();
369 std::string panel_id =
372 bool already_registered = (
cards_.find(panel_id) !=
cards_.end());
375 "Panel '%s' already registered, skipping duplicate",
379 if (!already_registered) {
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) {
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");
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");
609 if (resource_panel) {
613 std::string panel_id = panel->GetId();
618 "WindowContent '%s' already registered, skipping",
627 bool visible_by_default = panel->IsVisibleByDefault();
633 if (visible_by_default) {
642 LOG_INFO(
"WorkspaceWindowManager",
"Registered WindowContent: %s (%s)",
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()) {
789 std::string base_panel_id =
791 if (base_panel_id.empty()) {
792 base_panel_id = prefixed_panel_id;
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) {
838 std::string display_name = descriptor.
display_name.empty()
860 if (preferred_width > 0.0f) {
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)) {
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();
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();
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();
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) {
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(),
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) {
1288 for (
const auto& [card_id, card_info] :
cards_) {
1289 if (card_info.visibility_flag && *card_info.visibility_flag) {
1296 LOG_INFO(
"WorkspaceWindowManager",
"Saved preset: %s (%zu cards)",
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)
Interface for editor classes.
static std::vector< std::string > GetDefaultPanels(EditorType type)
Get default visible panels for an editor.
Base class for windows that edit specific ROM resources.
virtual std::string GetResourceType() const =0
The resource type name.
Base interface for all logical window content components.
virtual std::string GetWorkflowDescription() const
Optional workflow description for menus/command palette.
virtual std::string GetDisabledTooltip() const
Get tooltip text when panel is disabled.
virtual int GetWorkflowPriority() const
Optional workflow ordering priority (lower sorts first).
virtual std::string GetDisplayName() const =0
Human-readable name shown in menus and title bars.
virtual WindowLifecycle GetWindowLifecycle() const
Get the lifecycle category for this window.
virtual std::string GetEditorCategory() const =0
Editor category this panel belongs to.
virtual int GetPriority() const
Get display priority for menu ordering.
virtual void OnClose()
Called when panel is hidden.
virtual WindowScope GetScope() const
Get the registration scope for this window.
virtual std::string GetIcon() const =0
Material Design icon for this panel.
virtual float GetPreferredWidth() const
Get preferred width for this panel (optional)
virtual WindowContextScope GetContextScope() const
Optional context binding for this window (room/selection/etc)
virtual std::string GetWorkflowLabel() const
Optional workflow label for menus/command palette.
void DrawWithLazyInit(bool *p_open)
Execute lazy initialization if needed, then call Draw()
virtual std::string GetId() const =0
Unique identifier for this panel.
virtual std::string GetWorkflowGroup() const
Optional workflow group for hack-centric actions.
virtual std::string GetShortcutHint() const
Get keyboard shortcut hint for display.
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()
Draggable, dockable panel for editor sub-windows.
void SetPinChangedCallback(std::function< void(bool)> callback)
void SetPinned(bool pinned)
void SetStableId(const std::string &stable_id)
void SetPinnable(bool pinnable)
void SetPosition(Position pos)
bool Begin(bool *p_open=nullptr)
void SetDefaultSize(float width, float height)
#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)
WindowDescriptor BuildDescriptorFromPanel(const WindowContent &panel)
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)
Metadata for a dockable editor window (formerly PanelInfo)
std::function< void()> on_show
std::string shortcut_hint
std::string workflow_group
std::function< void()> on_hide
WindowContextScope context_scope
std::string disabled_tooltip
std::string workflow_description
std::string workflow_label
std::function< bool()> enabled_condition
WindowLifecycle window_lifecycle
Get the expressive theme color for a category.
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
std::vector< std::string > visible_cards