diff --git a/Cargo.lock b/Cargo.lock index 9b445721..c0445850 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1953,6 +1953,14 @@ dependencies = [ "eframe", ] +[[package]] +name = "hello_world_simple" +version = "0.1.0" +dependencies = [ + "eframe", + "tracing-subscriber", +] + [[package]] name = "hermit-abi" version = "0.1.19" diff --git a/crates/eframe/CHANGELOG.md b/crates/eframe/CHANGELOG.md index 7e8eb9eb..da8fa17c 100644 --- a/crates/eframe/CHANGELOG.md +++ b/crates/eframe/CHANGELOG.md @@ -6,6 +6,7 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C ## Unreleased * Add `Frame::request_screenshot` and `Frame::screenshot` to communicate to the backend that a screenshot of the current frame should be exposed by `Frame` during `App::post_rendering` ([#2676](https://github.com/emilk/egui/pull/2676)) +* Add `eframe::run_simple_native` - a simple API for simple apps ([#2453](https://github.com/emilk/egui/pull/2453)). ## 0.21.3 - 2023-02-15 diff --git a/crates/eframe/src/lib.rs b/crates/eframe/src/lib.rs index a2181c58..665f3904 100644 --- a/crates/eframe/src/lib.rs +++ b/crates/eframe/src/lib.rs @@ -54,6 +54,10 @@ //! } //! ``` //! +//! ## Simplified usage +//! If your app is only for native, and you don't need advanced features like state persistence, +//! then you can use the simpler function [`run_simple_native`]. +//! //! ## Feature flags #![cfg_attr(feature = "document-features", doc = document_features::document_features!())] //! @@ -149,9 +153,9 @@ mod native; /// ``` no_run /// use eframe::egui; /// -/// fn main() { +/// fn main() -> eframe::Result<()> { /// let native_options = eframe::NativeOptions::default(); -/// eframe::run_native("MyApp", native_options, Box::new(|cc| Box::new(MyEguiApp::new(cc)))); +/// eframe::run_native("MyApp", native_options, Box::new(|cc| Box::new(MyEguiApp::new(cc)))) /// } /// /// #[derive(Default)] @@ -179,8 +183,8 @@ mod native; /// # Errors /// This function can fail if we fail to set up a graphics context. #[cfg(not(target_arch = "wasm32"))] -#[allow(clippy::needless_pass_by_value)] #[cfg(any(feature = "glow", feature = "wgpu"))] +#[allow(clippy::needless_pass_by_value)] pub fn run_native( app_name: &str, native_options: NativeOptions, @@ -211,6 +215,63 @@ pub fn run_native( // ---------------------------------------------------------------------------- +/// The simplest way to get started when writing a native app. +/// +/// This does NOT support persistence. For that you need to use [`run_native`]. +/// +/// # Example +/// ``` no_run +/// fn main() -> eframe::Result<()> { +/// // Our application state: +/// let mut name = "Arthur".to_owned(); +/// let mut age = 42; +/// +/// let options = eframe::NativeOptions::default(); +/// eframe::run_simple_native("My egui App", options, move |ctx, _frame| { +/// egui::CentralPanel::default().show(ctx, |ui| { +/// ui.heading("My egui Application"); +/// ui.horizontal(|ui| { +/// let name_label = ui.label("Your name: "); +/// ui.text_edit_singleline(&mut name) +/// .labelled_by(name_label.id); +/// }); +/// ui.add(egui::Slider::new(&mut age, 0..=120).text("age")); +/// if ui.button("Click each year").clicked() { +/// age += 1; +/// } +/// ui.label(format!("Hello '{}', age {}", name, age)); +/// }); +/// }) +/// } +/// ``` +/// +/// # Errors +/// This function can fail if we fail to set up a graphics context. +#[cfg(not(target_arch = "wasm32"))] +#[cfg(any(feature = "glow", feature = "wgpu"))] +pub fn run_simple_native( + app_name: &str, + native_options: NativeOptions, + update_fun: impl FnMut(&egui::Context, &mut Frame) + 'static, +) -> Result<()> { + struct SimpleApp { + update_fun: U, + } + impl App for SimpleApp { + fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) { + (self.update_fun)(ctx, frame); + } + } + + run_native( + app_name, + native_options, + Box::new(|_cc| Box::new(SimpleApp { update_fun })), + ) +} + +// ---------------------------------------------------------------------------- + /// The different problems that can occur when trying to run `eframe`. #[derive(thiserror::Error, Debug)] pub enum Error { diff --git a/examples/hello_world_simple/Cargo.toml b/examples/hello_world_simple/Cargo.toml new file mode 100644 index 00000000..6c06c174 --- /dev/null +++ b/examples/hello_world_simple/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "hello_world_simple" +version = "0.1.0" +authors = ["Emil Ernerfeldt "] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.65" +publish = false + + +[dependencies] +eframe = { path = "../../crates/eframe", features = [ + "__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO +] } +tracing-subscriber = "0.3" diff --git a/examples/hello_world_simple/README.md b/examples/hello_world_simple/README.md new file mode 100644 index 00000000..08c58a7d --- /dev/null +++ b/examples/hello_world_simple/README.md @@ -0,0 +1,7 @@ +Example showing some UI controls like `Label`, `TextEdit`, `Slider`, `Button`. + +```sh +cargo run -p hello_world +``` + +![](screenshot.png) diff --git a/examples/hello_world_simple/screenshot.png b/examples/hello_world_simple/screenshot.png new file mode 100644 index 00000000..765339d4 Binary files /dev/null and b/examples/hello_world_simple/screenshot.png differ diff --git a/examples/hello_world_simple/src/main.rs b/examples/hello_world_simple/src/main.rs new file mode 100644 index 00000000..cecc6804 --- /dev/null +++ b/examples/hello_world_simple/src/main.rs @@ -0,0 +1,33 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release + +use eframe::egui; + +fn main() -> Result<(), eframe::Error> { + // Log to stdout (if you run with `RUST_LOG=debug`). + tracing_subscriber::fmt::init(); + + let options = eframe::NativeOptions { + initial_window_size: Some(egui::vec2(320.0, 240.0)), + ..Default::default() + }; + + // Our application state: + let mut name = "Arthur".to_owned(); + let mut age = 42; + + eframe::run_simple_native("My egui App", options, move |ctx, _frame| { + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("My egui Application"); + ui.horizontal(|ui| { + let name_label = ui.label("Your name: "); + ui.text_edit_singleline(&mut name) + .labelled_by(name_label.id); + }); + ui.add(egui::Slider::new(&mut age, 0..=120).text("age")); + if ui.button("Click each year").clicked() { + age += 1; + } + ui.label(format!("Hello '{}', age {}", name, age)); + }); + }) +}