1use operad::native::NativeWindowResult;
2use operad::widgets;
3use operad::widgets::ext::{
4 self as ext_widgets, DockPanelDescriptor, DockSide, DockWorkspaceOptions,
5};
6use operad::{
7 root_style, ColorRgba, LayoutStyle, StrokeStyle, TextStyle, UiDocument, UiNode, UiSize,
8 UiVisual,
9};
10
11fn main() -> NativeWindowResult {
12 operad::native::run("Docked workspace", workspace_document)
13}
14
15fn workspace_document(viewport: UiSize) -> UiDocument {
16 let mut ui = UiDocument::new(root_style(viewport.width, viewport.height));
17 let root = ui.add_child(
18 ui.root(),
19 UiNode::container(
20 "workspace.root",
21 LayoutStyle::column()
22 .with_width_percent(1.0)
23 .with_height_percent(1.0)
24 .with_padding(12.0),
25 )
26 .with_visual(UiVisual::panel(ColorRgba::new(13, 17, 23, 255), None, 0.0)),
27 );
28
29 let panels = [
30 DockPanelDescriptor::new("assets", "Assets", DockSide::Left, 190.0)
31 .with_min_size(140.0)
32 .resizable(true),
33 DockPanelDescriptor::center("editor", "Editor").with_min_size(220.0),
34 DockPanelDescriptor::new("inspector", "Inspector", DockSide::Right, 220.0)
35 .with_min_size(170.0)
36 .resizable(true),
37 DockPanelDescriptor::new("timeline", "Timeline", DockSide::Bottom, 110.0)
38 .with_min_size(80.0)
39 .resizable(true),
40 ];
41
42 let mut options = DockWorkspaceOptions::default();
43 options.layout = LayoutStyle::column()
44 .with_width_percent(1.0)
45 .with_height_percent(1.0);
46 options.panel_visual = UiVisual::panel(
47 ColorRgba::new(24, 29, 36, 255),
48 Some(StrokeStyle::new(ColorRgba::new(58, 68, 84, 255), 1.0)),
49 0.0,
50 );
51 options.center_visual = UiVisual::panel(
52 ColorRgba::new(16, 21, 28, 255),
53 Some(StrokeStyle::new(ColorRgba::new(58, 68, 84, 255), 1.0)),
54 0.0,
55 );
56
57 ext_widgets::dock_workspace(&mut ui, root, "workspace", &panels, options, panel_body);
58 ui
59}
60
61fn panel_body(ui: &mut UiDocument, parent: operad::UiNodeId, panel: &DockPanelDescriptor) {
62 match panel.id.as_str() {
63 "assets" => {
64 panel_label(ui, parent, "workspace.assets.one", "models/scene.glb");
65 panel_label(ui, parent, "workspace.assets.two", "textures/albedo.png");
66 panel_label(ui, parent, "workspace.assets.three", "materials/metal.toml");
67 }
68 "editor" => {
69 panel_heading(ui, parent, "workspace.editor.title", "Scene editor");
70 panel_label(
71 ui,
72 parent,
73 "workspace.editor.body",
74 "The center panel fills remaining space.",
75 );
76 }
77 "inspector" => {
78 panel_heading(ui, parent, "workspace.inspector.title", "Selected object");
79 panel_label(
80 ui,
81 parent,
82 "workspace.inspector.position",
83 "Position: 12, 4, -8",
84 );
85 panel_label(
86 ui,
87 parent,
88 "workspace.inspector.material",
89 "Material: brushed steel",
90 );
91 }
92 "timeline" => {
93 panel_label(ui, parent, "workspace.timeline.one", "Frame 0000");
94 panel_label(ui, parent, "workspace.timeline.two", "Frame 0120");
95 }
96 _ => {}
97 }
98}
99
100fn panel_heading(ui: &mut UiDocument, parent: operad::UiNodeId, name: &str, text: &str) {
101 widgets::label(
102 ui,
103 parent,
104 name,
105 text,
106 TextStyle {
107 font_size: 16.0,
108 line_height: 22.0,
109 color: ColorRgba::WHITE,
110 ..TextStyle::default()
111 },
112 LayoutStyle::new().with_width_percent(1.0).with_height(28.0),
113 );
114}
115
116fn panel_label(ui: &mut UiDocument, parent: operad::UiNodeId, name: &str, text: &str) {
117 widgets::label(
118 ui,
119 parent,
120 name,
121 text,
122 TextStyle::default(),
123 LayoutStyle::new().with_width_percent(1.0).with_height(24.0),
124 );
125}