Skip to content

Commit

Permalink
eframe app creation refactor (#1363)
Browse files Browse the repository at this point in the history
* Change how eframe apps are created
* eframe: re-export epi::* so users don't need to care about what epi is
  • Loading branch information
emilk authored Mar 16, 2022
1 parent c768d1d commit c8f6cae
Show file tree
Hide file tree
Showing 26 changed files with 387 additions and 444 deletions.
20 changes: 8 additions & 12 deletions eframe/examples/confirm_exit.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::{egui, epi};
use eframe::egui;

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native("Confirm exit", options, |_cc| Box::new(MyApp::default()));
}

#[derive(Default)]
struct MyApp {
can_exit: bool,
is_exiting: bool,
}

impl epi::App for MyApp {
fn name(&self) -> &str {
"Confirm exit"
}

impl eframe::App for MyApp {
fn on_exit_event(&mut self) -> bool {
self.is_exiting = true;
self.can_exit
}

fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Try to close the window");
});
Expand All @@ -42,8 +43,3 @@ impl epi::App for MyApp {
}
}
}

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(Box::new(MyApp::default()), options);
}
60 changes: 32 additions & 28 deletions eframe/examples/custom_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,42 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::{egui, epi};
use eframe::egui;

use parking_lot::Mutex;
use std::sync::Arc;

#[derive(Default)]
fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native("Custom 3D painting in eframe", options, |cc| {
Box::new(MyApp::new(cc))
});
}

struct MyApp {
rotating_triangle: Arc<Mutex<Option<RotatingTriangle>>>,
/// Behind an `Arc<Mutex<…>>` so we can pass it to [`egui::PaintCallback`] and paint later.
rotating_triangle: Arc<Mutex<RotatingTriangle>>,
angle: f32,
}

