khora_core/ui/editor/shell.rs
1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Abstract editor shell — generic host for dock-based panel layouts.
16//!
17//! The shell owns no application logic and no branding. It only knows how to:
18//! - apply a theme to the underlying UI backend,
19//! - lay out panels in a small set of fixed slots ([`PanelLocation`]),
20//! - render those panels each frame via the [`UiBuilder`] abstraction.
21//!
22//! Concrete implementations (e.g. egui) live in `khora-infra`. Editor-specific
23//! chrome (menu bars, toolbars, status bars, brand logos) is implemented as
24//! ordinary panels in the application crate (`khora-editor`) — never in the
25//! shell or the backend.
26
27use super::panel::{EditorPanel, PanelLocation};
28use super::state::{EditorState, StatusBarData};
29use crate::ui::{FontPack, UiTheme};
30
31/// The top-level editor shell — a generic host for docked panels.
32///
33/// Concrete implementations live in `khora-infra`. The engine calls
34/// [`show_frame()`](Self::show_frame) once per frame between
35/// `overlay.begin_frame()` and `overlay.end_frame_and_render()`.
36pub trait EditorShell: Send + Sync {
37 /// Registers a panel at the given dock location.
38 fn register_panel(&mut self, location: PanelLocation, panel: Box<dyn EditorPanel>);
39
40 /// Removes a panel by id. Returns `true` if it was found.
41 fn remove_panel(&mut self, id: &str) -> bool;
42
43 /// Applies a theme to the underlying UI backend.
44 fn set_theme(&mut self, theme: UiTheme);
45
46 /// Installs a custom font pack. If [`FontPack::is_empty`] is true, the
47 /// backend keeps its built-in defaults. Default no-op so backends that
48 /// don't support custom fonts compile without changes.
49 fn set_fonts(&mut self, fonts: FontPack) {
50 let _ = fonts;
51 }
52
53 /// Updates the status bar data shared with panels.
54 ///
55 /// Most editors will route this into a dedicated status-bar panel (the
56 /// shell does not draw a status bar itself).
57 fn set_status(&mut self, data: StatusBarData);
58
59 /// Sets a shared [`EditorState`] reference. Panels typically grab this
60 /// at construction; this method exists for shells that want to surface
61 /// state to internal helpers (debug overlays, etc.).
62 fn set_editor_state(&mut self, state: std::sync::Arc<std::sync::Mutex<EditorState>>);
63
64 /// Renders the full editor frame.
65 ///
66 /// Iterates every registered slot and invokes
67 /// [`EditorPanel::ui`] for each panel. The shell decides slot geometry;
68 /// the panel decides slot content.
69 fn show_frame(&mut self);
70}