Skip to main content

rustapi/docks/
data_editor.rs

1use crate::docks::data::DataDock;
2use crate::prelude::*;
3
4pub struct DataEditorDock {
5    inner: DataDock,
6}
7
8impl Dock for DataEditorDock {
9    fn new() -> Self
10    where
11        Self: Sized,
12    {
13        Self {
14            inner: DataDock::new(),
15        }
16    }
17
18    fn setup(&mut self, _ctx: &mut TheContext) -> TheCanvas {
19        let mut center = TheCanvas::new();
20
21        let mut preview_canvas = TheCanvas::new();
22        let mut preview_layout = TheRGBALayout::new(TheId::named("Data Editor RGBA Layout"));
23        if let Some(rgba_view) = preview_layout.rgba_view_mut().as_rgba_view() {
24            rgba_view.set_mode(TheRGBAViewMode::TilePicker);
25            rgba_view.set_background([24, 24, 24, 255]);
26            rgba_view.set_grid(None);
27            rgba_view.set_supports_external_zoom(false);
28        }
29        preview_canvas.set_layout(preview_layout);
30        center.set_top(preview_canvas);
31
32        let mut textedit = TheTextAreaEdit::new(TheId::named("DockDataEditorMax"));
33        if let Some(bytes) = crate::Embedded::get("parser/TOML.sublime-syntax")
34            && let Ok(source) = std::str::from_utf8(bytes.data.as_ref())
35        {
36            textedit.add_syntax_from_string(source);
37            textedit.set_code_type("TOML");
38        }
39        if let Some(bytes) = crate::Embedded::get("parser/gruvbox-dark.tmTheme")
40            && let Ok(source) = std::str::from_utf8(bytes.data.as_ref())
41        {
42            textedit.add_theme_from_string(source);
43            textedit.set_code_theme("Gruvbox Dark");
44        }
45        textedit.set_continuous(true);
46        textedit.display_line_number(true);
47        textedit.use_global_statusbar(true);
48        textedit.set_font_size(14.0);
49        textedit.set_supports_undo(false);
50        center.set_widget(textedit);
51
52        center
53    }
54
55    fn activate(
56        &mut self,
57        ui: &mut TheUI,
58        ctx: &mut TheContext,
59        project: &Project,
60        server_ctx: &mut ServerContext,
61    ) {
62        self.inner.activate(ui, ctx, project, server_ctx);
63        self.sync_hidden_to_max_editor(ui, ctx);
64        self.update_preview(ui, ctx, project, server_ctx);
65    }
66
67    fn minimized(&mut self, ui: &mut TheUI, ctx: &mut TheContext) {
68        self.inner.minimized(ui, ctx);
69    }
70
71    fn supports_actions(&self) -> bool {
72        self.inner.supports_actions()
73    }
74
75    fn supports_undo(&self) -> bool {
76        self.inner.supports_undo()
77    }
78
79    fn has_changes(&self) -> bool {
80        self.inner.has_changes()
81    }
82
83    fn mark_saved(&mut self) {
84        self.inner.mark_saved();
85    }
86
87    fn set_undo_state_to_ui(&self, ctx: &mut TheContext) {
88        self.inner.set_undo_state_to_ui(ctx);
89    }
90
91    fn handle_event(
92        &mut self,
93        event: &TheEvent,
94        ui: &mut TheUI,
95        ctx: &mut TheContext,
96        project: &mut Project,
97        server_ctx: &mut ServerContext,
98    ) -> bool {
99        let mut redraw = if let TheEvent::ValueChanged(id, value) = event
100            && id.name == "DockDataEditorMax"
101        {
102            let forwarded = TheEvent::ValueChanged(TheId::named("DockDataEditor"), value.clone());
103            self.inner
104                .handle_event(&forwarded, ui, ctx, project, server_ctx)
105        } else {
106            self.inner.handle_event(event, ui, ctx, project, server_ctx)
107        };
108        if let TheEvent::WidgetResized(id, _) = event
109            && id.name == "Data Editor RGBA Layout View"
110        {
111            redraw = true;
112        }
113        if let TheEvent::Custom(id, _) = event
114            && id.name == "Soft Update Minimap"
115        {
116            redraw = true;
117        }
118        if redraw {
119            self.sync_hidden_to_max_editor(ui, ctx);
120            self.update_preview(ui, ctx, project, server_ctx);
121        }
122        redraw
123    }
124
125    fn undo(
126        &mut self,
127        ui: &mut TheUI,
128        ctx: &mut TheContext,
129        project: &mut Project,
130        server_ctx: &mut ServerContext,
131    ) {
132        self.inner.undo(ui, ctx, project, server_ctx);
133        self.sync_hidden_to_max_editor(ui, ctx);
134        self.update_preview(ui, ctx, project, server_ctx);
135    }
136
137    fn redo(
138        &mut self,
139        ui: &mut TheUI,
140        ctx: &mut TheContext,
141        project: &mut Project,
142        server_ctx: &mut ServerContext,
143    ) {
144        self.inner.redo(ui, ctx, project, server_ctx);
145        self.sync_hidden_to_max_editor(ui, ctx);
146        self.update_preview(ui, ctx, project, server_ctx);
147    }
148
149    fn draw_minimap(
150        &self,
151        buffer: &mut TheRGBABuffer,
152        project: &Project,
153        ctx: &mut TheContext,
154        server_ctx: &ServerContext,
155    ) -> bool {
156        self.inner.draw_minimap(buffer, project, ctx, server_ctx)
157    }
158
159    fn supports_minimap_animation(&self) -> bool {
160        self.inner.supports_minimap_animation()
161    }
162}
163
164impl DataEditorDock {
165    fn sync_hidden_to_max_editor(&self, ui: &mut TheUI, ctx: &mut TheContext) {
166        if let Some(hidden) = ui.get_text_area_edit("DockDataEditor") {
167            let text = hidden.get_state().rows.join("\n");
168            ui.set_widget_value("DockDataEditorMax", ctx, TheValue::Text(text));
169        }
170    }
171
172    fn update_preview(
173        &self,
174        ui: &mut TheUI,
175        ctx: &mut TheContext,
176        project: &Project,
177        server_ctx: &ServerContext,
178    ) {
179        let Some(layout) = ui.get_rgba_layout("Data Editor RGBA Layout") else {
180            return;
181        };
182        let Some(view) = layout.rgba_view_mut().as_rgba_view() else {
183            return;
184        };
185        let dim = *view.dim();
186        let mut buffer = TheRGBABuffer::new(TheDim::sized(
187            (dim.width - 16).max(1),
188            (dim.height - 16).max(1),
189        ));
190        buffer.fill([18, 18, 18, 255]);
191        let _ = self
192            .inner
193            .draw_minimap(&mut buffer, project, ctx, server_ctx);
194        view.set_buffer(buffer);
195    }
196}