tirbofish/dropbear
main / crates / eucalyptus-editor / src / editor / ui / viewport.rs · 4280 bytes
crates/eucalyptus-editor/src/editor/ui/viewport.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::editor::page::EditorTabVisibility;
use crate::editor::{EditorTabDock, EditorTabDockDescriptor, EditorTabViewer};
use egui::Ui;
use glam::Vec2;
pub struct UICanvas;
impl EditorTabDock for UICanvas {
fn desc() -> EditorTabDockDescriptor {
EditorTabDockDescriptor {
id: "UI Viewport", // kept for some reason, change on release
title: "UI Canvas".to_string(),
visibility: EditorTabVisibility::UIEditor,
}
}
fn display(viewer: &mut EditorTabViewer<'_>, ui: &mut Ui) {
let available_rect = ui.available_rect_before_wrap();
let available_size = available_rect.size();
let pixels_per_point = ui.ctx().pixels_per_point();
let desired_width = (available_size.x * pixels_per_point).max(1.0).round() as u32;
let desired_height = (available_size.y * pixels_per_point).max(1.0).round() as u32;
viewer
.ui_editor
.render(viewer.graphics.clone(), desired_width, desired_height);
if let Some(texture_id) = viewer.ui_editor.texture_id() {
let response = ui.add_sized(
[available_size.x, available_size.y],
egui::Image::new((texture_id, available_size)).sense(egui::Sense::drag()),
);
let ppp = ui.ctx().pixels_per_point();
let viewport_pixels = Vec2::new(available_size.x * ppp, available_size.y * ppp);
if response.hovered() {
ui.ctx().input(|i| {
// pinch
let zoom_delta = i.zoom_delta();
if (zoom_delta - 1.0).abs() > f32::EPSILON {
viewer.ui_editor.zoom_by(zoom_delta - 1.0);
}
// scroll wheel
let scroll_y = i.smooth_scroll_delta.y;
let is_trackpad_panning = i.smooth_scroll_delta != egui::Vec2::ZERO;
if scroll_y.abs() > 0.0 && !is_trackpad_panning {
viewer.ui_editor.zoom_by(scroll_y * 0.0025);
}
// trackpad pan
let smooth_scroll = i.smooth_scroll_delta;
if smooth_scroll != egui::Vec2::ZERO {
let delta_pixels = Vec2::new(smooth_scroll.x * ppp, smooth_scroll.y * ppp);
viewer.ui_editor.pan_by_pixels(delta_pixels);
}
});
}
let is_middle_down = ui
.ctx()
.input(|i| i.pointer.button_down(egui::PointerButton::Middle));
// middle mouse button
if response.hovered() && is_middle_down {
let pointer_delta_points = ui.ctx().input(|i| i.pointer.delta());
if pointer_delta_points != egui::Vec2::ZERO {
let delta_pixels =
Vec2::new(pointer_delta_points.x * ppp, pointer_delta_points.y * ppp);
viewer.ui_editor.pan_by_pixels(delta_pixels);
}
}
let cursor_info = response.hover_pos().map(|hover_pos| {
let local = hover_pos - response.rect.min;
let pixel = Vec2::new(local.x * ppp, local.y * ppp);
viewer
.ui_editor
.world_from_screen_pixels(pixel, viewport_pixels)
});
let zoom_percent = viewer.ui_editor.zoom() * 100.0;
let hud = if let Some(world) = cursor_info {
format!(
"Coords: ({:.1}, {:.1}) u | zoom: {:.0}%",
world.x, world.y, zoom_percent
)
} else {
format!("Coords: (-, -) u | zoom: {:.0}%", zoom_percent)
};
let text_pos = response.rect.left_top() + egui::vec2(8.0, 8.0);
ui.painter().text(
text_pos,
egui::Align2::LEFT_TOP,
hud,
egui::TextStyle::Monospace.resolve(ui.style()),
egui::Color32::WHITE,
);
} else {
ui.centered_and_justified(|ui| {
ui.label("UI viewport texture is initialising...");
});
}
}
}