Browse Source

Split out the Egui demo code to new crate `egui_demo_lib`

pull/92/head
Emil Ernerfeldt 4 years ago
parent
commit
6953dc7d5d
  1. 2
      .github/workflows/rust.yml
  2. 10
      Cargo.lock
  3. 1
      Cargo.toml
  4. 1
      check.sh
  5. 7
      egui/Cargo.toml
  6. 6
      egui/src/context.rs
  7. 18
      egui/src/layout.rs
  8. 54
      egui/src/lib.rs
  9. 1
      egui_demo/Cargo.toml
  10. 2
      egui_demo/src/lib.rs
  11. 2
      egui_demo/src/main.rs
  12. 25
      egui_demo_lib/Cargo.toml
  13. 8
      egui_demo_lib/README.md
  14. 8
      egui_demo_lib/benches/benchmark.rs
  15. 28
      egui_demo_lib/src/app.rs
  16. 10
      egui_demo_lib/src/color_test.rs
  17. 9
      egui_demo_lib/src/dancing_strings.rs
  18. 5
      egui_demo_lib/src/demo_window.rs
  19. 44
      egui_demo_lib/src/demo_windows.rs
  20. 16
      egui_demo_lib/src/drag_and_drop.rs
  21. 35
      egui_demo_lib/src/font_book.rs
  22. 0
      egui_demo_lib/src/font_contents_emoji.rs
  23. 0
      egui_demo_lib/src/font_contents_ubuntu.rs
  24. 2
      egui_demo_lib/src/fractal_clock.rs
  25. 111
      egui_demo_lib/src/lib.rs
  26. 9
      egui_demo_lib/src/painting.rs
  27. 3
      egui_demo_lib/src/scrolls.rs
  28. 2
      egui_demo_lib/src/sliders.rs
  29. 16
      egui_demo_lib/src/tests.rs
  30. 35
      egui_demo_lib/src/toggle_switch.rs
  31. 16
      egui_demo_lib/src/widgets.rs

2
.github/workflows/rust.yml

@ -52,7 +52,7 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: test
args: -p egui # Only test egui due to weird build issues with the others
args: -p egui -p egui_demo_lib # TODO: fix weird build issues with the others
fmt:
name: Rustfmt

10
Cargo.lock

