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
use crate::App;
impl App {
/// Main app panel
pub fn show_central_panel(&mut self, ctx: &egui::Context) {
egui::CentralPanel::default().show(ctx, |ui| {
let mut scene_rect = self.scene_rect;
let available_size = ui.available_size() - ui.spacing().item_spacing * 2.0;
if self.state.edited_texture.is_none() && self.state.image_texture.is_none() {
// no image loaded
let (rect, res) = ui.allocate_exact_size(available_size, egui::Sense::click());
ui.painter().text(
rect.center(),
egui::Align2::CENTER_CENTER,
"Load image ...",
egui::FontId::default(),
egui::Color32::GRAY,
);
if res.clicked() {
self.open_picker.pick_file();
}
} else {
egui::Scene::new()
.zoom_range(1.0..=256.0)
.max_inner_size(available_size)
.show(ui, &mut scene_rect, |ui| {
let rect = if !self.state.show_original
&& let Some(texture) = &self.state.edited_texture
{
// display edited image
let res = ui.add(
egui::Image::from_texture(texture)
.texture_options(egui::TextureOptions::NEAREST)
.max_size(available_size)
.fit_to_exact_size(available_size)
.corner_radius(4.0)
.sense(egui::Sense::click()),
);
if res.clicked() {
self.state.show_original = true;
}
res.rect
} else if let Some(texture) = &self.state.image_texture {
// display original image
let res = ui.add(
egui::Image::from_texture(texture)
.texture_options(egui::TextureOptions::NEAREST)
.max_size(available_size)
.fit_to_exact_size(available_size)
.corner_radius(4.0)
.sense(egui::Sense::click()),
);
if res.clicked() {
if self.state.edited_texture.is_none() {
// apply if there's no edited texture to show
self.apply();
}
self.state.show_original = false;
}
// draw "original" indicator
let painter = ui.painter();
let pos = res.rect.min + egui::Vec2::splat(8.);
let galley = painter.layout_no_wrap(
"Original".to_string(),
egui::TextStyle::Body.resolve(ui.style()),
egui::Color32::WHITE,
);
let text_rect = egui::Rect::from_min_size(pos, galley.size());
let padding = egui::Vec2::splat(6.0);
let bg_rect = text_rect.expand2(padding);
painter.rect_filled(
bg_rect,
2.0,
egui::Color32::from_rgba_unmultiplied(0x16, 0x16, 0x16, 172),
);
painter.galley(pos, galley, egui::Color32::WHITE);
res.rect
} else {
unreachable!();
};
// paint border
ui.painter().rect_stroke(
rect,
4.0,
egui::Stroke::new(1.0, egui::Color32::GRAY),
egui::StrokeKind::Middle,
);
});
}
self.scene_rect = scene_rect;
ui.with_layout(egui::Layout::bottom_up(egui::Align::RIGHT), |ui| {
egui::warn_if_debug_build(ui);
});
});
}
}