impl epi::App for MyApp {
fn name(&self) -> &str {
"Custom 3D painting inside an egui window"
impl MyApp {
fn new(cc: &eframe::CreationContext<'_>) -> Self {
Self {
rotating_triangle: Arc::new(Mutex::new(RotatingTriangle::new(&cc.gl))),
angle: 0.0,
}
}
}

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

egui::ScrollArea::both().show(ui, |ui| {
egui::Frame::dark_canvas(ui.style()).show(ui, |ui| {
Expand All @@ -35,14 +52,10 @@ impl epi::App for MyApp {
ui.label("Drag to rotate!");
});
});
}

let mut frame = egui::Frame::window(&*ctx.style());
frame.fill = frame.fill.linear_multiply(0.5); // transparent
egui::Window::new("3D stuff in a window")
.frame(frame)
.show(ctx, |ui| {
self.custom_painting(ui);
});
fn on_exit(&mut self, gl: &glow::Context) {
self.rotating_triangle.lock().destroy(gl)
}
}

Expand All @@ -53,17 +66,15 @@ impl MyApp {

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

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

let callback = egui::epaint::PaintCallback {
let callback = egui::PaintCallback {
rect,
callback: std::sync::Arc::new(move |render_ctx| {
if let Some(painter) = render_ctx.downcast_ref::<egui_glow::Painter>() {
let mut rotating_triangle = rotating_triangle.lock();
let rotating_triangle = rotating_triangle
.get_or_insert_with(|| RotatingTriangle::new(painter.gl()));
rotating_triangle.paint(painter.gl(), angle);
rotating_triangle.lock().paint(painter.gl(), angle);
} else {
eprintln!("Can't do custom painting because we are not using a glow context");
}
Expand Down Expand Up @@ -163,9 +174,7 @@ impl RotatingTriangle {
}
}

// TODO: figure out how to call this in a nice way
#[allow(unused)]
fn destroy(self, gl: &glow::Context) {
fn destroy(&self, gl: &glow::Context) {
use glow::HasContext as _;
unsafe {
gl.delete_program(self.program);
Expand All @@ -186,8 +195,3 @@ impl RotatingTriangle {
}
}
}

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(Box::new(MyApp::default()), options);
}
93 changes: 44 additions & 49 deletions eframe/examples/custom_font.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,61 @@
use eframe::{egui, epi};
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::egui;

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native("egui example: custom font", options, |cc| {
Box::new(MyApp::new(cc))
});
}

fn setup_custom_fonts(ctx: &egui::Context) {
// Start with the default fonts (we will be adding to them rather than replacing them).
let mut fonts = egui::FontDefinitions::default();

// Install my own font (maybe supporting non-latin characters).
// .ttf and .otf files supported.
fonts.font_data.insert(
"my_font".to_owned(),
egui::FontData::from_static(include_bytes!("../../epaint/fonts/Hack-Regular.ttf")),
);

// Put my font first (highest priority) for proportional text:
fonts
.families
.entry(egui::FontFamily::Proportional)
.or_default()
.insert(0, "my_font".to_owned());

// Put my font as last fallback for monospace:
fonts
.families
.entry(egui::FontFamily::Monospace)
.or_default()
.push("my_font".to_owned());

// Tell egui to use these fonts:
ctx.set_fonts(fonts);
}

struct MyApp {
text: String,
}

impl Default for MyApp {
fn default() -> Self {
impl MyApp {
fn new(cc: &eframe::CreationContext<'_>) -> Self {
setup_custom_fonts(&cc.egui_ctx);
Self {
text: "Edit this text field if you want".to_owned(),
}
}
}

impl epi::App for MyApp {
fn name(&self) -> &str {
"egui example: custom font"
}

fn setup(
&mut self,
ctx: &egui::Context,
_frame: &epi::Frame,
_storage: Option<&dyn epi::Storage>,
_gl: &std::rc::Rc<epi::glow::Context>,
) {
// Start with the default fonts (we will be adding to them rather than replacing them).
let mut fonts = egui::FontDefinitions::default();

// Install my own font (maybe supporting non-latin characters).
// .ttf and .otf files supported.
fonts.font_data.insert(
"my_font".to_owned(),
egui::FontData::from_static(include_bytes!("../../epaint/fonts/Hack-Regular.ttf")),
);

// Put my font first (highest priority) for proportional text:
fonts
.families
.entry(egui::FontFamily::Proportional)
.or_default()
.insert(0, "my_font".to_owned());

// Put my font as last fallback for monospace:
fonts
.families
.entry(egui::FontFamily::Monospace)
.or_default()
.push("my_font".to_owned());

// Tell egui to use these fonts:
ctx.set_fonts(fonts);
}

fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("egui using custom fonts");
ui.text_edit_multiline(&mut self.text);
});
}
}

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(Box::new(MyApp::default()), options);
}
16 changes: 8 additions & 8 deletions eframe/examples/download_image.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::{egui, epi};
use eframe::egui;
use egui_extras::RetainedImage;
use poll_promise::Promise;

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(Box::new(MyApp::default()), options);
eframe::run_native(
"Download and show an image with eframe/egui",
options,
|_cc| Box::new(MyApp::default()),
);
}

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

impl epi::App for MyApp {
fn name(&self) -> &str {
"Download and show an image with eframe/egui"
}

fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
let promise = self.promise.get_or_insert_with(|| {
// Begin download.
// We download the image using `ehttp`, a library that works both in WASM and on native.
Expand Down
30 changes: 15 additions & 15 deletions eframe/examples/file_dialog.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::{egui, epi};
use eframe::egui;

fn main() {
let options = eframe::NativeOptions {
drag_and_drop_support: true,
..Default::default()
};
eframe::run_native(
"Native file dialogs and drag-and-drop files",
options,
|_cc| Box::new(MyApp::default()),
);
}

#[derive(Default)]
struct MyApp {
dropped_files: Vec<egui::DroppedFile>,
picked_path: Option<String>,
}

impl epi::App for MyApp {
fn name(&self) -> &str {
"Native file dialogs and drag-and-drop files"
}

fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Drag-and-drop files onto the window!");

Expand Down Expand Up @@ -93,11 +101,3 @@ impl MyApp {
}
}
}

fn main() {
let options = eframe::NativeOptions {
drag_and_drop_support: true,
..Default::default()
};
eframe::run_native(Box::new(MyApp::default()), options);
}
20 changes: 8 additions & 12 deletions eframe/examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::{egui, epi};
use eframe::egui;

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native("My egui App", options, |_cc| Box::new(MyApp::default()));
}

struct MyApp {
name: String,
Expand All @@ -16,12 +21,8 @@ impl Default for MyApp {
}
}

impl epi::App for MyApp {
fn name(&self) -> &str {
"My egui App"
}

fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Application");
ui.horizontal(|ui| {
Expand All @@ -39,8 +40,3 @@ impl epi::App for MyApp {
frame.set_window_size(ctx.used_size());
}
}

fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(Box::new(MyApp::default()), options);
}
Loading

0 comments on commit c8f6cae

Please sign in to comment.