khora_core/ui/editor/panel.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 panel and dock location types.
16
17use super::ui_builder::UiBuilder;
18
19/// Where a panel is placed in the editor dock layout.
20///
21/// Slots are filled by panels registered with the [`EditorShell`](super::EditorShell).
22/// The shell is responsible for laying them out — the panel only needs to know
23/// which slot it lives in.
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25pub enum PanelLocation {
26 /// Top fixed-height strip — non-resizable. Multiple `TopBar` panels stack
27 /// vertically in registration order. Heights come from
28 /// [`EditorPanel::preferred_size`].
29 TopBar,
30 /// Left fixed-width strip — non-resizable. Used for vertical mode
31 /// switchers / "spines". Width comes from [`EditorPanel::preferred_size`].
32 Spine,
33 /// Resizable left sidebar (e.g. Scene Tree / Hierarchy). Default width
34 /// comes from [`EditorPanel::preferred_size`] when set.
35 Left,
36 /// Resizable right sidebar (e.g. Inspector / Properties).
37 Right,
38 /// Resizable bottom strip (e.g. Console, Asset Browser). Panels sharing
39 /// this slot are displayed as tabs.
40 Bottom,
41 /// Bottom fixed-height strip — non-resizable. Sits below the resizable
42 /// `Bottom` slot. Used for status bars. Height comes from
43 /// [`EditorPanel::preferred_size`].
44 StatusBar,
45 /// Central area (e.g. 3D Viewport).
46 Center,
47 /// Floating overlay rendered on top of the dock. Inner `i32` is the
48 /// z-order — higher values draw on top. Used for command palettes,
49 /// modal dialogs, etc.
50 Floating(i32),
51}
52
53/// A single editor panel that can render itself into a [`UiBuilder`].
54///
55/// Panels are registered with an [`EditorShell`](super::EditorShell) at
56/// startup. The shell calls [`ui()`](Self::ui) each frame for every visible
57/// panel.
58pub trait EditorPanel: Send + Sync {
59 /// Unique identifier (used for dock serialization and lookup).
60 fn id(&self) -> &str;
61
62 /// Human-readable title shown in the tab / panel header.
63 fn title(&self) -> &str;
64
65 /// Build the panel contents for the current frame.
66 fn ui(&mut self, ui: &mut dyn UiBuilder);
67
68 /// Preferred size hint, in logical points.
69 ///
70 /// Interpretation depends on the panel's [`PanelLocation`]:
71 ///
72 /// | Location | Meaning |
73 /// |---|---|
74 /// | `TopBar`, `StatusBar` | Fixed height. |
75 /// | `Spine` | Fixed width. |
76 /// | `Left`, `Right` | Default width (still resizable by user). |
77 /// | `Bottom` | Default height (still resizable by user). |
78 /// | `Center`, `Floating` | Ignored. |
79 ///
80 /// Returning `None` lets the shell pick a sensible default for the slot.
81 fn preferred_size(&self) -> Option<f32> {
82 None
83 }
84}