@ -626,7 +626,6 @@ version = "0.6.0"
dependencies = [
"ahash",
"atomic_refcell",
"criterion",
"parking_lot",
"rusttype",
"serde",
@ -638,6 +637,7 @@ name = "egui_demo"
version = "0.1.0"
dependencies = [
"egui",
"egui_demo_lib",
"egui_glium",
"egui_web",
"js-sys",
@ -645,6 +645,14 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "egui_demo_lib"
version = "0.6.0"
dependencies = [
"criterion",
"egui",
]
[[package]]
name = "egui_glium"
version = "0.6.0"

1
Cargo.toml

@ -1,5 +1,6 @@
[workspace]
members = [
"egui_demo_lib",
"egui_demo",
"egui_glium",
"egui_web",

1
check.sh

@ -7,7 +7,6 @@ CARGO_INCREMENTAL=0 cargo clippy --workspace --all-targets --all-features -- -D
cargo test --workspace --all-targets --all-features
cargo test --workspace --doc
cargo check -p egui --lib --target wasm32-unknown-unknown
cargo check -p egui_web --lib --target wasm32-unknown-unknown
cargo check -p egui_demo --lib --target wasm32-unknown-unknown
cargo check -p example_web --lib --target wasm32-unknown-unknown

7
egui/Cargo.toml

@ -26,9 +26,6 @@ rusttype = "0.9"
serde = { version = "1", features = ["derive"], optional = true }
serde_json = { version = "1", optional = true }
[dev-dependencies]
criterion = { version = "0.3", default-features = false }
[features]
default = ["atomic_refcell", "default_fonts"]
@ -38,7 +35,3 @@ default_fonts = []
# Only needed if you plan to use the same egui::Context from multiple threads.
multi_threaded = ["parking_lot"]
[[bench]]
name = "benchmark"
harness = false

6
egui/src/context.rs

@ -676,6 +676,12 @@ impl Context {
// ---------------------------------------------------------------------
/// Move all the graphics at the given layer.
/// Can be used to implement drag-and-drop (see relevant demo).
pub fn translate_layer(&self, layer_id: LayerId, delta: Vec2) {
self.graphics().list(layer_id).translate(delta);
}
pub fn layer_id_at(&self, pos: Pos2) -> Option<LayerId> {
let resize_grab_radius_side = self.style().interaction.resize_grab_radius_side;
self.memory().layer_id_at(pos, resize_grab_radius_side)

18
egui/src/layout.rs

@ -130,15 +130,6 @@ impl Default for Layout {
}
impl Layout {
pub(crate) fn from_main_dir_and_cross_align(main_dir: Direction, cross_align: Align) -> Self {
Self {
main_dir,
main_wrap: false,
cross_align,
cross_justify: false,
}
}
pub fn left_to_right() -> Self {
Self {
main_dir: Direction::LeftToRight,
@ -180,6 +171,15 @@ impl Layout {
}
}
pub fn from_main_dir_and_cross_align(main_dir: Direction, cross_align: Align) -> Self {
Self {
main_dir,
main_wrap: false,
cross_align,
cross_justify: false,
}
}
#[deprecated = "Use `top_down`"]
pub fn vertical(cross_align: Align) -> Self {
Self::top_down(cross_align)

54
egui/src/lib.rs

@ -82,7 +82,6 @@ mod animation_manager;
pub mod app;
pub mod containers;
mod context;
pub mod demos;
mod id;
mod input;
mod introspection;
@ -103,7 +102,6 @@ pub use {
align::Align,
containers::*,
context::{Context, CtxRef},
demos::DemoApp,
id::Id,
input::*,
layers::*,
@ -122,28 +120,50 @@ pub use {
widgets::*,
};
// ----------------------------------------------------------------------------
#[cfg(debug_assertions)]
pub(crate) fn has_debug_assertions() -> bool {
pub(crate) const fn has_debug_assertions() -> bool {
true
}
#[cfg(not(debug_assertions))]
pub(crate) fn has_debug_assertions() -> bool {
pub(crate) const fn has_debug_assertions() -> bool {
false
}
#[test]
fn test_egui_e2e() {
let mut demo_windows = crate::demos::DemoWindows::default();
let mut ctx = crate::CtxRef::default();
let raw_input = crate::RawInput::default();
const NUM_FRAMES: usize = 5;
for _ in 0..NUM_FRAMES {
ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_output, paint_commands) = ctx.end_frame();
let paint_jobs = ctx.tessellate(paint_commands);
assert!(!paint_jobs.is_empty());
/// Helper function that adds a label when compiling with debug assertions enabled.
pub fn warn_if_debug_build(ui: &mut crate::Ui) {
if crate::has_debug_assertions() {
ui.label(
crate::Label::new("‼ Debug build ‼")
.small()
.text_color(crate::color::RED),
)
.on_hover_text("Egui was compiled with debug assertions enabled.");
}
}
// ----------------------------------------------------------------------------
/// Create a [`Hyperlink`](crate::Hyperlink) to this file (and line) on Github
///
/// Example: `ui.add(github_link_file_line!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export]
macro_rules! github_link_file_line {
($github_url:expr, $label:expr) => {{
let url = format!("{}{}#L{}", $github_url, file!(), line!());
$crate::Hyperlink::new(url).text($label)
}};
}
/// Create a [`Hyperlink`](crate::Hyperlink) to this file on github.
///
/// Example: `ui.add(github_link_file!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export]
macro_rules! github_link_file {
($github_url:expr, $label:expr) => {{
let url = format!("{}{}", $github_url, file!());
$crate::Hyperlink::new(url).text($label)
}};
}

1
egui_demo/Cargo.toml

@ -10,6 +10,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
egui = { path = "../egui", features = ["serde", "serde_json"] }
egui_demo_lib = { path = "../egui_demo_lib" }
serde = { version = "1", features = ["derive"] }
# For compiling natively:

2
egui_demo/src/lib.rs

@ -12,7 +12,7 @@ use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn start(canvas_id: &str) -> Result<(), wasm_bindgen::JsValue> {
let app = egui::DemoApp::default();
let app = egui_demo_lib::DemoApp::default();
egui_web::start(canvas_id, Box::new(app))?;
Ok(())
}

2
egui_demo/src/main.rs

@ -4,6 +4,6 @@
// When compiling natively:
fn main() {
let app = egui::DemoApp::default();
let app = egui_demo_lib::DemoApp::default();
egui_glium::run(Box::new(app));
}

25
egui_demo_lib/Cargo.toml

@ -0,0 +1,25 @@
[package]
name = "egui_demo_lib"
version = "0.6.0"
authors = ["Emil Ernerfeldt <emil.ernerfeldt@gmail.com>"]
description = "Example library for Egui"
edition = "2018"
homepage = "https://github.com/emilk/egui"
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/emilk/egui"
categories = ["gui", "graphics"]
keywords = ["glium", "egui", "gui", "gamedev"]
include = [ "**/*.rs", "Cargo.toml"]
[lib]
[dependencies]
egui = { version = "0.6.0", path = "../egui" }
[dev-dependencies]
criterion = { version = "0.3", default-features = false }
[[bench]]
name = "benchmark"
harness = false

8
egui_demo_lib/README.md

@ -0,0 +1,8 @@
# Egui Demo Library
This crate contains example code for Egui.
It is in a separate crate for two reasons:
* To ensure it only uses the public `egui` API.
* To remove the amount of code in `egui` proper.

8
egui/benches/benchmark.rs → egui_demo_lib/benches/benchmark.rs

@ -5,7 +5,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
{
let mut ctx = egui::CtxRef::default();
let mut demo_windows = egui::demos::DemoWindows::default();
let mut demo_windows = egui_demo_lib::DemoWindows::default();
c.bench_function("demo_windows_minimal", |b| {
b.iter(|| {
@ -19,7 +19,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
{
let mut ctx = egui::CtxRef::default();
ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything
let mut demo_windows = egui::demos::DemoWindows::default();
let mut demo_windows = egui_demo_lib::DemoWindows::default();
c.bench_function("demo_windows_full", |b| {
b.iter(|| {
@ -33,7 +33,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
{
let mut ctx = egui::CtxRef::default();
ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything
let mut demo_windows = egui::demos::DemoWindows::default();
let mut demo_windows = egui_demo_lib::DemoWindows::default();
ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_, paint_commands) = ctx.end_frame();
@ -49,7 +49,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
egui::CentralPanel::default().show(&ctx, |ui| {
c.bench_function("label", |b| {
b.iter(|| {
ui.label(egui::demos::LOREM_IPSUM_LONG);
ui.label(egui_demo_lib::LOREM_IPSUM_LONG);
})
});
});

28
egui/src/demos/app.rs → egui_demo_lib/src/app.rs

@ -1,4 +1,4 @@
use crate::{app, demos, util::History, CtxRef, Response, Ui};
use egui::{util::History, *};
// ----------------------------------------------------------------------------
@ -90,9 +90,9 @@ impl FrameHistory {
"Includes Egui layout and tessellation time.\n\
Does not include GPU usage, nor overhead for sending data to GPU.",
);
crate::demos::warn_if_debug_build(ui);
egui::warn_if_debug_build(ui);
crate::CollapsingHeader::new("📊 CPU usage history")
egui::CollapsingHeader::new("📊 CPU usage history")
.default_open(false)
.show(ui, |ui| {
self.graph(ui);
@ -100,8 +100,6 @@ impl FrameHistory {
}
fn graph(&mut self, ui: &mut Ui) -> Response {
use crate::*;
let graph_top_cpu_usage = 0.010;
ui.label("Egui CPU usage history");
@ -179,7 +177,7 @@ impl FrameHistory {
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct DemoApp {
demo_windows: demos::DemoWindows,
demo_windows: crate::DemoWindows,
backend_window_open: bool,
@ -236,7 +234,7 @@ impl DemoApp {
.or_else(|| Some(ui.ctx().pixels_per_point()));
if let Some(pixels_per_point) = &mut self.pixels_per_point {
ui.add(
crate::Slider::f32(pixels_per_point, 0.5..=5.0)
egui::Slider::f32(pixels_per_point, 0.5..=5.0)
.logarithmic(true)
.text("Scale (physical pixels per point)"),
);
@ -286,16 +284,16 @@ impl app::App for DemoApp {
}
#[cfg(feature = "serde_json")]
fn load(&mut self, storage: &dyn crate::app::Storage) {
*self = crate::app::get_value(storage, crate::app::APP_KEY).unwrap_or_default()
fn load(&mut self, storage: &dyn egui::app::Storage) {
*self = egui::app::get_value(storage, egui::app::APP_KEY).unwrap_or_default()
}
#[cfg(feature = "serde_json")]
fn save(&mut self, storage: &mut dyn crate::app::Storage) {
crate::app::set_value(storage, crate::app::APP_KEY, self);
fn save(&mut self, storage: &mut dyn egui::app::Storage) {
egui::app::set_value(storage, egui::app::APP_KEY, self);
}
fn ui(&mut self, ctx: &CtxRef, integration_context: &mut crate::app::IntegrationContext<'_>) {
fn ui(&mut self, ctx: &CtxRef, integration_context: &mut egui::app::IntegrationContext<'_>) {
self.frame_history
.on_new_frame(ctx.input().time, integration_context.info.cpu_usage);
@ -307,12 +305,12 @@ impl app::App for DemoApp {
.unwrap_or_default();
let link = if web_location_hash == "clock" {
Some(demos::DemoLink::Clock)
Some(crate::DemoLink::Clock)
} else {
None
};
let demo_environment = demos::DemoEnvironment {
let demo_environment = crate::DemoEnvironment {
seconds_since_midnight: integration_context.info.seconds_since_midnight,
link,
};
@ -339,7 +337,7 @@ impl app::App for DemoApp {
);
let mut backend_window_open = self.backend_window_open;
crate::Window::new("💻 Backend")
egui::Window::new("💻 Backend")
.min_width(360.0)
.scroll(false)
.open(&mut backend_window_open)

10
egui/src/demos/color_test.rs → egui_demo_lib/src/color_test.rs

@ -1,6 +1,4 @@
use crate::widgets::color_picker::show_color;
use crate::*;
use color::*;
use egui::{color::*, widgets::color_picker::show_color, *};
use std::collections::HashMap;
const GRADIENT_SIZE: Vec2 = vec2(256.0, 24.0);
@ -266,7 +264,7 @@ impl ColorTest {
}
fn vertex_gradient(ui: &mut Ui, bg_fill: Srgba, gradient: &Gradient) -> Response {
use crate::paint::*;
use egui::paint::*;
let response = ui.allocate_response(GRADIENT_SIZE, Sense::hover());
if bg_fill != Default::default() {
let mut triangles = Triangles::default();
@ -324,12 +322,12 @@ impl Gradient {
(0..=n)
.map(|i| {
let t = i as f32 / n as f32;
Srgba([
Srgba::from_rgba_premultiplied(
lerp((left[0] as f32)..=(right[0] as f32), t).round() as u8, // Don't ever do this please!
lerp((left[1] as f32)..=(right[1] as f32), t).round() as u8, // Don't ever do this please!
lerp((left[2] as f32)..=(right[2] as f32), t).round() as u8, // Don't ever do this please!
lerp((left[3] as f32)..=(right[3] as f32), t).round() as u8, // Don't ever do this please!
])
)
})
.collect(),
)

9
egui/src/demos/dancing_strings.rs → egui_demo_lib/src/dancing_strings.rs

@ -1,4 +1,4 @@
use crate::{containers::*, demos::*, *};
use egui::{containers::*, *};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
@ -10,12 +10,13 @@ impl Default for DancingStrings {
}
}
impl Demo for DancingStrings {
impl crate::Demo for DancingStrings {
fn name(&self) -> &str {
"♫ Dancing Strings"
}
fn show(&mut self, ctx: &CtxRef, open: &mut bool) {
use crate::View;
Window::new(self.name())
.open(open)
.default_size(vec2(512.0, 256.0))
@ -24,7 +25,7 @@ impl Demo for DancingStrings {
}
}
impl View for DancingStrings {
impl crate::View for DancingStrings {
fn ui(&mut self, ui: &mut Ui) {
Frame::dark_canvas(ui.style()).show(ui, |ui| {
ui.ctx().request_repaint();
@ -62,6 +63,6 @@ impl View for DancingStrings {
ui.painter().extend(cmds);
});
ui.add(__egui_github_link_file!());
ui.add(crate::__egui_github_link_file!());
}
}

5
egui/src/demos/demo_window.rs → egui_demo_lib/src/demo_window.rs

@ -1,4 +1,5 @@
use crate::{color::*, demos::*, *};
use crate::*;
use egui::{color::*, *};
/// Showcase some ui code
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
@ -221,8 +222,6 @@ impl BoxPainting {
// ----------------------------------------------------------------------------
use crate::layout::*;
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
struct LayoutDemo {

44
egui/src/demos/demo_windows.rs → egui_demo_lib/src/demo_windows.rs

@ -1,8 +1,4 @@
use crate::{
app,
demos::{self, Demo},
CtxRef, Resize, ScrollArea, Ui, Window,
};
use egui::{app, CtxRef, Resize, ScrollArea, Ui, Window};
// ----------------------------------------------------------------------------
@ -29,17 +25,17 @@ pub struct DemoEnvironment {
struct Demos {
/// open, view
#[cfg_attr(feature = "serde", serde(skip))] // TODO: serialize the `open` state.
demos: Vec<(bool, Box<dyn Demo>)>,
demos: Vec<(bool, Box<dyn crate::Demo>)>,
}
impl Default for Demos {
fn default() -> Self {
Self {
demos: vec![
(false, Box::new(crate::demos::FontBook::default())),
(false, Box::new(crate::demos::Painting::default())),
(false, Box::new(crate::demos::DancingStrings::default())),
(false, Box::new(crate::demos::DragAndDropDemo::default())),
(false, Box::new(crate::demos::Tests::default())),
(false, Box::new(crate::FontBook::default())),
(false, Box::new(crate::Painting::default())),
(false, Box::new(crate::DancingStrings::default())),
(false, Box::new(crate::DragAndDropDemo::default())),
(false, Box::new(crate::Tests::default())),
],
}
}
@ -67,12 +63,12 @@ impl Demos {
pub struct DemoWindows {
open_windows: OpenWindows,
demo_window: demos::DemoWindow,
demo_window: crate::DemoWindow,
#[cfg_attr(feature = "serde", serde(skip))]
color_test: demos::ColorTest,
color_test: crate::ColorTest,
fractal_clock: demos::FractalClock,
fractal_clock: crate::FractalClock,
/// open, title, view
demos: Demos,
@ -104,16 +100,16 @@ impl DemoWindows {
self.previous_link = env.link;
}
crate::SidePanel::left("side_panel", 190.0).show(ctx, |ui| {
egui::SidePanel::left("side_panel", 190.0).show(ctx, |ui| {
ui.heading("✒ Egui Demo");
crate::demos::warn_if_debug_build(ui);
egui::warn_if_debug_build(ui);
ui.separator();
ScrollArea::auto_sized().show(ui, |ui| {
ui.label("Egui is an immediate mode GUI library written in Rust.");
ui.add(
crate::Hyperlink::new("https://github.com/emilk/egui").text(" Egui home page"),
egui::Hyperlink::new("https://github.com/emilk/egui").text(" Egui home page"),
);
ui.label("Egui can be run on the web, or natively on 🐧");
@ -136,7 +132,7 @@ impl DemoWindows {
});
});
crate::TopPanel::top("menu_bar").show(ctx, |ui| {
egui::TopPanel::top("menu_bar").show(ctx, |ui| {
show_menu_bar(ui, &mut self.open_windows, env.seconds_since_midnight);
});
@ -215,7 +211,7 @@ impl DemoWindows {
.show(ctx, |ui| {
ui.label("scroll: NO");
ui.label("resizable: YES");
ui.label(demos::LOREM_IPSUM);
ui.label(crate::LOREM_IPSUM);
});
Window::new("resizable + embedded scroll")
@ -228,8 +224,8 @@ impl DemoWindows {
ui.label("resizable: YES");
ui.heading("We have a sub-region with scroll bar:");
ScrollArea::auto_sized().show(ui, |ui| {
ui.label(demos::LOREM_IPSUM_LONG);
ui.label(demos::LOREM_IPSUM_LONG);
ui.label(crate::LOREM_IPSUM_LONG);
ui.label(crate::LOREM_IPSUM_LONG);
});
// ui.heading("Some additional text here, that should also be visible"); // this works, but messes with the resizing a bit
});
@ -242,7 +238,7 @@ impl DemoWindows {
.show(ctx, |ui| {
ui.label("scroll: YES");
ui.label("resizable: YES");
ui.label(demos::LOREM_IPSUM_LONG);
ui.label(crate::LOREM_IPSUM_LONG);
});
Window::new("auto_sized")
@ -252,7 +248,7 @@ impl DemoWindows {
ui.label("This window will auto-size based on its contents.");
ui.heading("Resize this area:");
Resize::default().show(ui, |ui| {
ui.label(demos::LOREM_IPSUM);
ui.label(crate::LOREM_IPSUM);
});
ui.heading("Resize the above area!");
});
@ -327,7 +323,7 @@ impl OpenWindows {
}
fn show_menu_bar(ui: &mut Ui, windows: &mut OpenWindows, seconds_since_midnight: Option<f64>) {
use crate::*;
use egui::*;
menu::bar(ui, |ui| {
menu::menu(ui, "File", |ui| {

16
egui/src/demos/drag_and_drop.rs → egui_demo_lib/src/drag_and_drop.rs

@ -1,7 +1,4 @@
use crate::{
demos::{Demo, View},
*,
};
use egui::*;
pub fn drag_source(ui: &mut Ui, id: Id, body: impl FnOnce(&mut Ui)) {
let is_being_dragged = ui.memory().is_being_dragged(id);
@ -18,7 +15,7 @@ pub fn drag_source(ui: &mut Ui, id: Id, body: impl FnOnce(&mut Ui)) {
ui.output().cursor_icon = CursorIcon::Grabbing;
// Paint the body to a new layer:
let layer_id = LayerId::new(layers::Order::Tooltip, id);
let layer_id = LayerId::new(Order::Tooltip, id);
let response = ui.with_layer_id(layer_id, body).1;
// Now we move the visuals of the body to where the mouse is.
@ -30,7 +27,7 @@ pub fn drag_source(ui: &mut Ui, id: Id, body: impl FnOnce(&mut Ui)) {
if let Some(mouse_pos) = ui.input().mouse.pos {
let delta = mouse_pos - response.rect.center();
ui.ctx().graphics().list(layer_id).translate(delta);
ui.ctx().translate_layer(layer_id, delta);
}
}
}
@ -92,12 +89,13 @@ impl Default for DragAndDropDemo {
}
}
impl Demo for DragAndDropDemo {
impl crate::Demo for DragAndDropDemo {
fn name(&self) -> &str {
"✋ Drag and Drop"
}
fn show(&mut self, ctx: &CtxRef, open: &mut bool) {
use crate::View;
Window::new(self.name())
.open(open)
.default_size(vec2(256.0, 256.0))
@ -107,7 +105,7 @@ impl Demo for DragAndDropDemo {
}
}
impl View for DragAndDropDemo {
impl crate::View for DragAndDropDemo {
fn ui(&mut self, ui: &mut Ui) {
ui.label("This is a proof-of-concept of drag-and-drop in Egui");
ui.label("Drag items between columns.");
@ -153,6 +151,6 @@ impl View for DragAndDropDemo {
}
}
ui.add(__egui_github_link_file!());
ui.add(crate::__egui_github_link_file!());
}
}

35
egui/src/demos/font_book.rs → egui_demo_lib/src/font_book.rs

@ -1,10 +1,8 @@
use crate::*;
pub struct FontBook {
standard: bool,
emojis: bool,
filter: String,
text_style: TextStyle,
text_style: egui::TextStyle,
}
impl Default for FontBook {
@ -13,13 +11,14 @@ impl Default for FontBook {
standard: false,
emojis: true,
filter: Default::default(),
text_style: TextStyle::Button,
text_style: egui::TextStyle::Button,
}
}
}
impl FontBook {
fn characters_ui(&self, ui: &mut Ui, characters: &[(u32, char, &str)]) {
fn characters_ui(&self, ui: &mut egui::Ui, characters: &[(u32, char, &str)]) {
use egui::{Button, Label};
for &(_, chr, name) in characters {
if self.filter.is_empty()
|| name.contains(&self.filter)
@ -27,7 +26,7 @@ impl FontBook {
{
let button = Button::new(chr).text_style(self.text_style).frame(false);
let tooltip_ui = |ui: &mut Ui| {
let tooltip_ui = |ui: &mut egui::Ui| {
ui.add(Label::new(chr).text_style(self.text_style));
ui.label(format!("{}\nU+{:X}\n\nClick to copy", name, chr as u32));
};
@ -40,23 +39,23 @@ impl FontBook {
}
}
impl demos::Demo for FontBook {
impl crate::Demo for FontBook {
fn name(&self) -> &str {
"🔤 Font Book"
}
fn show(&mut self, ctx: &crate::CtxRef, open: &mut bool) {
Window::new(self.name()).open(open).show(ctx, |ui| {
use demos::View;
fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) {
egui::Window::new(self.name()).open(open).show(ctx, |ui| {
use crate::View;
self.ui(ui);
});
}
}
impl demos::View for FontBook {
fn ui(&mut self, ui: &mut Ui) {
use crate::demos::font_contents_emoji::FULL_EMOJI_LIST;
use crate::demos::font_contents_ubuntu::UBUNTU_FONT_CHARACTERS;
impl crate::View for FontBook {
fn ui(&mut self, ui: &mut egui::Ui) {
use crate::font_contents_emoji::FULL_EMOJI_LIST;
use crate::font_contents_ubuntu::UBUNTU_FONT_CHARACTERS;
ui.label(format!(
"Egui supports {} standard characters and {} emojis.\nClick on a character to copy it.",
@ -66,8 +65,8 @@ impl demos::View for FontBook {
ui.separator();
combo_box_with_label(ui, "Text style", format!("{:?}", self.text_style), |ui| {
for style in TextStyle::all() {
egui::combo_box_with_label(ui, "Text style", format!("{:?}", self.text_style), |ui| {
for style in egui::TextStyle::all() {
ui.selectable_value(&mut self.text_style, style, format!("{:?}", style));
}
});
@ -89,9 +88,9 @@ impl demos::View for FontBook {
ui.separator();
crate::ScrollArea::auto_sized().show(ui, |ui| {
egui::ScrollArea::auto_sized().show(ui, |ui| {
ui.horizontal_wrapped(|ui| {
ui.style_mut().spacing.item_spacing = Vec2::splat(2.0);
ui.style_mut().spacing.item_spacing = egui::Vec2::splat(2.0);
if self.standard {
self.characters_ui(ui, UBUNTU_FONT_CHARACTERS);

0
egui/src/demos/font_contents_emoji.rs → egui_demo_lib/src/font_contents_emoji.rs

0
egui/src/demos/font_contents_ubuntu.rs → egui_demo_lib/src/font_contents_ubuntu.rs

2
egui/src/demos/fractal_clock.rs → egui_demo_lib/src/fractal_clock.rs

@ -1,4 +1,4 @@
use crate::{containers::*, widgets::*, *};
use egui::{containers::*, widgets::*, *};
use std::f32::consts::TAU;
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]

111
egui/src/demos/mod.rs → egui_demo_lib/src/lib.rs

@ -1,6 +1,52 @@
//! Demo-code for showing how Egui is used.
//!
//! The demo-code is also used in benchmarks and tests.
#![cfg_attr(not(debug_assertions), deny(warnings))] // Forbid warnings in release builds
#![forbid(unsafe_code)]
#![warn(
clippy::all,
clippy::await_holding_lock,
clippy::dbg_macro,
clippy::doc_markdown,
clippy::empty_enum,
clippy::enum_glob_use,
clippy::exit,
clippy::filter_map_next,
clippy::fn_params_excessive_bools,
clippy::if_let_mutex,
clippy::imprecise_flops,
clippy::inefficient_to_string,
clippy::linkedlist,
clippy::lossy_float_literal,
clippy::macro_use_imports,
clippy::match_on_vec_items,
clippy::match_wildcard_for_single_variants,
clippy::mem_forget,
clippy::mismatched_target_os,
clippy::missing_errors_doc,
clippy::missing_safety_doc,
clippy::needless_borrow,
clippy::needless_continue,
clippy::needless_pass_by_value,
clippy::option_option,
clippy::pub_enum_variant_names,
clippy::rest_pat_in_fully_bound_structs,
clippy::todo,
clippy::unimplemented,
clippy::unnested_or_patterns,
clippy::verbose_file_reads,
future_incompatible,
missing_crate_level_docs,
missing_doc_code_examples,
// missing_docs,
nonstandard_style,
rust_2018_idioms,
unused_doc_comments,
)]
// ----------------------------------------------------------------------------
mod app;
mod color_test;
mod dancing_strings;
@ -34,7 +80,7 @@ Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius, tur
/// Something to view in the demo windows
pub trait View {
fn ui(&mut self, ui: &mut crate::Ui);
fn ui(&mut self, ui: &mut egui::Ui);
}
/// Something to view
@ -42,55 +88,20 @@ pub trait Demo {
fn name(&self) -> &str;
/// Show windows, etc
fn show(&mut self, ctx: &crate::CtxRef, open: &mut bool);
fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool);
}
// ----------------------------------------------------------------------------
pub fn warn_if_debug_build(ui: &mut crate::Ui) {
if crate::has_debug_assertions() {
ui.label(
crate::Label::new("‼ Debug build ‼")
.small()
.text_color(crate::color::RED),
)
.on_hover_text("Egui was compiled with debug assertions enabled.");
}
}
// ----------------------------------------------------------------------------
/// Create a [`Hyperlink`](crate::Hyperlink) to this file (and line) on Github
///
/// Example: `ui.add(github_link_file_line!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export]
macro_rules! github_link_file_line {
($github_url:expr, $label:expr) => {{
let url = format!("{}{}#L{}", $github_url, file!(), line!());
$crate::Hyperlink::new(url).text($label)
}};
}
/// Create a [`Hyperlink`](crate::Hyperlink) to this file on github.
///
/// Example: `ui.add(github_link_file!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export]
macro_rules! github_link_file {
($github_url:expr, $label:expr) => {{
let url = format!("{}{}", $github_url, file!());
$crate::Hyperlink::new(url).text($label)
}};
}
/// Create a [`Hyperlink`](crate::Hyperlink) to this egui source code file on github.
#[doc(hidden)]
#[macro_export]
macro_rules! __egui_github_link_file {
() => {
__egui_github_link_file!("(source code)")
crate::__egui_github_link_file!("(source code)")
};
($label:expr) => {
github_link_file!("https://github.com/emilk/egui/blob/master/", $label).small()
egui::github_link_file!("https://github.com/emilk/egui/blob/master/", $label).small()
};
}
@ -99,9 +110,27 @@ macro_rules! __egui_github_link_file {
#[macro_export]
macro_rules! __egui_github_link_file_line {
() => {
__egui_github_link_file_line!("(source code)")
crate::__egui_github_link_file_line!("(source code)")
};
($label:expr) => {
github_link_file_line!("https://github.com/emilk/egui/blob/master/", $label).small()
egui::github_link_file_line!("https://github.com/emilk/egui/blob/master/", $label).small()
};
}
// ----------------------------------------------------------------------------
#[test]
fn test_egui_e2e() {
let mut demo_windows = crate::DemoWindows::default();
let mut ctx = egui::CtxRef::default();
let raw_input = egui::RawInput::default();
const NUM_FRAMES: usize = 5;
for _ in 0..NUM_FRAMES {
ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_output, paint_commands) = ctx.end_frame();
let paint_jobs = ctx.tessellate(paint_commands);
assert!(!paint_jobs.is_empty());
}
}

9
egui/src/demos/painting.rs → egui_demo_lib/src/painting.rs

@ -1,4 +1,5 @@
use crate::{demos::*, *};
use crate::*;
use egui::*;
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
@ -58,7 +59,7 @@ impl Painting {
}
}
impl demos::Demo for Painting {
impl crate::Demo for Painting {
fn name(&self) -> &str {
"🖊 Painting"
}
@ -72,9 +73,9 @@ impl demos::Demo for Painting {
}
}
impl demos::View for Painting {
impl crate::View for Painting {
fn ui(&mut self, ui: &mut Ui) {
ui.add(__egui_github_link_file!("(source code)"));
ui.add(crate::__egui_github_link_file!("(source code)"));
self.ui_control(ui);
ui.label("Paint with your mouse/touch!");
Frame::dark_canvas(ui.style()).show(ui, |ui| {

3
egui/src/demos/scrolls.rs → egui_demo_lib/src/scrolls.rs

@ -1,4 +1,5 @@
use crate::{color::*, demos::LOREM_IPSUM_LONG, *};
use crate::LOREM_IPSUM_LONG;
use egui::{color::*, *};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]

2
egui/src/demos/sliders.rs → egui_demo_lib/src/sliders.rs

@ -1,4 +1,4 @@
use crate::*;
use egui::*;
use std::f64::INFINITY;
/// Showcase sliders

16
egui/src/demos/tests.rs → egui_demo_lib/src/tests.rs

@ -1,23 +1,21 @@
use crate::*;
#[derive(Default)]
pub struct Tests {}
impl demos::Demo for Tests {
impl crate::Demo for Tests {
fn name(&self) -> &str {
"📋 Tests"
}
fn show(&mut self, ctx: &crate::CtxRef, open: &mut bool) {
Window::new(self.name()).open(open).show(ctx, |ui| {
use demos::View;
fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) {
egui::Window::new(self.name()).open(open).show(ctx, |ui| {
use crate::View;
self.ui(ui);
});
}
}
impl demos::View for Tests {
fn ui(&mut self, ui: &mut Ui) {
impl crate::View for Tests {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.heading("Name collision example");
ui.label("\
@ -46,6 +44,6 @@ impl demos::View for Tests {
let _ = ui.button("Button");
let _ = ui.button("Button");
ui.add(__egui_github_link_file!());
ui.add(crate::__egui_github_link_file!());
}
}

35
egui/src/demos/toggle_switch.rs → egui_demo_lib/src/toggle_switch.rs

@ -1,6 +1,5 @@
//! Source code example of how to create your own widget.
//! This is meant to be read as a tutorial, hence the plethora of comments.
use crate::*;
/// iOS-style toggle switch:
///
@ -10,7 +9,7 @@ use crate::*;
/// | |.......|
/// \_______\_____/
/// ```
pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response {
pub fn toggle(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
// Widget code can be broken up in four steps:
// 1. Decide a size for the widget
// 2. Allocate space for it
@ -25,7 +24,7 @@ pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response {
// 2. Allocating space:
// This is where we get a region of the screen assigned.
// We also tell the Ui to sense clicks in the allocated region.
let response = ui.allocate_response(desired_size, Sense::click());
let response = ui.allocate_response(desired_size, egui::Sense::click());
// 3. Interact: Time to check for clicks!.
if response.clicked {
@ -41,16 +40,16 @@ pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response {
// "how should something that is being interacted with be painted?".
// This will, for instance, give us different colors when the widget is hovered or clicked.
let visuals = ui.style().interact(&response);
let off_bg_fill = Rgba::new(0.0, 0.0, 0.0, 0.0);
let on_bg_fill = Rgba::new(0.0, 0.5, 0.25, 1.0);
let bg_fill = lerp(off_bg_fill..=on_bg_fill, how_on);
let off_bg_fill = egui::Rgba::new(0.0, 0.0, 0.0, 0.0);
let on_bg_fill = egui::Rgba::new(0.0, 0.5, 0.25, 1.0);
let bg_fill = egui::lerp(off_bg_fill..=on_bg_fill, how_on);
// All coordinates are in absolute screen coordinates so we use `rect` to place the elements.
let rect = response.rect;
let radius = 0.5 * rect.height();
ui.painter().rect(rect, radius, bg_fill, visuals.bg_stroke);
// Paint the circle, animating it from left to right with `how_on`:
let circle_x = lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
let center = pos2(circle_x, rect.center().y);
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
let center = egui::pos2(circle_x, rect.center().y);
ui.painter()
.circle(center, 0.75 * radius, visuals.fg_fill, visuals.fg_stroke);
@ -61,32 +60,32 @@ pub fn toggle(ui: &mut Ui, on: &mut bool) -> Response {
/// Here is the same code again, but a bit more compact:
#[allow(dead_code)]
fn toggle_compact(ui: &mut Ui, on: &mut bool) -> Response {
fn toggle_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
let desired_size = ui.style().spacing.interact_size;
let response = ui.allocate_response(desired_size, Sense::click());
let response = ui.allocate_response(desired_size, egui::Sense::click());
*on ^= response.clicked; // toggle if clicked
let how_on = ui.ctx().animate_bool(response.id, *on);
let visuals = ui.style().interact(&response);
let off_bg_fill = Rgba::new(0.0, 0.0, 0.0, 0.0);
let on_bg_fill = Rgba::new(0.0, 0.5, 0.25, 1.0);
let bg_fill = lerp(off_bg_fill..=on_bg_fill, how_on);
let off_bg_fill = egui::Rgba::new(0.0, 0.0, 0.0, 0.0);
let on_bg_fill = egui::Rgba::new(0.0, 0.5, 0.25, 1.0);
let bg_fill = egui::lerp(off_bg_fill..=on_bg_fill, how_on);
let rect = response.rect;
let radius = 0.5 * rect.height();
ui.painter().rect(rect, radius, bg_fill, visuals.bg_stroke);
let circle_x = lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
let center = pos2(circle_x, rect.center().y);
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
let center = egui::pos2(circle_x, rect.center().y);
ui.painter()
.circle(center, 0.75 * radius, visuals.fg_fill, visuals.fg_stroke);
response
}
pub fn demo(ui: &mut Ui, on: &mut bool) {
ui.horizontal_wrapped_for_text(TextStyle::Button, |ui| {
pub fn demo(ui: &mut egui::Ui, on: &mut bool) {
ui.horizontal_wrapped_for_text(egui::TextStyle::Button, |ui| {
ui.label("It's easy to create your own widgets!");
ui.label("This toggle switch is just one function and 15 lines of code:");
toggle(ui, on).on_hover_text("Click to toggle");
ui.add(__egui_github_link_file!());
ui.add(crate::__egui_github_link_file!());
});
}

16
egui/src/demos/widgets.rs → egui_demo_lib/src/widgets.rs

@ -1,4 +1,4 @@
use crate::{color::*, demos::Sliders, *};
use egui::{color::*, *};
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
@ -20,7 +20,7 @@ pub struct Widgets {
button_enabled: bool,
count: usize,
radio: Enum,
sliders: Sliders,
sliders: crate::Sliders,
angle: f32,
color: Srgba,
single_line_text_input: String,
@ -46,7 +46,7 @@ impl Default for Widgets {
impl Widgets {
pub fn ui(&mut self, ui: &mut Ui) {
ui.add(__egui_github_link_file_line!());
ui.add(crate::__egui_github_link_file_line!());
ui.horizontal_wrapped_for_text(TextStyle::Body, |ui| {
ui.add(Label::new("Text can have").text_color(srgba(110, 255, 110, 255)));
@ -83,7 +83,7 @@ impl Widgets {
ui.radio_value(&mut self.radio, Enum::Third, "Third");
});
combo_box_with_label(ui, "Combo Box", format!("{:?}", self.radio), |ui| {
egui::combo_box_with_label(ui, "Combo Box", format!("{:?}", self.radio), |ui| {
ui.selectable_value(&mut self.radio, Enum::First, "First");
ui.selectable_value(&mut self.radio, Enum::Second, "Second");
ui.selectable_value(&mut self.radio, Enum::Third, "Third");
@ -110,12 +110,12 @@ impl Widgets {
});
ui.add(
Slider::f64(&mut self.sliders.value, 1.0..=100.0)
egui::Slider::f64(&mut self.sliders.value, 1.0..=100.0)
.logarithmic(true)
.text("A slider"),
);
CollapsingHeader::new("More sliders")
egui::CollapsingHeader::new("More sliders")
.default_open(false)
.show(ui, |ui| {
self.sliders.ui(ui);
@ -136,7 +136,7 @@ impl Widgets {
ui.separator();
ui.horizontal(|ui| {
ui.add(Label::new("Click to select a different text color: ").text_color(self.color));
ui.colored_label(self.color, "Click to select a different text color: ");
ui.color_edit_button_srgba(&mut self.color);
});
@ -154,6 +154,6 @@ impl Widgets {
ui.text_edit_multiline(&mut self.multiline_text_input);
ui.separator();
super::toggle_switch::demo(ui, &mut self.toggle_switch);
crate::toggle_switch::demo(ui, &mut self.toggle_switch);
}
}
Loading…
Cancel
Save