Move code from egui_demo_lib to egui_demo_app (#1540)

Also clean up feature names and dependencies
This commit is contained in:
Emil Ernerfeldt 2022-04-28 11:23:34 +02:00 committed by GitHub
parent 39917bec26
commit 355d70d2b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 213 additions and 174 deletions

11
Cargo.lock generated
View file

@ -1116,9 +1116,16 @@ dependencies = [
name = "egui_demo_app" name = "egui_demo_app"
version = "0.17.0" version = "0.17.0"
dependencies = [ dependencies = [
"chrono",
"console_error_panic_hook", "console_error_panic_hook",
"eframe", "eframe",
"egui",
"egui_demo_lib", "egui_demo_lib",
"egui_extras",
"ehttp",
"image",
"poll-promise",
"serde",
"tracing-subscriber", "tracing-subscriber",
"tracing-wasm", "tracing-wasm",
] ]
@ -1131,11 +1138,7 @@ dependencies = [
"criterion", "criterion",
"egui", "egui",
"egui_extras", "egui_extras",
"ehttp",
"enum-map", "enum-map",
"epi",
"image",
"poll-promise",
"serde", "serde",
"syntect", "syntect",
"tracing", "tracing",

View file

@ -16,21 +16,44 @@ crate-type = ["cdylib", "rlib"]
[features] [features]
default = ["persistence"] default = ["persistence"]
http = ["egui_demo_lib/http"]
persistence = ["eframe/persistence", "egui_demo_lib/persistence"] http = ["ehttp", "image", "poll-promise", "egui_extras/image"]
screen_reader = ["eframe/screen_reader"] # experimental persistence = [
"eframe/persistence",
"egui/persistence",
"serde",
]
screen_reader = ["eframe/screen_reader"] # experimental
serde = [
"dep:serde",
"egui_demo_lib/serde",
"egui_extras/serde",
"egui/serde",
]
syntax_highlighting = ["egui_demo_lib/syntax_highlighting"] syntax_highlighting = ["egui_demo_lib/syntax_highlighting"]
[dependencies] [dependencies]
chrono = { version = "0.4", features = ["js-sys", "wasmbind"] }
eframe = { version = "0.17.0", path = "../eframe" } eframe = { version = "0.17.0", path = "../eframe" }
egui = { version = "0.17.0", path = "../egui", features = ["extra_debug_asserts"] }
egui_demo_lib = { version = "0.17.0", path = "../egui_demo_lib", features = ["chrono"] }
# To use the old glium backend instead: # Optional dependencies:
# eframe = { version = "0.17.0", path = "../eframe", default-features = false, features = ["default_fonts", "egui_glium"] }
egui_demo_lib = { version = "0.17.0", path = "../egui_demo_lib", features = [ egui_extras = { version = "0.17.0", optional = true, path = "../egui_extras" }
"extra_debug_asserts",
# feature "http":
ehttp = { version = "0.2.0", optional = true }
image = { version = "0.24", optional = true, default-features = false, features = [
"jpeg",
"png",
] } ] }
poll-promise = { version = "0.1", optional = true, default-features = false }
# feature "persistence":
serde = { version = "1", optional = true, features = ["derive"] }
# native: # native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]

15
egui_demo_app/README.md Normal file
View file

@ -0,0 +1,15 @@
# egui demo app
This app demonstrates [`egui`](https://github.com/emilk/egui/) and [`eframe`](https://github.com/emilk/egui/tree/master/eframe).
View the demo app online at <https://egui.rs>.
Run it locally with `cargo run --release -p egui_demo_app`.
`egui_demo_app` can be compiled to WASM and viewed in a browser locally with:
```sh
./sh/start_server.sh &
./sh/build_demo_web.sh --fast --open
```
`egui_demo_app` uses [`egui_demo_lib`](https://github.com/emilk/egui/tree/master/egui_demo_lib).

View file

@ -32,14 +32,6 @@ impl Default for FractalClock {
} }
} }
impl epi::App for FractalClock {
fn update(&mut self, ctx: &egui::Context, _frame: &mut epi::Frame) {
egui::CentralPanel::default()
.frame(Frame::dark_canvas(&ctx.style()))
.show(ctx, |ui| self.ui(ui, crate::seconds_since_midnight()));
}
}
impl FractalClock { impl FractalClock {
pub fn ui(&mut self, ui: &mut Ui, seconds_since_midnight: Option<f64>) { pub fn ui(&mut self, ui: &mut Ui, seconds_since_midnight: Option<f64>) {
if !self.paused { if !self.paused {
@ -93,7 +85,7 @@ impl FractalClock {
"Inspired by a screensaver by Rob Mayoff", "Inspired by a screensaver by Rob Mayoff",
"http://www.dqd.com/~mayoff/programs/FractalClock/", "http://www.dqd.com/~mayoff/programs/FractalClock/",
); );
ui.add(crate::egui_github_link_file!()); ui.add(egui_demo_lib::egui_github_link_file!());
} }
fn paint(&mut self, painter: &Painter) { fn paint(&mut self, painter: &Painter) {

View file

@ -53,12 +53,12 @@ impl Default for HttpApp {
} }
} }
impl epi::App for HttpApp { impl eframe::App for HttpApp {
fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
egui::TopBottomPanel::bottom("http_bottom").show(ctx, |ui| { egui::TopBottomPanel::bottom("http_bottom").show(ctx, |ui| {
let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true); let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true);
ui.allocate_ui_with_layout(ui.available_size(), layout, |ui| { ui.allocate_ui_with_layout(ui.available_size(), layout, |ui| {
ui.add(crate::egui_github_link_file!()) ui.add(egui_demo_lib::egui_github_link_file!())
}) })
}); });
@ -108,7 +108,7 @@ impl epi::App for HttpApp {
} }
} }
fn ui_url(ui: &mut egui::Ui, frame: &mut epi::Frame, url: &mut String) -> bool { fn ui_url(ui: &mut egui::Ui, frame: &mut eframe::Frame, url: &mut String) -> bool {
let mut trigger_fetch = false; let mut trigger_fetch = false;
ui.horizontal(|ui| { ui.horizontal(|ui| {

View file

@ -1,13 +1,9 @@
mod color_test;
mod demo;
mod fractal_clock; mod fractal_clock;
#[cfg(feature = "http")] #[cfg(feature = "http")]
mod http_app; mod http_app;
pub use color_test::ColorTest;
pub use demo::DemoApp;
pub use fractal_clock::FractalClock; pub use fractal_clock::FractalClock;
#[cfg(feature = "http")] #[cfg(feature = "http")]
pub use http_app::HttpApp; pub use http_app::HttpApp;
pub use demo::DemoWindows; // used for tests

View file

@ -62,7 +62,7 @@ pub struct BackendPanel {
} }
impl BackendPanel { impl BackendPanel {
pub fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { pub fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
self.frame_history self.frame_history
.on_new_frame(ctx.input().time, frame.info().cpu_usage); .on_new_frame(ctx.input().time, frame.info().cpu_usage);
@ -76,7 +76,7 @@ impl BackendPanel {
self.egui_windows.windows(ctx); self.egui_windows.windows(ctx);
} }
pub fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame) { pub fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
egui::trace!(ui); egui::trace!(ui);
ui.vertical_centered(|ui| { ui.vertical_centered(|ui| {
ui.heading("💻 Backend"); ui.heading("💻 Backend");
@ -131,7 +131,7 @@ impl BackendPanel {
} }
} }
fn integration_ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame) { fn integration_ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
if frame.is_web() { if frame.is_web() {
ui.label("egui is an immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL."); ui.label("egui is an immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL.");
ui.label( ui.label(
@ -172,7 +172,7 @@ impl BackendPanel {
fn pixels_per_point_ui( fn pixels_per_point_ui(
&mut self, &mut self,
ui: &mut egui::Ui, ui: &mut egui::Ui,
info: &epi::IntegrationInfo, info: &eframe::IntegrationInfo,
) -> Option<f32> { ) -> Option<f32> {
let pixels_per_point = self.pixels_per_point.get_or_insert_with(|| { let pixels_per_point = self.pixels_per_point.get_or_insert_with(|| {
info.native_pixels_per_point info.native_pixels_per_point
@ -234,7 +234,7 @@ impl BackendPanel {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
fn show_integration_name(ui: &mut egui::Ui, integration_info: &epi::IntegrationInfo) { fn show_integration_name(ui: &mut egui::Ui, integration_info: &eframe::IntegrationInfo) {
let name = integration_info.name; let name = integration_info.name;
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0; ui.spacing_mut().item_spacing.x = 0.0;

View file

@ -1,5 +1,23 @@
//! Demo app for egui //! Demo app for egui
mod apps;
mod backend_panel;
pub(crate) mod frame_history;
mod wrap_app;
pub use wrap_app::WrapApp;
/// Time of day as seconds since midnight. Used for clock in demo app.
pub(crate) fn seconds_since_midnight() -> Option<f64> {
use chrono::Timelike;
let time = chrono::Local::now().time();
let seconds_since_midnight =
time.num_seconds_from_midnight() as f64 + 1e-9 * (time.nanosecond() as f64);
Some(seconds_since_midnight)
}
// ----------------------------------------------------------------------------
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use eframe::wasm_bindgen::{self, prelude::*}; use eframe::wasm_bindgen::{self, prelude::*};
@ -16,8 +34,5 @@ pub fn start(canvas_id: &str) -> Result<(), wasm_bindgen::JsValue> {
// Redirect tracing to console.log and friends: // Redirect tracing to console.log and friends:
tracing_wasm::set_as_global_default(); tracing_wasm::set_as_global_default();
eframe::start_web( eframe::start_web(canvas_id, Box::new(|cc| Box::new(WrapApp::new(cc))))
canvas_id,
Box::new(|cc| Box::new(egui_demo_lib::WrapApp::new(cc))),
)
} }

View file

@ -16,6 +16,6 @@ fn main() {
eframe::run_native( eframe::run_native(
"egui demo app", "egui demo app",
options, options,
Box::new(|cc| Box::new(egui_demo_lib::WrapApp::new(cc))), Box::new(|cc| Box::new(egui_demo_app::WrapApp::new(cc))),
); );
} }

View file

@ -1,36 +1,105 @@
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
struct EasyMarkApp {
editor: egui_demo_lib::easy_mark::EasyMarkEditor,
}
impl eframe::App for EasyMarkApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
self.editor.panels(ctx);
}
}
// ----------------------------------------------------------------------------
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct DemoApp {
demo_windows: egui_demo_lib::DemoWindows,
}
impl eframe::App for DemoApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
self.demo_windows.ui(ctx);
}
}
// ----------------------------------------------------------------------------
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct FractalClockApp {
fractal_clock: crate::apps::FractalClock,
}
impl eframe::App for FractalClockApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default()
.frame(egui::Frame::dark_canvas(&ctx.style()))
.show(ctx, |ui| {
self.fractal_clock.ui(ui, crate::seconds_since_midnight());
});
}
}
// ----------------------------------------------------------------------------
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct ColorTestApp {
color_test: egui_demo_lib::ColorTest,
}
impl eframe::App for ColorTestApp {
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
if frame.is_web() {
ui.label(
"NOTE: Some old browsers stuck on WebGL1 without sRGB support will not pass the color test.",
);
ui.separator();
}
egui::ScrollArea::both().auto_shrink([false; 2]).show(ui, |ui| {
self.color_test.ui(ui);
});
});
}
}
// ----------------------------------------------------------------------------
/// All the different demo apps. /// All the different demo apps.
#[derive(Default)] #[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))] #[cfg_attr(feature = "serde", serde(default))]
pub struct Apps { pub struct Apps {
demo: crate::apps::DemoApp, demo: DemoApp,
easy_mark_editor: crate::easy_mark::EasyMarkEditor, easy_mark_editor: EasyMarkApp,
#[cfg(feature = "http")] #[cfg(feature = "http")]
http: crate::apps::HttpApp, http: crate::apps::HttpApp,
clock: crate::apps::FractalClock, clock: FractalClockApp,
color_test: crate::apps::ColorTest, color_test: ColorTestApp,
} }
impl Apps { impl Apps {
fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &str, &mut dyn epi::App)> { fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &str, &mut dyn eframe::App)> {
vec![ vec![
("✨ Demos", "demo", &mut self.demo as &mut dyn epi::App), ("✨ Demos", "demo", &mut self.demo as &mut dyn eframe::App),
( (
"🖹 EasyMark editor", "🖹 EasyMark editor",
"easymark", "easymark",
&mut self.easy_mark_editor as &mut dyn epi::App, &mut self.easy_mark_editor as &mut dyn eframe::App,
), ),
#[cfg(feature = "http")] #[cfg(feature = "http")]
("⬇ HTTP", "http", &mut self.http as &mut dyn epi::App), ("⬇ HTTP", "http", &mut self.http as &mut dyn eframe::App),
( (
"🕑 Fractal Clock", "🕑 Fractal Clock",
"clock", "clock",
&mut self.clock as &mut dyn epi::App, &mut self.clock as &mut dyn eframe::App,
), ),
( (
"🎨 Color test", "🎨 Color test",
"colors", "colors",
&mut self.color_test as &mut dyn epi::App, &mut self.color_test as &mut dyn eframe::App,
), ),
] ]
.into_iter() .into_iter()
@ -50,26 +119,26 @@ pub struct WrapApp {
} }
impl WrapApp { impl WrapApp {
pub fn new(_cc: &epi::CreationContext<'_>) -> Self { pub fn new(_cc: &eframe::CreationContext<'_>) -> Self {
#[cfg(feature = "persistence")] #[cfg(feature = "persistence")]
if let Some(storage) = _cc.storage { if let Some(storage) = _cc.storage {
return epi::get_value(storage, epi::APP_KEY).unwrap_or_default(); return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
} }
Self::default() Self::default()
} }
} }
impl epi::App for WrapApp { impl eframe::App for WrapApp {
#[cfg(feature = "persistence")] #[cfg(feature = "persistence")]
fn save(&mut self, storage: &mut dyn epi::Storage) { fn save(&mut self, storage: &mut dyn eframe::Storage) {
epi::set_value(storage, epi::APP_KEY, self); eframe::set_value(storage, eframe::APP_KEY, self);
} }
fn clear_color(&self) -> egui::Rgba { fn clear_color(&self) -> egui::Rgba {
egui::Rgba::TRANSPARENT // we set a [`CentralPanel`] fill color in `demo_windows.rs` egui::Rgba::TRANSPARENT // we set a [`CentralPanel`] fill color in `demo_windows.rs`
} }
fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
if let Some(web_info) = frame.info().web_info.as_ref() { if let Some(web_info) = frame.info().web_info.as_ref() {
if let Some(anchor) = web_info.location.hash.strip_prefix('#') { if let Some(anchor) = web_info.location.hash.strip_prefix('#') {
self.selected_anchor = anchor.to_owned(); self.selected_anchor = anchor.to_owned();
@ -130,7 +199,7 @@ impl epi::App for WrapApp {
} }
impl WrapApp { impl WrapApp {
fn bar_contents(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame) { fn bar_contents(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
// A menu-bar is a horizontal layout with some special styles applied. // A menu-bar is a horizontal layout with some special styles applied.
// egui::menu::bar(ui, |ui| { // egui::menu::bar(ui, |ui| {
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {

View file

@ -20,57 +20,30 @@ all-features = true
[features] [features]
default = ["datetime"] default = []
# Enable additional checks if debug assertions are enabled (debug builds). chrono = ["egui_extras/datepicker", "dep:chrono"]
extra_debug_asserts = ["egui/extra_debug_asserts"]
# Always enable additional checks.
extra_asserts = ["egui/extra_asserts"]
datetime = ["egui_extras/chrono", "chrono"]
http = ["ehttp", "image", "poll-promise"]
persistence = [
"egui/persistence",
"epi/persistence",
"egui_extras/persistence",
"serde",
]
serde = ["egui/serde", "dep:serde"] serde = ["egui/serde", "dep:serde"]
syntax_highlighting = ["syntect"] syntax_highlighting = ["syntect"]
[dependencies] [dependencies]
egui = { version = "0.17.0", path = "../egui", default-features = false } egui = { version = "0.17.0", path = "../egui", default-features = false }
epi = { version = "0.17.0", path = "../epi" } egui_extras = { version = "0.17.0", path = "../egui_extras" }
egui_extras = { version = "0.17.0", path = "../egui_extras", features = [
"image",
"datepicker",
] }
chrono = { version = "0.4", optional = true, features = ["js-sys", "wasmbind"] }
enum-map = { version = "2", features = ["serde"] } enum-map = { version = "2", features = ["serde"] }
tracing = "0.1" tracing = "0.1"
unicode_names2 = { version = "0.5.0", default-features = false } unicode_names2 = { version = "0.5.0", default-features = false }
# feature "http": # Optional:
ehttp = { version = "0.2.0", optional = true } chrono = { version = "0.4", optional = true, features = ["js-sys", "wasmbind"] }
image = { version = "0.24", optional = true, default-features = false, features = [
"jpeg",
"png",
] }
poll-promise = { version = "0.1", optional = true, default-features = false }
# feature "syntax_highlighting":
syntect = { version = "4", optional = true, default-features = false, features = [
"default-fancy",
] }
# feature "persistence":
serde = { version = "1", optional = true, features = ["derive"] } serde = { version = "1", optional = true, features = ["derive"] }
syntect = { version = "4", optional = true, default-features = false, features = ["default-fancy"] }
[dev-dependencies] [dev-dependencies]
criterion = { version = "0.3", default-features = false } criterion = { version = "0.3", default-features = false }
[[bench]] [[bench]]
name = "benchmark" name = "benchmark"
harness = false harness = false

View file

@ -12,4 +12,5 @@ The demo library is a separate crate for three reasons:
* To ensure it only uses the public `egui` api. * To ensure it only uses the public `egui` api.
* To remove the amount of code in `egui` proper. * To remove the amount of code in `egui` proper.
* To make it easy for other integrations to use the egui demos a test. * To make it easy for 3rd party egui integrations to use it for tests.
- See for instance https://github.com/not-fl3/egui-miniquad/blob/master/examples/demo.rs

View file

@ -1,12 +0,0 @@
#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct DemoApp {
demo_windows: super::DemoWindows,
}
impl epi::App for DemoApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut epi::Frame) {
self.demo_windows.ui(ctx);
}
}

View file

@ -9,6 +9,7 @@ const RED: Color32 = Color32::RED;
const TRANSPARENT: Color32 = Color32::TRANSPARENT; const TRANSPARENT: Color32 = Color32::TRANSPARENT;
const WHITE: Color32 = Color32::WHITE; const WHITE: Color32 = Color32::WHITE;
/// A test for sanity-checking and diagnosing egui rendering backends.
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct ColorTest { pub struct ColorTest {
#[cfg_attr(feature = "serde", serde(skip))] #[cfg_attr(feature = "serde", serde(skip))]
@ -29,22 +30,6 @@ impl Default for ColorTest {
} }
} }
impl epi::App for ColorTest {
fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
if frame.is_web() {
ui.label(
"NOTE: Some old browsers stuck on WebGL1 without sRGB support will not pass the color test.",
);
ui.separator();
}
ScrollArea::both().auto_shrink([false; 2]).show(ui, |ui| {
self.ui(ui);
});
});
}
}
impl ColorTest { impl ColorTest {
pub fn ui(&mut self, ui: &mut Ui) { pub fn ui(&mut self, ui: &mut Ui) {
ui.set_max_width(680.0); ui.set_max_width(680.0);

View file

@ -1,5 +1,5 @@
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
enum Plot { enum Plot {
Sin, Sin,
Bell, Bell,
@ -15,7 +15,7 @@ fn sigmoid(x: f64) -> f64 {
} }
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct ContextMenus { pub struct ContextMenus {
plot: Plot, plot: Plot,
show_axes: [bool; 2], show_axes: [bool; 2],

View file

@ -76,7 +76,7 @@ pub fn drop_target<R>(
InnerResponse::new(ret, response) InnerResponse::new(ret, response)
} }
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct DragAndDropDemo { pub struct DragAndDropDemo {
/// columns with items /// columns with items
columns: Vec<Vec<String>>, columns: Vec<Vec<String>>,

View file

@ -4,7 +4,6 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
mod app;
pub mod code_editor; pub mod code_editor;
pub mod code_example; pub mod code_example;
pub mod context_menu; pub mod context_menu;
@ -31,8 +30,7 @@ pub mod window_options;
pub mod window_with_panels; pub mod window_with_panels;
pub use { pub use {
app::DemoApp, demo_app_windows::DemoWindows, misc_demo_window::MiscDemoWindow, demo_app_windows::DemoWindows, misc_demo_window::MiscDemoWindow, widget_gallery::WidgetGallery,
widget_gallery::WidgetGallery,
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View file

@ -18,7 +18,7 @@ pub struct WidgetGallery {
color: egui::Color32, color: egui::Color32,
animate_progress_bar: bool, animate_progress_bar: bool,
#[cfg(feature = "datetime")] #[cfg(feature = "chrono")]
#[cfg_attr(feature = "serde", serde(skip))] #[cfg_attr(feature = "serde", serde(skip))]
date: Option<chrono::Date<chrono::Utc>>, date: Option<chrono::Date<chrono::Utc>>,
@ -37,7 +37,7 @@ impl Default for WidgetGallery {
string: Default::default(), string: Default::default(),
color: egui::Color32::LIGHT_BLUE.linear_multiply(0.5), color: egui::Color32::LIGHT_BLUE.linear_multiply(0.5),
animate_progress_bar: false, animate_progress_bar: false,
#[cfg(feature = "datetime")] #[cfg(feature = "chrono")]
date: None, date: None,
texture: None, texture: None,
} }
@ -109,7 +109,7 @@ impl WidgetGallery {
string, string,
color, color,
animate_progress_bar, animate_progress_bar,
#[cfg(feature = "datetime")] #[cfg(feature = "chrono")]
date, date,
texture, texture,
} = self; } = self;
@ -216,7 +216,7 @@ impl WidgetGallery {
} }
ui.end_row(); ui.end_row();
#[cfg(feature = "datetime")] #[cfg(feature = "chrono")]
{ {
let date = date.get_or_insert_with(|| chrono::offset::Utc::now().date()); let date = date.get_or_insert_with(|| chrono::offset::Utc::now().date());
ui.add(doc_link_label("DatePickerButton", "DatePickerButton")); ui.add(doc_link_label("DatePickerButton", "DatePickerButton"));

View file

@ -29,8 +29,8 @@ impl Default for EasyMarkEditor {
} }
} }
impl epi::App for EasyMarkEditor { impl EasyMarkEditor {
fn update(&mut self, ctx: &egui::Context, _frame: &mut epi::Frame) { pub fn panels(&mut self, ctx: &egui::Context) {
egui::TopBottomPanel::bottom("easy_mark_bottom").show(ctx, |ui| { egui::TopBottomPanel::bottom("easy_mark_bottom").show(ctx, |ui| {
let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true); let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true);
ui.allocate_ui_with_layout(ui.available_size(), layout, |ui| { ui.allocate_ui_with_layout(ui.available_size(), layout, |ui| {
@ -42,10 +42,8 @@ impl epi::App for EasyMarkEditor {
self.ui(ui); self.ui(ui);
}); });
} }
}
impl EasyMarkEditor { pub fn ui(&mut self, ui: &mut egui::Ui) {
fn ui(&mut self, ui: &mut egui::Ui) {
egui::Grid::new("controls").show(ui, |ui| { egui::Grid::new("controls").show(ui, |ui| {
ui.checkbox(&mut self.highlight_editor, "Highlight editor"); ui.checkbox(&mut self.highlight_editor, "Highlight editor");
egui::reset_button(ui, self); egui::reset_button(ui, self);

View file

@ -1,27 +1,27 @@
//! Demo-code for showing how egui is used. //! Demo-code for showing how egui is used.
//! //!
//! The demo-code is also used in benchmarks and tests. //! This library can be used to test 3rd party egui integrations (see for instance <https://github.com/not-fl3/egui-miniquad/blob/master/examples/demo.rs>).
//!
//! The demo is also used in benchmarks and tests.
#![allow(clippy::float_cmp)] #![allow(clippy::float_cmp)]
#![allow(clippy::manual_range_contains)] #![allow(clippy::manual_range_contains)]
mod apps; mod color_test;
mod backend_panel; mod demo;
pub mod easy_mark; pub mod easy_mark;
pub(crate) mod frame_history;
pub mod syntax_highlighting; pub mod syntax_highlighting;
mod wrap_app;
pub use apps::ColorTest; // used for tests pub use color_test::ColorTest;
pub use apps::DemoWindows; // used for tests pub use demo::DemoWindows;
pub use wrap_app::WrapApp;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// Create a [`Hyperlink`](crate::Hyperlink) to this egui source code file on github. /// Create a [`Hyperlink`](egui::Hyperlink) to this egui source code file on github.
#[macro_export]
macro_rules! egui_github_link_file { macro_rules! egui_github_link_file {
() => { () => {
crate::egui_github_link_file!("(source code)") $crate::egui_github_link_file!("(source code)")
}; };
($label: expr) => { ($label: expr) => {
egui::github_link_file!( egui::github_link_file!(
@ -30,12 +30,12 @@ macro_rules! egui_github_link_file {
) )
}; };
} }
pub(crate) use egui_github_link_file;
/// Create a [`Hyperlink`](crate::Hyperlink) to this egui source code file and line on github. /// Create a [`Hyperlink`](egui::Hyperlink) to this egui source code file and line on github.
#[macro_export]
macro_rules! egui_github_link_file_line { macro_rules! egui_github_link_file_line {
() => { () => {
crate::egui_github_link_file_line!("(source code)") $crate::egui_github_link_file_line!("(source code)")
}; };
($label: expr) => { ($label: expr) => {
egui::github_link_file_line!( egui::github_link_file_line!(
@ -44,7 +44,6 @@ macro_rules! egui_github_link_file_line {
) )
}; };
} }
pub(crate) use egui_github_link_file_line;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -93,19 +92,3 @@ fn test_egui_zero_window_size() {
); );
} }
} }
// ----------------------------------------------------------------------------
/// Time of day as seconds since midnight. Used for clock in demo app.
pub(crate) fn seconds_since_midnight() -> Option<f64> {
#[cfg(feature = "datetime")]
{
use chrono::Timelike;
let time = chrono::Local::now().time();
let seconds_since_midnight =
time.num_seconds_from_midnight() as f64 + 1e-9 * (time.nanosecond() as f64);
Some(seconds_since_midnight)
}
#[cfg(not(feature = "datetime"))]
None
}

View file

@ -5,6 +5,7 @@ All notable changes to the `egui_extras` integration will be noted in this file.
## Unreleased ## Unreleased
* Added `Strip`, `Table` and `DatePicker` ([#963](https://github.com/emilk/egui/pull/963)). * Added `Strip`, `Table` and `DatePicker` ([#963](https://github.com/emilk/egui/pull/963)).
* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)). * MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)).
* Renamed feature "persistence" to "serde" ([#1540](https://github.com/emilk/egui/pull/1540)).
## 0.17.0 - 2022-02-22 ## 0.17.0 - 2022-02-22

View file

@ -26,14 +26,13 @@ all-features = true
[features] [features]
default = [] default = []
# Support loading svg images
svg = ["resvg", "tiny-skia", "usvg"]
# Datepicker widget # Datepicker widget
datepicker = ["chrono"] datepicker = ["chrono"]
# Persistence serde = ["dep:serde"]
persistence = ["serde"]
# Support loading svg images
svg = ["resvg", "tiny-skia", "usvg"]
# Log warnings using `tracing` crate # Log warnings using `tracing` crate
tracing = ["dep:tracing", "egui/tracing"] tracing = ["dep:tracing", "egui/tracing"]
@ -57,7 +56,7 @@ resvg = { version = "0.22", optional = true }
tiny-skia = { version = "0.6", optional = true } tiny-skia = { version = "0.6", optional = true }
usvg = { version = "0.22", optional = true } usvg = { version = "0.22", optional = true }
# feature "persistence": # feature "serde":
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
# feature "tracing" # feature "tracing"

View file

@ -3,7 +3,7 @@ use chrono::{Date, Utc};
use egui::{Area, Button, Frame, Key, Order, RichText, Ui, Widget}; use egui::{Area, Button, Frame, Key, Order, RichText, Ui, Widget};
#[derive(Default, Clone)] #[derive(Default, Clone)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub(crate) struct DatePickerButtonState { pub(crate) struct DatePickerButtonState {
pub picker_visible: bool, pub picker_visible: bool,
} }

View file

@ -4,7 +4,7 @@ use chrono::{Date, Datelike, NaiveDate, Utc, Weekday};
use egui::{Align, Button, Color32, ComboBox, Direction, Id, Layout, RichText, Ui, Vec2}; use egui::{Align, Button, Color32, ComboBox, Direction, Id, Layout, RichText, Ui, Vec2};
#[derive(Default, Clone)] #[derive(Default, Clone)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
struct DatePickerPopupState { struct DatePickerPopupState {
year: i32, year: i32,
month: u32, month: u32,