25 {
"overworld.canvas",
"Primary map canvas; the editor's work surface."},
26 {
"overworld.tile16_selector",
27 "Tile16 palette the canvas paints from; docked beside the canvas in the "
28 "Overworld Default preset."},
29 {
"overworld.properties",
30 "Current default: selected-map properties in the Overworld Default "
32 {
"overworld.area_graphics",
33 "Reviewed Overworld default: selected-area graphics beside the map; "
34 "shares the right-bottom dock with map properties instead of covering "
35 "the canvas with a bottom strip."},
39 "Single default dungeon surface; hosts the room browser, canvas, and "
43 {
"graphics.sheet_browser_v2",
44 "Sheet list that selects what the pixel editor edits."},
45 {
"graphics.pixel_editor",
"Primary graphics sheet editing surface."},
48 {
"palette.control_panel",
49 "Single Palette workspace; hosts group navigation and color editing."},
52 {
"sprite.vanilla_editor",
"Primary sprite editing surface."},
55 {
"screen.dungeon_maps",
56 "Primary surface of the Screen editor's default preset."},
57 {
"screen.title_screen",
58 "Opened by ScreenEditor::Initialize, so it is what actually shows on "
59 "first open (the preset lists dungeon_maps); resolve in the audit doc."},
62 {
"music.song_browser",
"Song list that selects what the tracker edits."},
63 {
"music.tracker",
"Playback transport for the Music Default preset."},
64 {
"music.piano_roll",
"Primary music editing surface."},
67 {
"message.message_list",
68 "Message list that selects what the editor edits."},
69 {
"message.message_editor",
"Primary message text editing surface."},
72 {
"assembly.code_editor",
"Primary assembly source editing surface."},
73 {
"assembly.file_browser",
"Project file tree that opens sources."},
74 {
"assembly.disassembly",
75 "Current default: disassembly view in the Assembly Default preset."},
77 "Current default: registered visible. Its Open Folder and Save buttons "
78 "are the only quick actions when no project code folder is set."},
82 "Primary planning surface: goal, milestones, route strip and decisions."},
84 "Route step and item editor; the Overview's route strip selects into it."},
87 {
"dashboard.main",
"Editor picker shown at startup and on Ctrl+E."},
90 {
"emulator.ppu_viewer",
"Primary emulator output surface."},
91 {
"memory.hex_editor",
"Primary surface of the Memory editor."},
94 {
"agent.chat",
"Primary agent conversation surface."},
95 {
"agent.configuration",
96 "Current default: agent provider setup in the Agent preset."},
97 {
"agent.status",
"Current default: agent status in the Agent preset."},
106 "Overworld panels are Codex-coordinated; src/app/editor/overworld/* needs "
107 "scawful's approval before edits.";
127 "Override GetPresentationPolicy() in the panel class (or pass a policy to "
128 "RegisterWindowContent) and return one of: "
129 "WindowPresentationPolicy::EmbeddedTool().WithHost(\"<surface that embeds "
130 "it>\") for a tool that acts on another surface's selection (inspector "
131 "section, tool tab, canvas context-menu popup); OptionalPopOut() for a "
132 "standalone window users choose to open; "
133 "Diagnostic().WithHost(\"Command palette\") for developer or validation "
134 "tooling. CoreWorkspace() is only for an editor's primary work surface and "
135 "needs a FirstClassPanelAllowlist() entry. See \"Panel admission\" in "
136 "docs/internal/architecture/editor-ui-module-pattern.md.";
139 "Core is reserved for an editor's primary work surface. Either add the "
140 "window id to FirstClassPanelAllowlist() in "
141 "src/app/editor/system/workspace/panel_admission.cc with the workflow it "
142 "serves and why no inspector, tool tab, or context-menu popup can host it, "
143 "or pick EmbeddedTool().WithHost(...) or OptionalPopOut().";
146 "Hide it by default: remove IsVisibleByDefault()/visible_by_default and "
147 "its LayoutPresets default_visible_panels entry so it opens from its host "
148 "or the command palette. If it really is a primary surface, add the window "
149 "id to FirstClassPanelAllowlist() in "
150 "src/app/editor/system/workspace/panel_admission.cc with a reason.";
153 "Add .WithHost(\"<surface>\") to the policy, for example "
154 "EmbeddedTool().WithHost(\"Dungeon Workbench inspector\") or "
155 "Diagnostic().WithHost(\"Command palette\"). The host is where users find "
156 "the window now that it is not in the window browser.";
161 return kFirstClassAllowlist;
165 const std::string& window_id) {
166 for (
const auto& entry : kFirstClassAllowlist) {
167 if (window_id == entry.window_id) {
175 return kDeferredDeclarations;
179 for (
const auto& entry : kDeferredDeclarations) {
180 if (window_id == entry.window_id) {
194 const std::vector<std::string> registered =
196 std::set<std::string> registered_ids(registered.begin(), registered.end());
197 std::set<std::string> visible;
199 for (
const auto& window_id : registered) {
204 visible.insert(window_id);
217 if (registered_ids.count(window_id) != 0) {
218 visible.insert(window_id);
222 return std::vector<std::string>(visible.begin(), visible.end());
227 std::vector<PanelAdmissionFinding> findings;
229 const std::vector<std::string> default_visible =
231 const std::set<std::string> default_visible_set(default_visible.begin(),
232 default_visible.end());
234 std::vector<std::string> window_ids =
236 std::sort(window_ids.begin(), window_ids.end());
237 window_ids.erase(std::unique(window_ids.begin(), window_ids.end()),
240 for (
const auto& window_id : window_ids) {
243 if (descriptor ==
nullptr) {
248 auto add = [&](std::string problem, std::string fix) {
249 findings.push_back({window_id, descriptor->
category, std::move(problem),
254 add(
"declares no presentation policy.", kUndeclaredFix);
259 add(
"declares CoreWorkspace but is not in FirstClassPanelAllowlist().",
263 if (default_visible_set.count(window_id) != 0 && !admitted) {
264 add(std::string(
"is visible by default (IsVisibleByDefault(), "
265 "visible_by_default, or a LayoutPresets default) with "
268 " but is not in FirstClassPanelAllowlist().",
272 const bool needs_host =
275 if (needs_host && policy.
host.empty()) {
277 " names no host surface.",
285 const std::vector<PanelAdmissionFinding>& findings) {
288 std::vector<std::string> fix_order;
289 std::map<std::string, std::vector<const PanelAdmissionFinding*>> groups;
290 for (
const auto& finding : findings) {
291 auto [it, inserted] = groups.try_emplace(finding.fix);
293 fix_order.push_back(finding.fix);
295 it->second.push_back(&finding);
299 for (
const auto& fix : fix_order) {
301 out +=
" [" + finding->category +
"] " + finding->window_id +
": " +
302 finding->problem +
"\n";
304 out +=
" Fix: " + fix +
"\n\n";
static std::vector< std::string > GetDefaultPanels(EditorType type)
Get default visible panels for an editor.
Central registry for all editor cards with session awareness and dependency injection.
const WindowDescriptor * GetWindowDescriptor(size_t session_id, const std::string &base_window_id) const
std::vector< std::string > GetWindowsInSession(size_t session_id) const
constexpr char kUndeclaredFix[]
constexpr char kDefaultVisibleFix[]
constexpr char kCoreFix[]
const std::vector< PanelAdmissionEntry > kFirstClassAllowlist
constexpr char kHostFix[]
const std::vector< PanelAdmissionEntry > kDeferredDeclarations
constexpr char kOverworldFrozen[]
const PanelAdmissionEntry * FindFirstClassPanelEntry(const std::string &window_id)
Returns the allowlist entry for a base window id, or nullptr.
std::string FormatPanelAdmissionFindings(const std::vector< PanelAdmissionFinding > &findings)
Joins findings into one message for test output.
const std::vector< PanelAdmissionEntry > & FirstClassPanelAllowlist()
bool IsPolicyDeclarationDeferred(const std::string &window_id)
std::vector< PanelAdmissionFinding > AuditPanelAdmission(const WorkspaceWindowManager &window_manager, size_t session_id)
Audits every window registered for session_id. Empty means admitted.
std::vector< std::string > CollectDefaultVisibleWindowIds(const WorkspaceWindowManager &window_manager, size_t session_id)
const char * WindowPresentationRoleName(WindowPresentationRole role)
const std::vector< PanelAdmissionEntry > & DeferredPolicyDeclarations()
Admission rules for registered workspace windows.
One audit failure. fix tells the panel author what to change.
std::string ToString() const
Metadata for a dockable editor window (formerly PanelInfo)
WindowPresentationPolicy presentation
WindowPresentationRole role