1#ifndef APP_EDITOR_SYSTEM_PANEL_MANAGER_H_
2#define APP_EDITOR_SYSTEM_PANEL_MANAGER_H_
10#include <unordered_map>
11#include <unordered_set>
19#ifndef YAZE_ENABLE_CARD_SHIM_DEPRECATION
20#define YAZE_ENABLE_CARD_SHIM_DEPRECATION 1
23#if YAZE_ENABLE_CARD_SHIM_DEPRECATION && defined(__has_cpp_attribute)
24#if __has_cpp_attribute(deprecated)
25#define YAZE_CARD_SHIM_DEPRECATED(msg) [[deprecated(msg)]]
27#define YAZE_CARD_SHIM_DEPRECATED(msg)
30#define YAZE_CARD_SHIM_DEPRECATED(msg)
98 const std::string label =
161 const std::string& canonical_base_id);
169 void RegisterPanel(
size_t session_id,
const std::string& card_id,
170 const std::string& display_name,
const std::string& icon,
171 const std::string& category,
172 const std::string& shortcut_hint =
"",
int priority = 50,
173 std::function<
void()> on_show =
nullptr,
174 std::function<
void()> on_hide =
nullptr,
175 bool visible_by_default =
false);
177 void UnregisterPanel(
size_t session_id,
const std::string& base_card_id);
249 const std::string& to_category);
255 bool ShowPanel(
size_t session_id,
const std::string& base_card_id);
256 bool HidePanel(
size_t session_id,
const std::string& base_card_id);
257 bool TogglePanel(
size_t session_id,
const std::string& base_card_id);
258 bool IsPanelVisible(
size_t session_id,
const std::string& base_card_id)
const;
269 void ShowOnlyPanel(
size_t session_id,
const std::string& base_card_id);
277 const std::string& category)
const;
280 const std::string& base_card_id)
const;
309 const std::vector<std::string>& panel_ids);
317 size_t session_id)
const;
325 size_t session_id,
const std::unordered_map<std::string, bool>& state,
326 bool publish_events =
false);
345 const std::string& base_card_id)
const;
360 if (viewport_width <= 0.0f) {
366 if (viewport_width < 900.0f) {
367 const float preferred = viewport_width * 0.50f;
368 const float min_width = std::max(220.0f, viewport_width * 0.40f);
369 const float max_width =
370 std::max(min_width, std::min(380.0f, viewport_width * 0.58f));
371 return std::clamp(preferred, min_width, max_width);
374 if (viewport_width < 1200.0f) {
375 const float preferred = viewport_width * 0.34f;
376 const float min_width = 300.0f;
377 const float max_width = std::min(420.0f, viewport_width * 0.42f);
378 return std::clamp(preferred, min_width, max_width);
383 if (viewport_width < 1400.0f) {
384 const float preferred = viewport_width * 0.25f;
385 const float min_width = 300.0f;
386 const float max_width = 380.0f;
387 return std::clamp(preferred, min_width, max_width);
391 const float max_width = viewport_width * 0.30f;
392 if (max_width > 0.0f && width > max_width) {
414 std::function<
void(
float)> cb) {
440 const std::vector<PanelDescriptor>& cards);
578 std::function<
void(
bool,
bool)> cb) {
613 void SavePreset(
const std::string& name,
const std::string& description =
"");
616 std::vector<WorkspacePreset>
GetPresets()
const;
636 void ShowAll(
size_t session_id);
637 void HideAll(
size_t session_id);
653 std::string
MakePanelId(
size_t session_id,
const std::string& base_id)
const;
654 std::string
MakePanelId(
size_t session_id,
const std::string& base_id,
715 const std::string& root_path =
"");
720 std::function<
void(
const std::string& category,
const std::string& path)>
742 size_t session_id,
const std::string& category)
const;
754 void SetPanelPinned(
size_t session_id,
const std::string& base_card_id,
bool pinned);
755 bool IsPanelPinned(
size_t session_id,
const std::string& base_card_id)
const;
758 void SetPanelPinned(
const std::string& base_card_id,
bool pinned);
782 const std::string& base_panel_id);
784 const std::string& base_panel_id)
const;
789 return static_cast<size_t>(scope);
794 const std::string& old_key,
795 const std::string& new_key);
798 const std::string& prefixed_id)
const;
810 std::unordered_map<std::string, PanelDescriptor>
cards_;
835 std::unordered_map<size_t, std::unordered_map<std::string, std::string>>
839 std::unordered_map<size_t, std::unordered_map<std::string, std::string>>
847 std::unordered_map<size_t,
853 std::unordered_map<std::string, WorkspacePreset>
presets_;
889 std::unordered_map<std::string, std::unique_ptr<FileBrowser>>
898 const std::string& base_id)
const;
902 const std::string& panel_id);
911#undef YAZE_CARD_SHIM_DEPRECATED
void Publish(const T &event)
Base interface for all logical panel components.
Interface for editor classes.
File system browser for the sidebar.
Central registry for all editor cards with session awareness and dependency injection.
std::unordered_map< std::string, bool > SerializeVisibilityState(size_t session_id) const
Serialize panel visibility state for persistence.
std::vector< std::string > GetPinnedPanels() const
void TriggerShowCommandPalette()
void ToggleSidebarVisibility()
float GetPanelBrowserCategoryWidth() const
void ApplyContextPolicy(size_t session_id, PanelContextScope scope, const std::string &old_key, const std::string &new_key)
std::function< void(bool visible, bool expanded)> on_sidebar_state_changed_
size_t GetSessionCount() const
size_t GetVisiblePanelCount(size_t session_id) const
void ShowOnlyPanel(size_t session_id, const std::string &base_card_id)
std::unordered_map< std::string, bool > centralized_visibility_
void SetPanelExpanded(bool expanded, bool notify=true)
void SetEmulatorVisibilityChangedCallback(std::function< void(bool)> cb)
void SetOnCategorySelectedCallback(std::function< void(const std::string &)> callback)
void SetSidebarStateChangedCallback(std::function< void(bool, bool)> cb)
std::unordered_map< std::string, std::unique_ptr< EditorPanel > > panel_instances_
bool * GetVisibilityFlag(const std::string &base_card_id)
std::function< void(const std::string &) on_category_selected_)
void ShowAllPanelsInCategory(const std::string &category)
void RegisterSession(size_t session_id)
void SetFileBrowserPath(const std::string &category, const std::string &path)
void TriggerCategorySelected(const std::string &category)
bool ShouldPrefixPanels() const
EditorPanel * GetEditorPanel(const std::string &panel_id)
Get an EditorPanel instance by ID.
void TriggerShowAgentProposalsSidebar()
void SetSidebarVisible(bool visible, bool notify=true)
void OnEditorSwitch(const std::string &from_category, const std::string &to_category)
Handle editor/category switching for panel visibility.
void UnregisterSessionPanels(size_t session_id)
void SetActiveSession(size_t session_id)
bool TogglePanel(size_t session_id, const std::string &base_card_id)
const PanelDescriptor * GetPanelDescriptor(size_t session_id, const std::string &base_card_id) const
void SetCategoryChangedCallback(std::function< void(const std::string &)> cb)
void HideAllPanelsInCategory(const std::string &category)
void TriggerResetLayout()
std::unordered_map< std::string, std::string > panel_resource_types_
uint64_t GetPanelMRUTime(const std::string &card_id) const
Get MRU timestamp for a panel (0 if never used)
void TriggerPanelClicked(const std::string &category)
void TriggerShowShortcuts()
std::unordered_map< size_t, std::vector< std::string > > session_cards_
void ToggleEmulatorVisible()
PanelManager & operator=(PanelManager &&)=delete
void TogglePanelExpanded()
void SetActiveSidePanelWidth(float width, float viewport_width=0.0f, bool notify=true)
void ResetSidePanelWidth(bool notify=true)
std::vector< std::string > GetPanelsInSession(size_t session_id) const
void HandleSidebarKeyboardNav(size_t session_id, const std::vector< PanelDescriptor > &cards)
Handle keyboard navigation in sidebar (click-to-focus modal)
void RestorePinnedState(const std::unordered_map< std::string, bool > &state)
Restore pinned panel state from persistence.
void RestoreVisibilityState(size_t session_id, const std::unordered_map< std::string, bool > &state, bool publish_events=false)
Restore panel visibility state from persistence.
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > session_reverse_card_mapping_
std::unordered_map< std::string, bool > SerializePinnedState() const
Serialize pinned panel state for persistence.
void SetActiveCategory(const std::string &category, bool notify=true)
std::vector< std::string > GetAllCategories() const
std::string GetContextKey(size_t session_id, PanelContextScope scope) const
bool * GetVisibilityFlag(size_t session_id, const std::string &base_card_id)
void UnregisterSession(size_t session_id)
void HideAllPanelsInSession(size_t session_id)
std::string GetBaseIdForPrefixedId(size_t session_id, const std::string &prefixed_id) const
bool HasFileBrowser(const std::string &category) const
PanelManager & operator=(const PanelManager &)=delete
void RegisterPanelAlias(const std::string &legacy_base_id, const std::string &canonical_base_id)
Register a legacy panel ID alias that resolves to a canonical ID.
static float GetSidePanelWidthForViewport(float viewport_width)
std::vector< PanelDescriptor > GetPanelsSortedByMRU(size_t session_id, const std::string &category) const
Get panels in category sorted by: pinned first, then MRU.
bool SidebarHasFocus() const
std::function< void(bool)> on_emulator_visibility_changed_
void UnregisterPanelsWithPrefix(const std::string &prefix)
void SetOnPanelClickedCallback(std::function< void(const std::string &)> callback)
void SetEditorResolver(std::function< Editor *(const std::string &)> resolver)
std::function< void(const std::string &, const std::string &) on_file_clicked_)
int GetFocusedPanelIndex() const
std::vector< PanelDescriptor > GetPanelsInCategory(size_t session_id, const std::string &category) const
std::unordered_map< size_t, std::unordered_map< PanelContextScope, std::string, PanelContextScopeHash > > session_context_keys_
bool ShowPanel(size_t session_id, const std::string &base_card_id)
std::string MakePanelId(size_t session_id, const std::string &base_id) const
std::function< void(float width)> on_side_panel_width_changed_
std::unordered_map< std::string, PanelDescriptor > cards_
void UnregisterPanel(const std::string &base_card_id)
std::unordered_map< std::string, bool > pinned_panels_
bool IsPanelExpanded() const
static CategoryTheme GetCategoryTheme(const std::string &category)
void RegisterPanel(size_t session_id, const PanelDescriptor &base_info)
std::string GetActiveCategory() const
bool IsPanelVisible(size_t session_id, const std::string &base_card_id) const
bool LoadPreset(const std::string &name)
void EnableFileBrowser(const std::string &category, const std::string &root_path="")
void TriggerShowAgentChatSidebar()
PanelManager(const PanelManager &)=delete
void SetEventBus(EventBus *event_bus)
static constexpr float GetCollapsedSidebarWidth()
PanelValidationResult ValidatePanel(const std::string &card_id) const
std::unordered_map< size_t, std::unordered_map< std::string, std::string > > session_card_mapping_
void DeletePreset(const std::string &name)
std::vector< std::string > recent_categories_
bool IsEmulatorVisible() const
std::string ResolveBasePanelId(const std::string &panel_id) const
size_t GetRegistryPanelCount() const
Returns the number of panels registered via ContentRegistry.
PanelManager(PanelManager &&)=delete
void DisableFileBrowser(const std::string &category)
void RegisterRegistryPanelsForSession(size_t session_id)
Register descriptors for all registry panels in a session.
std::function< void(const std::string &) on_card_clicked_)
std::unordered_map< std::string, std::unique_ptr< FileBrowser > > category_file_browsers_
std::string GetPrefixedPanelId(size_t session_id, const std::string &base_id) const
static constexpr float GetSidebarWidth()
void TriggerShowPanelBrowser()
std::unordered_set< std::string > active_editor_categories_
void SetPanelBrowserCategoryWidth(float width, bool notify=true)
std::string GetPanelWindowName(size_t session_id, const std::string &base_card_id) const
Resolve the exact ImGui window name for a panel by base ID.
void UnregisterPanel(size_t session_id, const std::string &base_card_id)
void DrawAllVisiblePanels()
Draw all visible EditorPanel instances (central drawing)
float panel_browser_category_width_
float GetStoredSidePanelWidth() const
void ResetToDefaults(size_t session_id)
static constexpr size_t kMaxRecentCategories
bool IsSidebarVisible() const
std::unordered_set< std::string > global_panel_ids_
void UnregisterEditorPanel(const std::string &panel_id)
Unregister and destroy an EditorPanel instance.
bool IsPanelVisible(const std::string &base_card_id) const
void ShowAllPanelsInCategory(size_t session_id, const std::string &category)
std::vector< PanelValidationResult > ValidatePanels() const
void MarkPanelUsed(const std::string &panel_id)
Mark a panel as recently used (for LRU)
void SetEmulatorVisible(bool visible)
std::unordered_map< std::string, std::list< std::string > > resource_panels_
size_t GetPanelCount() const
void SetStoredSidePanelWidth(float width, bool notify=false)
void MarkPanelRecentlyUsed(const std::string &card_id)
Record that a panel was used (for MRU ordering in sidebar)
void SetContextKey(size_t session_id, PanelContextScope scope, std::string key)
Set a string key for a given context scope (room/selection/etc)
void EnforceResourceLimits(const std::string &resource_type)
Enforce limits on resource panels (LRU eviction)
static std::string GetCategoryIcon(const std::string &category)
void UpdateSessionCount()
EditorPanel * FindPanelInstance(const std::string &prefixed_panel_id, const std::string &base_panel_id)
static constexpr const char * kDashboardCategory
static SidePanelWidthBounds GetSidePanelWidthBounds(float viewport_width)
void SetVisiblePanels(size_t session_id, const std::vector< std::string > &panel_ids)
Set which panels should be visible for a session.
void TrackPanelForSession(size_t session_id, const std::string &base_id, const std::string &panel_id)
static constexpr float GetSidePanelWidth()
void RegisterRegistryPanel(std::unique_ptr< EditorPanel > panel)
Register a ContentRegistry-managed EditorPanel instance.
std::unordered_map< std::string, std::string > panel_id_aliases_
float GetActiveSidePanelWidth(float viewport_width) const
std::function< void(float width)> on_panel_browser_category_width_changed_
static constexpr float GetDefaultPanelBrowserCategoryWidth()
bool IsPanelPinned(size_t session_id, const std::string &base_card_id) const
void TriggerShowSettings()
const std::unordered_map< std::string, PanelDescriptor > & GetAllPanelDescriptors() const
Get all panel descriptors (for layout designer, panel browser, etc.)
void RegisterPanel(const PanelDescriptor &base_info)
void SetPanelBrowserCategoryWidthChangedCallback(std::function< void(float)> cb)
bool HidePanel(const std::string &base_card_id)
FileBrowser * GetFileBrowser(const std::string &category)
void ToggleFavorite(const std::string &card_id)
std::unordered_map< std::string, uint64_t > last_used_at_
bool ShowPanel(const std::string &base_card_id)
void RegisterEditorPanel(std::unique_ptr< EditorPanel > panel)
Register an EditorPanel instance for central drawing.
void SavePreset(const std::string &name, const std::string &description="")
bool HidePanel(size_t session_id, const std::string &base_card_id)
std::unordered_set< std::string > registry_panel_ids_
void LoadPresetsFromFile()
void SetSidePanelWidthChangedCallback(std::function< void(float)> cb)
void SetFileClickedCallback(std::function< void(const std::string &category, const std::string &path)> callback)
std::vector< WorkspacePreset > GetPresets() const
std::function< Editor *(const std::string &) editor_resolver_)
size_t GetActiveSessionId() const
void SetPanelPinned(size_t session_id, const std::string &base_card_id, bool pinned)
bool IsFavorite(const std::string &card_id) const
void HideAllPanelsInCategory(size_t session_id, const std::string &category)
void TriggerShowEmulator()
std::unordered_map< std::string, WorkspacePreset > presets_
std::string active_category_
void RegisterPanelDescriptorForSession(size_t session_id, const EditorPanel &panel)
std::function< void(const std::string &) on_category_changed_)
std::vector< std::string > GetVisiblePanelIds(size_t session_id) const
Get list of currently visible panel IDs for a session.
void ShowAllPanelsInSession(size_t session_id)
std::string ResolvePanelAlias(const std::string &panel_id) const
Resolve a panel ID through the alias table.
Draggable, dockable panel for editor sub-windows.
PanelCategory
Defines lifecycle behavior for editor panels.
@ EditorBound
Hidden when switching editors (default)
PanelScope
Defines whether a panel is session-scoped or global.
PanelContextScope
Optional context binding for a panel's behavior within an editor.
Metadata for an editor panel (formerly PanelInfo)
std::string disabled_tooltip
std::string GetImGuiWindowName() const
Build the exact ImGui window name used by PanelWindow::Begin.
std::function< void()> on_show
PanelCategory panel_category
std::string GetWindowTitle() const
Get the effective window title for DockBuilder.
PanelContextScope context_scope
std::string shortcut_hint
ShortcutScope shortcut_scope
std::function< bool()> enabled_condition
std::function< void()> on_hide
Get the expressive theme color for a category.
size_t operator()(PanelContextScope scope) const noexcept
std::string expected_title
std::vector< std::string > visible_cards
static UIActionRequestEvent Redo(size_t session=0)
static UIActionRequestEvent ShowCommandPalette(size_t session=0)
static UIActionRequestEvent SaveRom(size_t session=0)
static UIActionRequestEvent Create(Action act, size_t session=0)
static UIActionRequestEvent Undo(size_t session=0)
static UIActionRequestEvent ShowSettings(size_t session=0)
static UIActionRequestEvent ShowAgentProposalsSidebar(size_t session=0)
static UIActionRequestEvent ShowAgentChatSidebar(size_t session=0)
static UIActionRequestEvent OpenRom(size_t session=0)
static UIActionRequestEvent ShowEmulator(size_t session=0)