Skip to content

Commit c8f6cae

Browse files
authored
eframe app creation refactor (#1363)
* Change how eframe apps are created * eframe: re-export epi::* so users don't need to care about what epi is
1 parent c768d1d commit c8f6cae

File tree

26 files changed

+387
-444
lines changed

26 files changed

+387
-444
lines changed

eframe/examples/confirm_exit.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
22

3-
use eframe::{egui, epi};
3+
use eframe::egui;
4+
5+
fn main() {
6+
let options = eframe::NativeOptions::default();
7+
eframe::run_native("Confirm exit", options, |_cc| Box::new(MyApp::default()));
8+
}
49

510
#[derive(Default)]
611
struct MyApp {
712
can_exit: bool,
813
is_exiting: bool,
914
}
1015

11-
impl epi::App for MyApp {
12-
fn name(&self) -> &str {
13-
"Confirm exit"
14-
}
15-
16+
impl eframe::App for MyApp {
1617
fn on_exit_event(&mut self) -> bool {
1718
self.is_exiting = true;
1819
self.can_exit
1920
}
2021

21-
fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
22+
fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) {
2223
egui::CentralPanel::default().show(ctx, |ui| {
2324
ui.heading("Try to close the window");
2425
});
@@ -42,8 +43,3 @@ impl epi::App for MyApp {
4243
}
4344
}
4445
}
45-
46-
fn main() {
47-
let options = eframe::NativeOptions::default();
48-
eframe::run_native(Box::new(MyApp::default()), options);
49-
}

eframe/examples/custom_3d.rs

+32-28
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,42 @@
88
99
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
1010

11-
use eframe::{egui, epi};
11+
use eframe::egui;
1212

1313
use parking_lot::Mutex;
1414
use std::sync::Arc;
1515

16-
#[derive(Default)]
16+
fn main() {
17+
let options = eframe::NativeOptions::default();
18+
eframe::run_native("Custom 3D painting in eframe", options, |cc| {
19+
Box::new(MyApp::new(cc))
20+
});
21+
}
22+
1723
struct MyApp {
18-
rotating_triangle: Arc<Mutex<Option<RotatingTriangle>>>,
24+
/// Behind an `Arc<Mutex<…>>` so we can pass it to [`egui::PaintCallback`] and paint later.
25+
rotating_triangle: Arc<Mutex<RotatingTriangle>>,
1926
angle: f32,
2027
}
2128

22-
impl epi::App for MyApp {
23-
fn name(&self) -> &str {
24-
"Custom 3D painting inside an egui window"
29+
impl MyApp {
30+
fn new(cc: &eframe::CreationContext<'_>) -> Self {
31+
Self {
32+
rotating_triangle: Arc::new(Mutex::new(RotatingTriangle::new(&cc.gl))),
33+
angle: 0.0,
34+
}
2535
}
36+
}
2637

27-
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
38+
impl eframe::App for MyApp {
39+
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
2840
egui::CentralPanel::default().show(ctx, |ui| {
29-
ui.heading("Here is some 3D stuff:");
41+
ui.horizontal(|ui| {
42+
ui.spacing_mut().item_spacing.x = 0.0;
43+
ui.label("The triangle is being painted using ");
44+
ui.hyperlink_to("glow", "https://github.com/grovesNL/glow");
45+
ui.label(" (OpenGL).");
46+
});
3047

3148
egui::ScrollArea::both().show(ui, |ui| {
3249
egui::Frame::dark_canvas(ui.style()).show(ui, |ui| {
@@ -35,14 +52,10 @@ impl epi::App for MyApp {
3552
ui.label("Drag to rotate!");
3653
});
3754
});
55+
}
3856

39-
let mut frame = egui::Frame::window(&*ctx.style());
40-
frame.fill = frame.fill.linear_multiply(0.5); // transparent
41-
egui::Window::new("3D stuff in a window")
42-
.frame(frame)
43-
.show(ctx, |ui| {
44-
self.custom_painting(ui);
45-
});
57+
fn on_exit(&mut self, gl: &glow::Context) {
58+
self.rotating_triangle.lock().destroy(gl)
4659
}
4760
}
4861

@@ -53,17 +66,15 @@ impl MyApp {
5366

5467
self.angle += response.drag_delta().x * 0.01;
5568

69+
// Clone locals so we can move them into the paint callback:
5670
let angle = self.angle;
5771
let rotating_triangle = self.rotating_triangle.clone();
5872

59-
let callback = egui::epaint::PaintCallback {
73+
let callback = egui::PaintCallback {
6074
rect,
6175
callback: std::sync::Arc::new(move |render_ctx| {
6276
if let Some(painter) = render_ctx.downcast_ref::<egui_glow::Painter>() {
63-
let mut rotating_triangle = rotating_triangle.lock();
64-
let rotating_triangle = rotating_triangle
65-
.get_or_insert_with(|| RotatingTriangle::new(painter.gl()));
66-
rotating_triangle.paint(painter.gl(), angle);
77+
rotating_triangle.lock().paint(painter.gl(), angle);
6778
} else {
6879
eprintln!("Can't do custom painting because we are not using a glow context");
6980
}
@@ -163,9 +174,7 @@ impl RotatingTriangle {
163174
}
164175
}
165176

166-
// TODO: figure out how to call this in a nice way
167-
#[allow(unused)]
168-
fn destroy(self, gl: &glow::Context) {
177+
fn destroy(&self, gl: &glow::Context) {
169178
use glow::HasContext as _;
170179
unsafe {
171180
gl.delete_program(self.program);
@@ -186,8 +195,3 @@ impl RotatingTriangle {
186195
}
187196
}
188197
}
189-
190-
fn main() {
191-
let options = eframe::NativeOptions::default();
192-
eframe::run_native(Box::new(MyApp::default()), options);
193-
}

eframe/examples/custom_font.rs

+44-49
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,61 @@
1-
use eframe::{egui, epi};
1+
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
2+
3+
use eframe::egui;
4+
5+
fn main() {
6+
let options = eframe::NativeOptions::default();
7+
eframe::run_native("egui example: custom font", options, |cc| {
8+
Box::new(MyApp::new(cc))
9+
});
10+
}
11+
12+
fn setup_custom_fonts(ctx: &egui::Context) {
13+
// Start with the default fonts (we will be adding to them rather than replacing them).
14+
let mut fonts = egui::FontDefinitions::default();
15+
16+
// Install my own font (maybe supporting non-latin characters).
17+
// .ttf and .otf files supported.
18+
fonts.font_data.insert(
19+
"my_font".to_owned(),
20+
egui::FontData::from_static(include_bytes!("../../epaint/fonts/Hack-Regular.ttf")),
21+
);
22+
23+
// Put my font first (highest priority) for proportional text:
24+
fonts
25+
.families
26+
.entry(egui::FontFamily::Proportional)
27+
.or_default()
28+
.insert(0, "my_font".to_owned());
29+
30+
// Put my font as last fallback for monospace:
31+
fonts
32+
.families
33+
.entry(egui::FontFamily::Monospace)
34+
.or_default()
35+
.push("my_font".to_owned());
36+
37+
// Tell egui to use these fonts:
38+
ctx.set_fonts(fonts);
39+
}
240

341
struct MyApp {
442
text: String,
543
}
644

7-
impl Default for MyApp {
8-
fn default() -> Self {
45+
impl MyApp {
46+
fn new(cc: &eframe::CreationContext<'_>) -> Self {
47+
setup_custom_fonts(&cc.egui_ctx);
948
Self {
1049
text: "Edit this text field if you want".to_owned(),
1150
}
1251
}
1352
}
1453

15-
impl epi::App for MyApp {
16-
fn name(&self) -> &str {
17-
"egui example: custom font"
18-
}
19-
20-
fn setup(
21-
&mut self,
22-
ctx: &egui::Context,
23-
_frame: &epi::Frame,
24-
_storage: Option<&dyn epi::Storage>,
25-
_gl: &std::rc::Rc<epi::glow::Context>,
26-
) {
27-
// Start with the default fonts (we will be adding to them rather than replacing them).
28-
let mut fonts = egui::FontDefinitions::default();
29-
30-
// Install my own font (maybe supporting non-latin characters).
31-
// .ttf and .otf files supported.
32-
fonts.font_data.insert(
33-
"my_font".to_owned(),
34-
egui::FontData::from_static(include_bytes!("../../epaint/fonts/Hack-Regular.ttf")),
35-
);
36-
37-
// Put my font first (highest priority) for proportional text:
38-
fonts
39-
.families
40-
.entry(egui::FontFamily::Proportional)
41-
.or_default()
42-
.insert(0, "my_font".to_owned());
43-
44-
// Put my font as last fallback for monospace:
45-
fonts
46-
.families
47-
.entry(egui::FontFamily::Monospace)
48-
.or_default()
49-
.push("my_font".to_owned());
50-
51-
// Tell egui to use these fonts:
52-
ctx.set_fonts(fonts);
53-
}
54-
55-
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
54+
impl eframe::App for MyApp {
55+
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
5656
egui::CentralPanel::default().show(ctx, |ui| {
5757
ui.heading("egui using custom fonts");
5858
ui.text_edit_multiline(&mut self.text);
5959
});
6060
}
6161
}
62-
63-
fn main() {
64-
let options = eframe::NativeOptions::default();
65-
eframe::run_native(Box::new(MyApp::default()), options);
66-
}

eframe/examples/download_image.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
22

3-
use eframe::{egui, epi};
3+
use eframe::egui;
44
use egui_extras::RetainedImage;
55
use poll_promise::Promise;
66

77
fn main() {
88
let options = eframe::NativeOptions::default();
9-
eframe::run_native(Box::new(MyApp::default()), options);
9+
eframe::run_native(
10+
"Download and show an image with eframe/egui",
11+
options,
12+
|_cc| Box::new(MyApp::default()),
13+
);
1014
}
1115

1216
#[derive(Default)]
@@ -15,12 +19,8 @@ struct MyApp {
1519
promise: Option<Promise<ehttp::Result<RetainedImage>>>,
1620
}
1721

18-
impl epi::App for MyApp {
19-
fn name(&self) -> &str {
20-
"Download and show an image with eframe/egui"
21-
}
22-
23-
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
22+
impl eframe::App for MyApp {
23+
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
2424
let promise = self.promise.get_or_insert_with(|| {
2525
// Begin download.
2626
// We download the image using `ehttp`, a library that works both in WASM and on native.

eframe/examples/file_dialog.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
22

3-
use eframe::{egui, epi};
3+
use eframe::egui;
4+
5+
fn main() {
6+
let options = eframe::NativeOptions {
7+
drag_and_drop_support: true,
8+
..Default::default()
9+
};
10+
eframe::run_native(
11+
"Native file dialogs and drag-and-drop files",
12+
options,
13+
|_cc| Box::new(MyApp::default()),
14+
);
15+
}
416

517
#[derive(Default)]
618
struct MyApp {
719
dropped_files: Vec<egui::DroppedFile>,
820
picked_path: Option<String>,
921
}
1022

11-
impl epi::App for MyApp {
12-
fn name(&self) -> &str {
13-
"Native file dialogs and drag-and-drop files"
14-
}
15-
16-
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
23+
impl eframe::App for MyApp {
24+
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
1725
egui::CentralPanel::default().show(ctx, |ui| {
1826
ui.label("Drag-and-drop files onto the window!");
1927

@@ -93,11 +101,3 @@ impl MyApp {
93101
}
94102
}
95103
}
96-
97-
fn main() {
98-
let options = eframe::NativeOptions {
99-
drag_and_drop_support: true,
100-
..Default::default()
101-
};
102-
eframe::run_native(Box::new(MyApp::default()), options);
103-
}

eframe/examples/hello_world.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
22

3-
use eframe::{egui, epi};
3+
use eframe::egui;
4+
5+
fn main() {
6+
let options = eframe::NativeOptions::default();
7+
eframe::run_native("My egui App", options, |_cc| Box::new(MyApp::default()));
8+
}
49

510
struct MyApp {
611
name: String,
@@ -16,12 +21,8 @@ impl Default for MyApp {
1621
}
1722
}
1823

19-
impl epi::App for MyApp {
20-
fn name(&self) -> &str {
21-
"My egui App"
22-
}
23-
24-
fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
24+
impl eframe::App for MyApp {
25+
fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) {
2526
egui::CentralPanel::default().show(ctx, |ui| {
2627
ui.heading("My egui Application");
2728
ui.horizontal(|ui| {
@@ -39,8 +40,3 @@ impl epi::App for MyApp {
3940
frame.set_window_size(ctx.used_size());
4041
}
4142
}
42-
43-
fn main() {
44-
let options = eframe::NativeOptions::default();
45-
eframe::run_native(Box::new(MyApp::default()), options);
46-
}

0 commit comments

Comments
 (0)