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."},
30 "Scratch workspace for staging, assembling, and selecting tile "
31 "compositions beside the canvas."},
32 {
"overworld.properties",
33 "Current default: selected-map properties in the Overworld Default "
35 {
"overworld.area_graphics",
36 "Reviewed Overworld default: selected-area graphics beside the map; "
37 "shares the right-bottom dock with map properties instead of covering "
38 "the canvas with a bottom strip."},
42 "Single default dungeon surface; hosts the room browser, canvas, and "
46 {
"graphics.sheet_browser_v2",
47 "Sheet list that selects what the pixel editor edits."},
48 {
"graphics.pixel_editor",
"Primary graphics sheet editing surface."},
51 {
"palette.control_panel",
52 "Single Palette workspace; hosts group navigation and color editing."},
55 {
"sprite.vanilla_editor",
"Primary sprite editing surface."},
58 {
"screen.dungeon_maps",
59 "Primary surface of the Screen editor's default preset."},
60 {
"screen.title_screen",
61 "Opened by ScreenEditor::Initialize, so it is what actually shows on "
62 "first open (the preset lists dungeon_maps); resolve in the audit doc."},
65 {
"music.song_browser",
"Song list that selects what the tracker edits."},
66 {
"music.tracker",
"Playback transport for the Music Default preset."},
67 {
"music.piano_roll",
"Primary music editing surface."},
70 {
"message.message_list",
71 "Message list that selects what the editor edits."},
72 {
"message.message_editor",
"Primary message text editing surface."},
75 {
"assembly.code_editor",
"Primary assembly source editing surface."},
76 {
"assembly.file_browser",
"Project file tree that opens sources."},
77 {
"assembly.disassembly",
78 "Current default: disassembly view in the Assembly Default preset."},
80 "Current default: registered visible. Its Open Folder and Save buttons "
81 "are the only quick actions when no project code folder is set."},
85 "Primary planning surface: goal, milestones, route strip and decisions."},
87 "Route step and item editor; the Overview's route strip selects into it."},
90 {
"dashboard.main",
"Editor picker shown at startup and on Ctrl+E."},
93 {
"emulator.ppu_viewer",
"Primary emulator output surface."},
94 {
"memory.hex_editor",
"Primary surface of the Memory editor."},
97 {
"agent.chat",
"Primary agent conversation surface."},
98 {
"agent.configuration",
99 "Current default: agent provider setup in the Agent preset."},
100 {
"agent.status",
"Current default: agent status in the Agent preset."},
109 "Overworld panels are Codex-coordinated; src/app/editor/overworld/* needs "
110 "scawful's approval before edits.";
130 "Override GetPresentationPolicy() in the panel class (or pass a policy to "
131 "RegisterWindowContent) and return one of: "
132 "WindowPresentationPolicy::EmbeddedTool().WithHost(\"<surface that embeds "
133 "it>\") for a tool that acts on another surface's selection (inspector "
134 "section, tool tab, canvas context-menu popup); OptionalPopOut() for a "
135 "standalone window users choose to open; "
136 "Diagnostic().WithHost(\"Command palette\") for developer or validation "
137 "tooling. CoreWorkspace() is only for an editor's primary work surface and "
138 "needs a FirstClassPanelAllowlist() entry. See \"Panel admission\" in "
139 "docs/internal/architecture/editor-ui-module-pattern.md.";
142 "Core is reserved for an editor's primary work surface. Either add the "
143 "window id to FirstClassPanelAllowlist() in "
144 "src/app/editor/system/workspace/panel_admission.cc with the workflow it "
145 "serves and why no inspector, tool tab, or context-menu popup can host it, "
146 "or pick EmbeddedTool().WithHost(...) or OptionalPopOut().";
149 "Hide it by default: remove IsVisibleByDefault()/visible_by_default and "
150 "its LayoutPresets default_visible_panels entry so it opens from its host "
151 "or the command palette. If it really is a primary surface, add the window "
152 "id to FirstClassPanelAllowlist() in "
153 "src/app/editor/system/workspace/panel_admission.cc with a reason.";
156 "Add .WithHost(\"<surface>\") to the policy, for example "
157 "EmbeddedTool().WithHost(\"Dungeon Workbench inspector\") or "
158 "Diagnostic().WithHost(\"Command palette\"). The host is where users find "
159 "the window now that it is not in the window browser.";
164 return kFirstClassAllowlist;
168 const std::string& window_id) {
169 for (
const auto& entry : kFirstClassAllowlist) {
170 if (window_id == entry.window_id) {
178 return kDeferredDeclarations;
182 for (
const auto& entry : kDeferredDeclarations) {
183 if (window_id == entry.window_id) {
197 const std::vector<std::string> registered =
199 std::set<std::string> registered_ids(registered.begin(), registered.end());
200 std::set<std::string> visible;
202 for (
const auto& window_id : registered) {
207 visible.insert(window_id);
220 if (registered_ids.count(window_id) != 0) {
221 visible.insert(window_id);
225 return std::vector<std::string>(visible.begin(), visible.end());
230 std::vector<PanelAdmissionFinding> findings;
232 const std::vector<std::string> default_visible =
234 const std::set<std::string> default_visible_set(default_visible.begin(),
235 default_visible.end());
237 std::vector<std::string> window_ids =
239 std::sort(window_ids.begin(), window_ids.end());
240 window_ids.erase(std::unique(window_ids.begin(), window_ids.end()),
243 for (
const auto& window_id : window_ids) {
246 if (descriptor ==
nullptr) {
251 auto add = [&](std::string problem, std::string fix) {
252 findings.push_back({window_id, descriptor->
category, std::move(problem),
257 add(
"declares no presentation policy.", kUndeclaredFix);
262 add(
"declares CoreWorkspace but is not in FirstClassPanelAllowlist().",
266 if (default_visible_set.count(window_id) != 0 && !admitted) {
267 add(std::string(
"is visible by default (IsVisibleByDefault(), "
268 "visible_by_default, or a LayoutPresets default) with "
271 " but is not in FirstClassPanelAllowlist().",
275 const bool needs_host =
278 if (needs_host && policy.
host.empty()) {
280 " names no host surface.",
288 const std::vector<PanelAdmissionFinding>& findings) {
291 std::vector<std::string> fix_order;
292 std::map<std::string, std::vector<const PanelAdmissionFinding*>> groups;
293 for (
const auto& finding : findings) {
294 auto [it, inserted] = groups.try_emplace(finding.fix);
296 fix_order.push_back(finding.fix);
298 it->second.push_back(&finding);
302 for (
const auto& fix : fix_order) {
304 out +=
" [" + finding->category +
"] " + finding->window_id +
": " +
305 finding->problem +
"\n";
307 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