diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3d9c046ce53..5d05e480b2b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -3,7 +3,7 @@ on: [push, pull_request] name: CI env: - # This is required to enable the web_sys clipboard API which egui_web uses + # This is required to enable the web_sys clipboard API which eframe web uses # https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html # https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html RUSTFLAGS: --cfg=web_sys_unstable_apis @@ -160,21 +160,7 @@ jobs: toolchain: 1.60.0 override: true - run: sudo apt-get update && sudo apt-get install libspeechd-dev - - run: cargo doc -p eframe -p egui -p egui_extras -p egui_glium -p egui_glow -p egui_web -p egui-winit -p emath -p epaint -p epi --lib --no-deps --all-features - - doc_web: - name: cargo doc web - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: 1.60.0 - override: true - - run: sudo apt-get update && sudo apt-get install libspeechd-dev - - run: rustup target add wasm32-unknown-unknown - - run: cargo doc -p egui_web --target wasm32-unknown-unknown --lib --no-deps --all-features + - run: cargo doc -p eframe -p egui -p egui_extras -p egui_glium -p egui_glow -p egui-winit -p emath -p epaint --lib --no-deps --all-features cargo-deny: runs-on: ubuntu-20.04 diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 397d7fd36df..d11da529b78 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -5,7 +5,7 @@ Also see [`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUT ## Crate overview -The crates in this repository are: `egui, emath, epaint, egui_extras, epi, egui-winit, egui_web, egui_glium, egui_glow, egui_demo_lib, egui_demo_app`. +The crates in this repository are: `egui, emath, epaint, egui_extras, egui-winit, egui_glium, egui_glow, egui_demo_lib, egui_demo_app`. ### `egui`: The main GUI library. Example code: `if ui.button("Click me").clicked() { … }` @@ -24,18 +24,11 @@ Depends on `emath`. ### `egui_extras` This adds additional features on top of `egui`. -### `epi` -Depends only on `egui`. -Adds a thin application level wrapper around `egui` for hosting an `egui` app inside of `eframe`. - ### `egui-winit` This crates provides bindings between [`egui`](https://github.com/emilk/egui) and [winit](https://crates.io/crates/winit). The library translates winit events to egui, handled copy/paste, updates the cursor, open links clicked in egui, etc. -### `egui_web` -Puts an egui app inside the web browser by compiling to WASM and binding to the web browser with [`js-sys`](https://crates.io/crates/js-sys) and [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen). Paints the triangles that egui outputs using WebGL. - ### `egui_glium` Puts an egui app inside a native window on your laptop. Paints the triangles that egui outputs using [glium](https://github.com/glium/glium). @@ -43,12 +36,12 @@ Puts an egui app inside a native window on your laptop. Paints the triangles tha Puts an egui app inside a native window on your laptop. Paints the triangles that egui outputs using [glow](https://github.com/grovesNL/glow). ### `eframe` -A wrapper around `egui_web` + `egui_glium`, so you can compile the same app for either web or native. +`eframe` is the official `egui` framework, built so you can compile the same app for either web or native. The demo that you can see at is using `eframe` to host the `egui`. The demo code is found in: ### `egui_demo_lib` -Depends on `egui` + `epi`. +Depends on `egui`. This contains a bunch of uses of `egui` and looks like the ui code you would write for an `egui` app. ### `egui_demo_app` diff --git a/CHANGELOG.md b/CHANGELOG.md index 6513cf7469c..448ccdfcca7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # egui changelog All notable changes to the `egui` crate will be documented in this file. -NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md), [`egui-winit`](egui-winit/CHANGELOG.md), [`egui_glium`](egui_glium/CHANGELOG.md), and [`egui_glow`](egui_glow/CHANGELOG.md) have their own changelogs! +NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui-winit`](egui-winit/CHANGELOG.md), [`egui_glium`](egui_glium/CHANGELOG.md), and [`egui_glow`](egui_glow/CHANGELOG.md) have their own changelogs! ## Unreleased @@ -366,9 +366,9 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w * [Add plot legends](https://github.com/emilk/egui/pull/349). * [Users can now store custom state in `egui::Memory`](https://github.com/emilk/egui/pull/257). * Add `Response::on_disabled_hover_text` to show tooltip for disabled widgets. -* Zoom input: ctrl-scroll and (on `egui_web`) trackpad-pinch gesture. +* Zoom input: ctrl-scroll and (on `eframe` web) trackpad-pinch gesture. * Support for raw [multi touch](https://github.com/emilk/egui/pull/306) events, - enabling zoom, rotate, and more. Works with `egui_web` on mobile devices, + enabling zoom, rotate, and more. Works with `eframe` web on mobile devices, and should work with `egui_glium` for certain touch devices/screens. * Add (optional) compatibility with [mint](https://docs.rs/mint). diff --git a/Cargo.lock b/Cargo.lock index 087d4c4150b..416e908b0bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1075,15 +1075,24 @@ checksum = "6907e25393cdcc1f4f3f513d9aac1e840eb1cc341a0fccb01171f7d14d10b946" name = "eframe" version = "0.17.0" dependencies = [ + "bytemuck", "dark-light", + "directories-next", "egui", "egui-winit", "egui_glow", - "egui_web", - "epi", "glow", "glutin", + "js-sys", + "percent-encoding", "puffin", + "ron", + "serde", + "tracing", + "tts", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", "winit", ] @@ -1189,25 +1198,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "egui_web" -version = "0.17.0" -dependencies = [ - "bytemuck", - "egui", - "egui_glow", - "epi", - "js-sys", - "percent-encoding", - "ron", - "serde", - "tracing", - "tts", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "ehttp" version = "0.2.0" @@ -1307,18 +1297,6 @@ dependencies = [ "serde", ] -[[package]] -name = "epi" -version = "0.17.0" -dependencies = [ - "directories-next", - "egui", - "glow", - "ron", - "serde", - "tracing", -] - [[package]] name = "error-code" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index 1aad261ee74..25b3d8c4743 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,10 @@ members = [ "egui_extras", "egui_glium", "egui_glow", - "egui_web", "egui-winit", "egui", "emath", "epaint", - "epi", "examples/confirm_exit", "examples/custom_3d_glow", diff --git a/README.md b/README.md index c6bb3875651..a3baa7919f6 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ If you have questions, use [GitHub Discussions](https://github.com/emilk/egui/di ## Demo -[Click to run egui web demo](https://www.egui.rs/#demo) (works in any browser with WASM and WebGL support). Uses [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web). +[Click to run egui web demo](https://www.egui.rs/#demo) (works in any browser with WASM and WebGL support). Uses [`eframe`](https://github.com/emilk/egui/tree/master/eframe). To test the demo app locally, run `cargo run --release -p egui_demo_app`. @@ -160,14 +160,12 @@ An integration needs to do the following each frame: ### Official integrations -If you're making an app, your best bet is using [`eframe`](https://github.com/emilk/egui/tree/master/eframe), the official egui framework. It lets you write apps that work on both the web and native. `eframe` is just a thin wrapper over `egui_web` and `egui_glow` (see below). - These are the official egui integrations: +* [`eframe`](https://github.com/emilk/egui/tree/master/eframe) for compiling the same app to web/wasm and desktop/native. Uses `egui_glow` and `egui-winit`. * [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) for compiling native apps with [Glium](https://github.com/glium/glium). * [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) for rendering egui with [glow](https://github.com/grovesNL/glow) on native and web, and for making native apps. -* [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) for making a web app. Compiles to WASM, renders with WebGL. [Click to run the egui demo](https://www.egui.rs/#demo). Uses `egui_glow`. -* [`egui-winit`](https://github.com/emilk/egui/tree/master/egui-winit) for integrating with [winit](https://github.com/rust-windowing/winit). `egui-winit` is used by `egui_glium` and `egui_glow`. +* [`egui-winit`](https://github.com/emilk/egui/tree/master/egui-winit) for integrating with [winit](https://github.com/rust-windowing/winit). ### 3rd party integrations @@ -217,7 +215,7 @@ loop { } ``` -For a reference OpenGL backend, see [the `egui_glium` painter](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs), [the `egui_glow` painter](https://github.com/emilk/egui/blob/master/egui_glow/src/painter.rs), or [the `egui_web` `WebGL` painter](https://github.com/emilk/egui/blob/master/egui_web/src/webgl2.rs). +For a reference OpenGL backend, see [the `egui_glium` painter](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs) or [the `egui_glow` painter](https://github.com/emilk/egui/blob/master/egui_glow/src/painter.rs). ### Debugging your integration @@ -385,7 +383,7 @@ Notable contributions by: * [@optozorax](https://github.com/optozorax): [Arbitrary widget data storage](https://github.com/emilk/egui/pull/257). * [@quadruple-output](https://github.com/quadruple-output): [Multitouch](https://github.com/emilk/egui/pull/306). * [@EmbersArc](https://github.com/EmbersArc): [Plots](https://github.com/emilk/egui/pulls?q=+is%3Apr+author%3AEmbersArc). -* [@AsmPrgmC3](https://github.com/AsmPrgmC3): [Proper sRGBA blending in `egui_web`](https://github.com/emilk/egui/pull/650). +* [@AsmPrgmC3](https://github.com/AsmPrgmC3): [Proper sRGBA blending for web](https://github.com/emilk/egui/pull/650). * [@AlexApps99](https://github.com/AlexApps99): [`egui_glow`](https://github.com/emilk/egui/pull/685). * [@mankinskin](https://github.com/mankinskin): [Context menus](https://github.com/emilk/egui/pull/543). * [@t18b219k](https://github.com/t18b219k): [Port glow painter to web](https://github.com/emilk/egui/pull/868). diff --git a/eframe/CHANGELOG.md b/eframe/CHANGELOG.md index 5a3fe9caaa1..48d776e3432 100644 --- a/eframe/CHANGELOG.md +++ b/eframe/CHANGELOG.md @@ -1,15 +1,12 @@ # Changelog for eframe -All notable changes to the `eframe` and `epi` crates. +All notable changes to the `eframe` crate. -NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/CHANGELOG.md), and [`egui_glow`](../egui_glow/CHANGELOG.md) have their own changelogs! +NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/CHANGELOG.md), and [`egui_glow`](../egui_glow/CHANGELOG.md) have their own changelogs! ## Unreleased -* Change default for `NativeOptions::drag_and_drop_support` to `true` ([#1329](https://github.com/emilk/egui/pull/1329)). -* Remove the `egui_glium` feature. `eframe` will now always use `egui_glow` as the native backend ([#1357](https://github.com/emilk/egui/pull/1357)). +* Removed `eframe::epi` - everything is now in `eframe` (`eframe::App`, `eframe::Frame` etc) ([#1545](https://github.com/emilk/egui/pull/1545)). * Removed `Frame::request_repaint` - just call `egui::Context::request_repaint` for the same effect ([#1366](https://github.com/emilk/egui/pull/1366)). -* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). -* Added new `NativeOptions`: `vsync`, `multisampling`, `depth_buffer`, `stencil_buffer`. * Changed app creation/setup ([#1363](https://github.com/emilk/egui/pull/1363)): * Removed `App::setup` and `App::name`. * Provide `CreationContext` when creating app with egui context, storage, integration info and glow context. @@ -19,24 +16,39 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG * Changed `App::update` to take `&mut Frame` instead of `&Frame`. * `Frame` is no longer `Clone` or `Sync`. * Add `glow` (OpenGL) context to `Frame` ([#1425](https://github.com/emilk/egui/pull/1425)). -* Fixed potential scale bug when DPI scaling changes (e.g. when dragging a window between different displays) ([#1441](https://github.com/emilk/egui/pull/1441)). * MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)). + +#### Desktop/Native: +* Remove the `egui_glium` feature. `eframe` will now always use `egui_glow` as the native backend ([#1357](https://github.com/emilk/egui/pull/1357)). +* Change default for `NativeOptions::drag_and_drop_support` to `true` ([#1329](https://github.com/emilk/egui/pull/1329)). +* Added new `NativeOptions`: `vsync`, `multisampling`, `depth_buffer`, `stencil_buffer`. * `dark-light` (dark mode detection) is now an opt-in feature ([#1437](https://github.com/emilk/egui/pull/1437)). +* Fixed potential scale bug when DPI scaling changes (e.g. when dragging a window between different displays) ([#1441](https://github.com/emilk/egui/pull/1441)). * Added new feature `puffin` to add [`puffin profiler`](https://github.com/EmbarkStudios/puffin) scopes ([#1483](https://github.com/emilk/egui/pull/1483)). * Moved app persistence to a background thread, allowing for smoother frame rates (on native). +#### Web: +* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). +* egui code will no longer be called after panic ([#1306](https://github.com/emilk/egui/pull/1306)). + ## 0.17.0 - 2022-02-22 * Removed `Frame::alloc_texture`. Use `egui::Context::load_texture` instead ([#1110](https://github.com/emilk/egui/pull/1110)). +* Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)). +* Log using the `tracing` crate. Log to stdout by adding `tracing_subscriber::fmt::init();` to your `main` ([#1192](https://github.com/emilk/egui/pull/1192)). + +#### Desktop/Native: * The default native backend is now `egui_glow` (instead of `egui_glium`) ([#1020](https://github.com/emilk/egui/pull/1020)). -* The default web painter is now `egui_glow` (instead of WebGL) ([#1020](https://github.com/emilk/egui/pull/1020)). * Automatically detect and apply dark or light mode from system ([#1045](https://github.com/emilk/egui/pull/1045)). * Fix horizontal scrolling direction on Linux. * Added `App::on_exit_event` ([#1038](https://github.com/emilk/egui/pull/1038)) * Added `NativeOptions::initial_window_pos`. * Fixed `enable_drag` for Windows OS ([#1108](https://github.com/emilk/egui/pull/1108)). -* Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)). -* Log using the `tracing` crate. Log to stdout by adding `tracing_subscriber::fmt::init();` to your `main` ([#1192](https://github.com/emilk/egui/pull/1192)). + +#### Web: +* The default web painter is now `egui_glow` (instead of WebGL) ([#1020](https://github.com/emilk/egui/pull/1020)). +* Fixed glow failure on Chromium ([#1092](https://github.com/emilk/egui/pull/1092)). +* Updated `eframe::IntegrationInfo::web_location_hash` on `hashchange` event ([#1140](https://github.com/emilk/egui/pull/1140)). * Expose all parts of the location/url in `frame.info().web_info` ([#1258](https://github.com/emilk/egui/pull/1258)). @@ -45,20 +57,34 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG * Added `Frame::request_repaint` to replace `repaint_signal` ([#999](https://github.com/emilk/egui/pull/999)). * Added `Frame::alloc_texture/free_texture` to replace `tex_allocator` ([#999](https://github.com/emilk/egui/pull/999)). +#### Web: +* Fixed [dark rendering in WebKitGTK](https://github.com/emilk/egui/issues/794) ([#888](https://github.com/emilk/egui/pull/888/)). +* Added feature `glow` to switch to a [`glow`](https://github.com/grovesNL/glow) based painter ([#868](https://github.com/emilk/egui/pull/868)). + ## 0.15.0 - 2021-10-24 * `Frame` now provides `set_window_title` to set window title dynamically * `Frame` now provides `set_decorations` to set whether to show window decorations. * Remove "http" feature (use https://github.com/emilk/ehttp instead!). -* Increase native scroll speed. * Add `App::persist_native_window` and `App::persist_egui_memory` to control what gets persisted. + +#### Desktop/Native: +* Increase native scroll speed. * Add new backend `egui_glow` as an alternative to `egui_glium`. Enable with `default-features = false, features = ["default_fonts", "egui_glow"]`. +#### Web: +* Implement `eframe::NativeTexture` trait for the WebGL painter. +* Deprecate `Painter::register_webgl_texture. +* Fix multiline paste. +* Fix painting with non-opaque backgrounds. +* Improve text input on mobile and for IME. + ## 0.14.0 - 2021-08-24 * Add dragging and dropping files into egui. * Improve http fetch API. * `run_native` now returns when the app is closed. +* Web: Made text thicker and less pixelated. ## 0.13.1 - 2021-06-24 @@ -68,16 +94,24 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG ## 0.13.0 - 2021-06-24 * `App::setup` now takes a `Frame` and `Storage` by argument. * `App::load` has been removed. Implement `App::setup` instead. +* Web: Default to light visuals unless the system reports a preference for dark mode. +* Web: Improve alpha blending, making fonts look much better (especially in light mode) +* Web: Fix double-paste bug ## 0.12.0 - 2021-05-10 * Moved options out of `trait App` into new `NativeOptions`. * Add option for `always_on_top`. +* Web: Scroll faster when scrolling with mouse wheel. ## 0.11.0 - 2021-04-05 * You can now turn your window transparent with the `App::transparent` option. * You can now disable window decorations with the `App::decorated` option. +* Web: [Fix mobile and IME text input](https://github.com/emilk/egui/pull/253) +* Web: Hold down a modifier key when clicking a link to open it in a new tab. + +Contributors: [n2](https://github.com/n2) ## 0.10.0 - 2021-02-28 @@ -89,10 +123,15 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG ## 0.9.0 - 2021-02-07 * [Add support for HTTP body](https://github.com/emilk/egui/pull/139). +* Web: Right-clicks will no longer open browser context menu. +* Web: Fix a bug where one couldn't select items in a combo box on a touch screen. ## 0.8.0 - 2021-01-17 * Simplify `TextureAllocator` interface. +* WebGL2 is now supported, with improved texture sampler. WebGL1 will be used as a fallback. +* Web: Slightly improved alpha-blending (work-around for non-existing linear-space blending). +* Web: Call `prevent_default` for arrow keys when entering text ## 0.7.0 - 2021-01-04 diff --git a/eframe/Cargo.toml b/eframe/Cargo.toml index 2f5ccc5c8a7..19adbbe075d 100644 --- a/eframe/Cargo.toml +++ b/eframe/Cargo.toml @@ -31,9 +31,11 @@ default_fonts = ["egui/default_fonts"] # Enable saving app state to disk. persistence = [ + "directories-next", "egui-winit/serde", "egui/persistence", - "epi/persistence", + "ron", + "serde", ] # Enable profiling with the puffin crate: https://github.com/EmbarkStudios/puffin @@ -44,27 +46,85 @@ puffin = ["dep:puffin", "egui_glow/puffin"] # enable screen reader support (requires `ctx.options().screen_reader = true;`) screen_reader = [ "egui-winit/screen_reader", - "egui_web/screen_reader", + "tts", ] [dependencies] -egui = { version = "0.17.0", path = "../egui", default-features = false } -epi = { version = "0.17.0", path = "../epi" } +egui = { version = "0.17.0", path = "../egui", default-features = false, features = [ + "bytemuck", + "tracing", +] } +egui_glow = { version = "0.17.0", path = "../egui_glow", default-features = false } +glow = "0.11" +tracing = "0.1" + +# optional: +ron = { version = "0.7", optional = true } +serde = { version = "1", optional = true } +# ------------------------------------------- # native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -egui_glow = { version = "0.17.0", path = "../egui_glow", default-features = false, features = [ - "clipboard", - "links", -] } dark-light = { version = "0.2.1", optional = true } egui-winit = { version = "0.17.0", path = "../egui-winit", default-features = false, features = ["clipboard", "links"] } -glow = "0.11" glutin = { version = "0.28.0" } -puffin = { version = "0.13", optional = true } winit = "0.26.1" +# optional: +puffin = { version = "0.13", optional = true } +directories-next = { version = "2", optional = true } + +# ------------------------------------------- # web: [target.'cfg(target_arch = "wasm32")'.dependencies] -egui_web = { version = "0.17.0", path = "../egui_web", default-features = false } +bytemuck = "1.7" +js-sys = "0.3" +percent-encoding = "2.1" +wasm-bindgen = "0.2" +wasm-bindgen-futures = "0.4" +web-sys = { version = "0.3.52", features = [ + "BinaryType", + "Blob", + "Clipboard", + "ClipboardEvent", + "CompositionEvent", + "console", + "CssStyleDeclaration", + "DataTransfer", + "DataTransferItem", + "DataTransferItemList", + "Document", + "DomRect", + "DragEvent", + "Element", + "Event", + "EventListener", + "EventTarget", + "ExtSRgb", + "File", + "FileList", + "FocusEvent", + "HtmlCanvasElement", + "HtmlElement", + "HtmlInputElement", + "InputEvent", + "KeyboardEvent", + "Location", + "MediaQueryList", + "MouseEvent", + "Navigator", + "Performance", + "Storage", + "Touch", + "TouchEvent", + "TouchList", + "WebGl2RenderingContext", + "WebglDebugRendererInfo", + "WebGlRenderingContext", + "WheelEvent", + "Window", +] } + +# optional: +tts = { version = "0.20", optional = true } # feature screen_reader diff --git a/eframe/README.md b/eframe/README.md index b7eda2d7b48..7554384ca11 100644 --- a/eframe/README.md +++ b/eframe/README.md @@ -17,9 +17,7 @@ For how to use `egui`, see [the egui docs](https://docs.rs/egui). --- -`eframe` is a very thin crate that re-exports [`egui`](https://github.com/emilk/egui) and[`epi`](https://github.com/emilk/egui/tree/master/epi) with thin wrappers over the backends. - -`eframe` uses [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) for web and [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) for native. +`eframe` uses [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) for rendering, and on native it uses [`egui-winit`](https://github.com/emilk/egui/tree/master/egui-winit). To use on Linux, first run: @@ -34,6 +32,22 @@ You need to either use `edition = "2021"`, or set `resolver = "2"` in the `[work `eframe` is not the only way to write an app using `egui`! You can also try [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad), [`bevy_egui`](https://github.com/mvlabat/bevy_egui), [`egui_sdl2_gl`](https://github.com/ArjunNair/egui_sdl2_gl), and others. +## Problems with running egui on the web +`eframe` uses WebGL (via [`glow`](https://crates.io/crates/glow)) and WASM, and almost nothing else from the web tech stack. This has some benefits, but also produces some challenges and serious downsides. + +* Rendering: Getting pixel-perfect rendering right on the web is very difficult. +* Search: you cannot search an egui web page like you would a normal web page. +* Bringing up an on-screen keyboard on mobile: there is no JS function to do this, so `eframe` fakes it by adding some invisible DOM elements. It doesn't always work. +* Mobile text editing is not as good as for a normal web app. +* Accessibility: There is an experimental screen reader for `eframe`, but it has to be enabled explicitly. There is no JS function to ask "Does the user want a screen reader?" (and there should probably not be such a function, due to user tracking/integrity concerns). +* No integration with browser settings for colors and fonts. +* On Linux and Mac, Firefox will copy the WebGL render target from GPU, to CPU and then back again (https://bugzilla.mozilla.org/show_bug.cgi?id=1010527#c0), slowing down egui. + +In many ways, `eframe` is trying to make the browser do something it wasn't designed to do (though there are many things browser vendors could do to improve how well libraries like egui work). + +The suggested use for `eframe` are for web apps where performance and responsiveness are more important than accessibility and mobile text editing. + + ## Companion crates Not all rust crates work when compiled to WASM, but here are some useful crates have been designed to work well both natively and as WASM: @@ -44,5 +58,4 @@ Not all rust crates work when compiled to WASM, but here are some useful crates ## Name - The _frame_ in `eframe` stands both for the frame in which your `egui` app resides and also for "framework" (`frame` is a framework, `egui` is a library). diff --git a/epi/src/lib.rs b/eframe/src/epi.rs similarity index 94% rename from epi/src/lib.rs rename to eframe/src/epi.rs index 41693d946ee..5cd070d550a 100644 --- a/epi/src/lib.rs +++ b/eframe/src/epi.rs @@ -1,22 +1,12 @@ -//! Backend-agnostic interface for writing apps using [`egui`]. +//! Platform-agnostic interface for writing apps using [`egui`] (epi = egui programming interface). //! //! `epi` provides interfaces for window management and serialization. -//! An app written for `epi` can then be plugged into [`eframe`](https://docs.rs/eframe), -//! the egui framework crate. //! //! Start by looking at the [`App`] trait, and implement [`App::update`]. #![warn(missing_docs)] // Let's keep `epi` well-documented. -/// File storage which can be used by native backends. -#[cfg(not(target_arch = "wasm32"))] -#[cfg(feature = "persistence")] -pub mod file_storage; - -pub use egui; // Re-export for user convenience -pub use glow; // Re-export for user convenience - -/// The is is how your app is created. +/// This is how your app is created. /// /// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc. pub type AppCreator = Box) -> Box>; @@ -42,8 +32,7 @@ pub struct CreationContext<'s> { // ---------------------------------------------------------------------------- -/// Implement this trait to write apps that can be compiled both natively using the [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) crate, -/// and deployed as a web site using the [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) crate. +/// Implement this trait to write apps that can be compiled for both web/wasm and desktop/native using [`eframe`](https://github.com/emilk/egui/tree/master/eframe). pub trait App { /// Called each time the UI needs repainting, which may be many times per second. /// @@ -232,7 +221,7 @@ impl Default for NativeOptions { } } -/// Image data for the icon. +/// Image data for an application icon. #[derive(Clone)] pub struct IconData { /// RGBA pixels, unmultiplied. @@ -338,7 +327,7 @@ impl Frame { /// for integrations only: call once per frame #[doc(hidden)] - pub fn take_app_output(&mut self) -> crate::backend::AppOutput { + pub fn take_app_output(&mut self) -> backend::AppOutput { std::mem::take(&mut self.output) } } @@ -407,9 +396,6 @@ pub struct Location { /// Information about the integration passed to the use app each frame. #[derive(Clone, Debug)] pub struct IntegrationInfo { - /// The name of the integration, e.g. `egui_web`, `egui_glium`, `egui_glow` - pub name: &'static str, - /// If the app is running in a Web context, this returns information about the environment. pub web_info: Option, @@ -431,6 +417,8 @@ pub struct IntegrationInfo { /// /// On the web this is backed by [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). /// On desktop this is backed by the file system. +/// +/// See [`CreationContext::storage`] and [`App::save`]. pub trait Storage { /// Get the value for the given key. fn get_string(&self, key: &str) -> Option; @@ -443,7 +431,7 @@ pub trait Storage { /// Stores nothing. #[derive(Clone, Default)] -pub struct DummyStorage {} +pub(crate) struct DummyStorage {} impl Storage for DummyStorage { fn get_string(&self, _key: &str) -> Option { @@ -475,8 +463,6 @@ pub const APP_KEY: &str = "app"; /// You only need to look here if you are writing a backend for `epi`. #[doc(hidden)] pub mod backend { - use super::*; - /// Action that can be taken by the user app. #[derive(Clone, Debug, Default)] #[must_use] diff --git a/eframe/src/lib.rs b/eframe/src/lib.rs index fc2822abc8a..2a21f0aaa91 100644 --- a/eframe/src/lib.rs +++ b/eframe/src/lib.rs @@ -1,18 +1,14 @@ -//! eframe - the egui framework crate +//! eframe - the [`egui`] framework crate //! //! If you are planning to write an app for web or native, -//! and are happy with just using egui for all visuals, -//! Then `eframe` is for you! +//! and want to use [`egui`] for everything, then `eframe` is for you! //! //! To get started, see the [examples](https://github.com/emilk/egui/tree/master/examples). //! To learn how to set up `eframe` for web and native, go to and follow the instructions there! //! -//! In short, you implement [`App`] and then +//! In short, you implement [`App`] (especially [`App::update`]) and then //! call [`crate::run_native`] from your `main.rs`, and/or call `eframe::start_web` from your `lib.rs`. //! -//! `eframe` is implemented using [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) for web and -//! [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) for native. -//! //! ## Usage, native: //! ``` no_run //! use eframe::egui; @@ -60,7 +56,9 @@ #![allow(clippy::needless_doctest_main)] // Re-export all useful libraries: -pub use {egui, egui::emath, egui::epaint, epi}; +pub use {egui, egui::emath, egui::epaint, glow}; + +mod epi; // Re-export everything in `epi` so `eframe` users don't have to care about what `epi` is: pub use epi::*; @@ -69,7 +67,13 @@ pub use epi::*; // When compiling for web #[cfg(target_arch = "wasm32")] -pub use egui_web::wasm_bindgen; +mod web; + +#[cfg(target_arch = "wasm32")] +pub use wasm_bindgen; + +#[cfg(target_arch = "wasm32")] +pub use web_sys; /// Install event listeners to register different input events /// and start running the given app. @@ -90,7 +94,7 @@ pub use egui_web::wasm_bindgen; /// ``` #[cfg(target_arch = "wasm32")] pub fn start_web(canvas_id: &str, app_creator: AppCreator) -> Result<(), wasm_bindgen::JsValue> { - egui_web::start(canvas_id, app_creator)?; + web::start(canvas_id, app_creator)?; Ok(()) } diff --git a/eframe/src/native/epi_integration.rs b/eframe/src/native/epi_integration.rs index 2b9d80ec520..3f9cd45481f 100644 --- a/eframe/src/native/epi_integration.rs +++ b/eframe/src/native/epi_integration.rs @@ -1,3 +1,4 @@ +use crate::epi; use egui_winit::{native_pixels_per_point, WindowSettings}; pub fn points_to_size(points: egui::Vec2) -> winit::dpi::LogicalSize { @@ -136,7 +137,7 @@ pub fn handle_app_output( /// For loading/saving app state and/or egui memory to disk. pub fn create_storage(_app_name: &str) -> Option> { #[cfg(feature = "persistence")] - if let Some(storage) = epi::file_storage::FileStorage::from_app_name(_app_name) { + if let Some(storage) = super::file_storage::FileStorage::from_app_name(_app_name) { return Some(Box::new(storage)); } None @@ -158,7 +159,6 @@ pub struct EpiIntegration { impl EpiIntegration { pub fn new( - integration_name: &'static str, gl: std::rc::Rc, max_texture_side: usize, window: &winit::window::Window, @@ -172,7 +172,6 @@ impl EpiIntegration { let frame = epi::Frame { info: epi::IntegrationInfo { - name: integration_name, web_info: None, prefer_dark_mode, cpu_usage: None, diff --git a/epi/src/file_storage.rs b/eframe/src/native/file_storage.rs similarity index 82% rename from epi/src/file_storage.rs rename to eframe/src/native/file_storage.rs index 1c0af6cb9f9..29e86abf286 100644 --- a/epi/src/file_storage.rs +++ b/eframe/src/native/file_storage.rs @@ -114,27 +114,3 @@ where } } } - -// ---------------------------------------------------------------------------- - -/// Alternative to [`FileStorage`] -pub fn read_memory(ctx: &egui::Context, memory_file_path: impl AsRef) { - let memory: Option = read_ron(memory_file_path); - if let Some(memory) = memory { - *ctx.memory() = memory; - } -} - -/// Alternative to [`FileStorage`] -/// -/// # Errors -/// When failing to serialize or create the file. -pub fn write_memory( - ctx: &egui::Context, - memory_file_path: impl AsRef, -) -> Result<(), Box> { - let file = std::fs::File::create(memory_file_path)?; - let ron_config = Default::default(); - ron::ser::to_writer_pretty(file, &*ctx.memory(), ron_config)?; - Ok(()) -} diff --git a/eframe/src/native/mod.rs b/eframe/src/native/mod.rs index fb84f7628cc..bcb8ec2d81a 100644 --- a/eframe/src/native/mod.rs +++ b/eframe/src/native/mod.rs @@ -1,4 +1,8 @@ mod epi_integration; mod run; +/// File storage which can be used by native backends. +#[cfg(feature = "persistence")] +pub mod file_storage; + pub use run::run; diff --git a/eframe/src/native/run.rs b/eframe/src/native/run.rs index a746ffd5a31..984ea1bd112 100644 --- a/eframe/src/native/run.rs +++ b/eframe/src/native/run.rs @@ -1,4 +1,5 @@ use super::epi_integration; +use crate::epi; use egui_winit::winit; struct RequestRepaintEvent; @@ -50,7 +51,6 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi .unwrap_or_else(|error| panic!("some OpenGL error occurred {}\n", error)); let mut integration = epi_integration::EpiIntegration::new( - "egui_glow", gl.clone(), painter.max_texture_side(), gl_window.window(), diff --git a/egui_web/src/backend.rs b/eframe/src/web/backend.rs similarity index 96% rename from egui_web/src/backend.rs rename to eframe/src/web/backend.rs index 0644e4bf5bb..98004eb6c36 100644 --- a/egui_web/src/backend.rs +++ b/eframe/src/web/backend.rs @@ -1,4 +1,6 @@ -use crate::{glow_wrapping::WrappedGlowPainter, *}; +use super::{glow_wrapping::WrappedGlowPainter, *}; + +use crate::epi; use egui::TexturesDelta; pub use egui::{pos2, Color32}; @@ -131,7 +133,7 @@ pub struct AppRunner { app: Box, pub(crate) needs_repaint: std::sync::Arc, last_save_time: f64, - screen_reader: crate::screen_reader::ScreenReader, + screen_reader: super::screen_reader::ScreenReader, pub(crate) text_cursor_pos: Option, pub(crate) mutable_text_under_cursor: bool, textures_delta: TexturesDelta, @@ -141,11 +143,10 @@ impl AppRunner { pub fn new(canvas_id: &str, app_creator: epi::AppCreator) -> Result { let painter = WrappedGlowPainter::new(canvas_id).map_err(JsValue::from)?; - let prefer_dark_mode = crate::prefer_dark_mode(); + let prefer_dark_mode = super::prefer_dark_mode(); let frame = epi::Frame { info: epi::IntegrationInfo { - name: "egui_web", web_info: Some(epi::WebInfo { location: web_location(), }), @@ -310,7 +311,7 @@ impl AppRunner { set_cursor_icon(cursor_icon); if let Some(open) = open_url { - crate::open_url(&open.url, open.new_tab); + super::open_url(&open.url, open.new_tab); } #[cfg(web_sys_unstable_apis)] @@ -397,12 +398,12 @@ fn start_runner(app_runner: AppRunner) -> Result { panicked: Arc::new(AtomicBool::new(false)), }; - crate::events::install_canvas_events(&runner_container)?; - crate::events::install_document_events(&runner_container)?; + super::events::install_canvas_events(&runner_container)?; + super::events::install_document_events(&runner_container)?; text_agent::install_text_agent(&runner_container)?; - crate::events::repaint_every_ms(&runner_container, 1000)?; // just in case. TODO: make it a parameter + super::events::repaint_every_ms(&runner_container, 1000)?; // just in case. TODO: make it a parameter - crate::events::paint_and_schedule(&runner_container.runner, runner_container.panicked.clone())?; + super::events::paint_and_schedule(&runner_container.runner, runner_container.panicked.clone())?; // Disable all event handlers on panic std::panic::set_hook(Box::new({ diff --git a/egui_web/src/events.rs b/eframe/src/web/events.rs similarity index 99% rename from egui_web/src/events.rs rename to eframe/src/web/events.rs index 83cb91557b4..26e7fc34db8 100644 --- a/egui_web/src/events.rs +++ b/eframe/src/web/events.rs @@ -1,4 +1,4 @@ -use crate::*; +use super::*; use std::sync::atomic::{AtomicBool, Ordering}; pub fn paint_and_schedule( diff --git a/egui_web/src/glow_wrapping.rs b/eframe/src/web/glow_wrapping.rs similarity index 90% rename from egui_web/src/glow_wrapping.rs rename to eframe/src/web/glow_wrapping.rs index 80d6fab5ab9..a2333423728 100644 --- a/egui_web/src/glow_wrapping.rs +++ b/eframe/src/web/glow_wrapping.rs @@ -14,7 +14,7 @@ pub(crate) struct WrappedGlowPainter { impl WrappedGlowPainter { pub fn new(canvas_id: &str) -> Result { - let canvas = crate::canvas_element_or_die(canvas_id); + let canvas = super::canvas_element_or_die(canvas_id); let (gl, shader_prefix) = init_glow_context_from_canvas(&canvas)?; let gl = std::rc::Rc::new(gl); @@ -122,7 +122,7 @@ fn init_webgl1(canvas: &HtmlCanvasElement) -> Option<(glow::Context, &'static st .dyn_into::() .unwrap(); - let shader_prefix = if crate::webgl1_requires_brightening(&gl1_ctx) { + let shader_prefix = if super::webgl1_requires_brightening(&gl1_ctx) { tracing::debug!("Enabling webkitGTK brightening workaround."); "#define APPLY_BRIGHTENING_GAMMA" } else { @@ -156,14 +156,3 @@ trait DummyWebGLConstructor { fn from_webgl2_context(context: web_sys::WebGl2RenderingContext) -> Self; } - -#[cfg(not(target_arch = "wasm32"))] -impl DummyWebGLConstructor for glow::Context { - fn from_webgl1_context(_context: WebGlRenderingContext) -> Self { - panic!("you can't use egui_web(glow) on native") - } - - fn from_webgl2_context(_context: WebGl2RenderingContext) -> Self { - panic!("you can't use egui_web(glow) on native") - } -} diff --git a/egui_web/src/input.rs b/eframe/src/web/input.rs similarity index 99% rename from egui_web/src/input.rs rename to eframe/src/web/input.rs index 1cc652719d6..5d1b00cfb08 100644 --- a/egui_web/src/input.rs +++ b/eframe/src/web/input.rs @@ -1,4 +1,4 @@ -use crate::{canvas_element, canvas_origin, AppRunner}; +use super::{canvas_element, canvas_origin, AppRunner}; pub fn pos_from_mouse_event(canvas_id: &str, event: &web_sys::MouseEvent) -> egui::Pos2 { let canvas = canvas_element(canvas_id).unwrap(); diff --git a/egui_web/src/lib.rs b/eframe/src/web/mod.rs similarity index 94% rename from egui_web/src/lib.rs rename to eframe/src/web/mod.rs index 72c053788a6..1ba569a242c 100644 --- a/egui_web/src/lib.rs +++ b/eframe/src/web/mod.rs @@ -1,8 +1,4 @@ //! [`egui`] bindings for web apps (compiling to WASM). -//! -//! This library is an [`epi`] backend. -//! -//! If you are writing an app, you may want to look at [`eframe`](https://docs.rs/eframe) instead. #![allow(clippy::missing_errors_doc)] // So many `-> Result<_, JsValue>` @@ -18,17 +14,17 @@ pub use backend::*; pub use events::*; pub use storage::*; -use egui::mutex::{Mutex, MutexGuard}; -pub use wasm_bindgen; -pub use web_sys; +use std::collections::BTreeMap; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; -use input::*; +use egui::mutex::{Mutex, MutexGuard}; +use wasm_bindgen::prelude::*; use web_sys::EventTarget; -use std::collections::BTreeMap; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; -use wasm_bindgen::prelude::*; +use input::*; // ---------------------------------------------------------------------------- @@ -76,7 +72,7 @@ pub fn canvas_element(canvas_id: &str) -> Option { } pub fn canvas_element_or_die(canvas_id: &str) -> web_sys::HtmlCanvasElement { - crate::canvas_element(canvas_id) + canvas_element(canvas_id) .unwrap_or_else(|| panic!("Failed to find canvas with id '{}'", canvas_id)) } @@ -162,13 +158,6 @@ pub fn set_clipboard_text(s: &str) { } } -pub fn spawn_future(future: F) -where - F: std::future::Future + 'static, -{ - wasm_bindgen_futures::spawn_local(future); -} - fn cursor_web_name(cursor: egui::CursorIcon) -> &'static str { match cursor { egui::CursorIcon::Alias => "alias", @@ -250,7 +239,7 @@ pub(crate) fn webgl1_requires_brightening(gl: &web_sys::WebGlRenderingContext) - // but safari use same vendor and renderer // so exclude "Mac OS X" user-agent. let user_agent = web_sys::window().unwrap().navigator().user_agent().unwrap(); - !user_agent.contains("Mac OS X") && crate::is_safari_and_webkit_gtk(gl) + !user_agent.contains("Mac OS X") && is_safari_and_webkit_gtk(gl) } /// detecting Safari and `webkitGTK`. diff --git a/egui_web/src/screen_reader.rs b/eframe/src/web/screen_reader.rs similarity index 100% rename from egui_web/src/screen_reader.rs rename to eframe/src/web/screen_reader.rs diff --git a/egui_web/src/storage.rs b/eframe/src/web/storage.rs similarity index 92% rename from egui_web/src/storage.rs rename to eframe/src/web/storage.rs index 1b6cc1232bf..6a3d5279407 100644 --- a/egui_web/src/storage.rs +++ b/eframe/src/web/storage.rs @@ -10,10 +10,6 @@ pub fn local_storage_set(key: &str, value: &str) { local_storage().map(|storage| storage.set_item(key, value)); } -pub fn local_storage_remove(key: &str) { - local_storage().map(|storage| storage.remove_item(key)); -} - #[cfg(feature = "persistence")] pub fn load_memory(ctx: &egui::Context) { if let Some(memory_string) = local_storage_get("egui_memory_ron") { diff --git a/egui_web/src/text_agent.rs b/eframe/src/web/text_agent.rs similarity index 99% rename from egui_web/src/text_agent.rs rename to eframe/src/web/text_agent.rs index c73873549d5..b7b035c2667 100644 --- a/egui_web/src/text_agent.rs +++ b/eframe/src/web/text_agent.rs @@ -1,7 +1,7 @@ //! The text agent is an `` element used to trigger //! mobile keyboard and IME input. -use crate::{canvas_element, AppRunner, AppRunnerContainer}; +use super::{canvas_element, AppRunner, AppRunnerContainer}; use egui::mutex::MutexGuard; use std::cell::Cell; use std::rc::Rc; diff --git a/egui-winit/src/lib.rs b/egui-winit/src/lib.rs index db1aeea9e7f..47129ac2fe4 100644 --- a/egui-winit/src/lib.rs +++ b/egui-winit/src/lib.rs @@ -451,7 +451,7 @@ impl State { open_url, copied_text, events: _, // handled above - mutable_text_under_cursor: _, // only used in egui_web + mutable_text_under_cursor: _, // only used in eframe web text_cursor_pos, } = platform_output; diff --git a/egui/src/context.rs b/egui/src/context.rs index 559862160bf..e2609b4a86b 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -639,7 +639,7 @@ impl Context { /// Will become active at the start of the next frame. /// /// Note that this may be overwritten by input from the integration via [`RawInput::pixels_per_point`]. - /// For instance, when using `egui_web` the browsers native zoom level will always be used. + /// For instance, when using `eframe` on web, the browsers native zoom level will always be used. pub fn set_pixels_per_point(&self, pixels_per_point: f32) { if pixels_per_point != self.pixels_per_point() { self.request_repaint(); diff --git a/egui/src/data/input.rs b/egui/src/data/input.rs index 426f879c80f..c689179d3f5 100644 --- a/egui/src/data/input.rs +++ b/egui/src/data/input.rs @@ -131,7 +131,7 @@ impl RawInput { pub struct HoveredFile { /// Set by the `egui-winit` backend. pub path: Option, - /// With the `egui_web` backend, this is set to the mime-type of the file (if available). + /// With the `eframe` web backend, this is set to the mime-type of the file (if available). pub mime: String, } @@ -141,11 +141,11 @@ pub struct HoveredFile { pub struct DroppedFile { /// Set by the `egui-winit` backend. pub path: Option, - /// Name of the file. Set by the `egui_web` backend. + /// Name of the file. Set by the `eframe` web backend. pub name: String, - /// Set by the `egui_web` backend. + /// Set by the `eframe` web backend. pub last_modified: Option, - /// Set by the `egui_web` backend. + /// Set by the `eframe` web backend. pub bytes: Option>, } diff --git a/egui/src/data/output.rs b/egui/src/data/output.rs index 058fcb19f91..28bdd5272f1 100644 --- a/egui/src/data/output.rs +++ b/egui/src/data/output.rs @@ -67,7 +67,7 @@ pub struct PlatformOutput { pub events: Vec, /// Is there a mutable [`TextEdit`](crate::TextEdit) under the cursor? - /// Use by `egui_web` to show/hide mobile keyboard and IME agent. + /// Use by `eframe` web to show/hide mobile keyboard and IME agent. pub mutable_text_under_cursor: bool, /// Screen-space position of text edit cursor (used for IME). diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 4faec5c3ff8..5d043fb0f4f 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -306,7 +306,7 @@ impl InputState { /// ``` /// /// By far not all touch devices are supported, and the details depend on the `egui` - /// integration backend you are using. `egui_web` supports multi touch for most mobile + /// integration backend you are using. `eframe` web supports multi touch for most mobile /// devices, but not for a `Trackpad` on `MacOS`, for example. The backend has to be able to /// capture native touch events, but many browsers seem to pass such events only for touch /// _screens_, but not touch _pads._ diff --git a/egui/src/widgets/text_edit/builder.rs b/egui/src/widgets/text_edit/builder.rs index ae988ddac98..6110efd7514 100644 --- a/egui/src/widgets/text_edit/builder.rs +++ b/egui/src/widgets/text_edit/builder.rs @@ -404,9 +404,9 @@ impl<'t> TextEdit<'t> { }); let mut state = TextEditState::load(ui.ctx(), id).unwrap_or_default(); - // On touch screens (e.g. mobile in egui_web), should + // On touch screens (e.g. mobile in `eframe` web), should // dragging select text, or scroll the enclosing [`ScrollArea`] (if any)? - // Since currently copying selected text in not supported on `egui_web`, + // Since currently copying selected text in not supported on `eframe` web, // we prioritize touch-scrolling: let any_touches = ui.input().any_touches(); // separate line to avoid double-locking the same mutex let allow_drag_to_select = !any_touches || ui.memory().has_focus(id); @@ -595,7 +595,7 @@ impl<'t> TextEdit<'t> { } if interactive { - // egui_web uses `text_cursor_pos` when showing IME, + // eframe web uses `text_cursor_pos` when showing IME, // so only set it when text is editable and visible! ui.ctx().output().text_cursor_pos = Some(cursor_pos.left_top()); } diff --git a/egui_demo_app/src/backend_panel.rs b/egui_demo_app/src/backend_panel.rs index 3401417bb04..8ea7ea519d1 100644 --- a/egui_demo_app/src/backend_panel.rs +++ b/egui_demo_app/src/backend_panel.rs @@ -142,7 +142,11 @@ impl BackendPanel { ui.separator(); } - show_integration_name(ui, &frame.info()); + ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("egui running inside "); + ui.hyperlink_to("eframe", "https://github.com/emilk/egui/tree/master/eframe"); + }); if let Some(web_info) = &frame.info().web_info { ui.collapsing("Web info (location)", |ui| { @@ -150,7 +154,7 @@ impl BackendPanel { }); } - // For instance: `egui_web` sets `pixels_per_point` every frame to force + // For instance: `eframe` web sets `pixels_per_point` every frame to force // egui to use the same scale as the web zoom factor. let integration_controls_pixels_per_point = ui.input().raw.pixels_per_point.is_some(); if !integration_controls_pixels_per_point { @@ -234,27 +238,6 @@ impl BackendPanel { // ---------------------------------------------------------------------------- -fn show_integration_name(ui: &mut egui::Ui, integration_info: &eframe::IntegrationInfo) { - let name = integration_info.name; - ui.horizontal(|ui| { - ui.spacing_mut().item_spacing.x = 0.0; - ui.label("Integration: "); - match name { - "egui_glium" | "egui_glow" | "egui_web" => { - ui.hyperlink_to( - name, - format!("https://github.com/emilk/egui/tree/master/{}", name), - ); - } - name => { - ui.label(name); - } - } - }); -} - -// ---------------------------------------------------------------------------- - #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] struct EguiWindows { // egui stuff: diff --git a/egui_glow/README.md b/egui_glow/README.md index 5ce94213314..4662ae255d5 100644 --- a/egui_glow/README.md +++ b/egui_glow/README.md @@ -9,7 +9,7 @@ This crates provides bindings between [`egui`](https://github.com/emilk/egui) an * Render egui using glow on both native and web. * Write cross platform native egui apps (with the `winit` feature). -To write web apps using `glow` you should use either [`eframe`](https://github.com/emilk/egui/tree/master/eframe) or [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) (both uses `egui_glow` for rendering, by default). +To write web apps using `glow` you can use [`eframe`](https://github.com/emilk/egui/tree/master/eframe) (which uses `egui_glow` for rendering). To use on Linux, first run: diff --git a/egui_glow/src/lib.rs b/egui_glow/src/lib.rs index 1522efab75b..0106b6a36d1 100644 --- a/egui_glow/src/lib.rs +++ b/egui_glow/src/lib.rs @@ -85,6 +85,7 @@ pub fn check_for_gl_error_impl(gl: &glow::Context, file: &str, line: u32, contex macro_rules! profile_function { ($($arg: tt)*) => { #[cfg(feature = "puffin")] + #[cfg(not(target_arch = "wasm32"))] puffin::profile_function!($($arg)*); }; } @@ -94,6 +95,7 @@ pub(crate) use profile_function; macro_rules! profile_scope { ($($arg: tt)*) => { #[cfg(feature = "puffin")] + #[cfg(not(target_arch = "wasm32"))] puffin::profile_scope!($($arg)*); }; } diff --git a/egui_web/CHANGELOG.md b/egui_web/CHANGELOG.md index 5644cdb4263..675ab336f2a 100644 --- a/egui_web/CHANGELOG.md +++ b/egui_web/CHANGELOG.md @@ -1,13 +1,7 @@ -# Changelog for egui_web -All notable changes to the `egui_web` integration will be noted in this file. +# Legacy changelog for egui_web +Between versions 0.17 and 0.18, `egui_web` was absorbed into `eframe`. Most of this changelog was then merged into [the `eframe` changelog](../eframe/CHANGELOG.md). This changelog is now only kept for historical reasons. -## Unreleased -* egui code will no longer be called after panic ([#1306](https://github.com/emilk/egui/pull/1306)). -* Remove the "webgl" feature. `egui_web` now always use `glow` (which in turn wraps WebGL) ([#1356](https://github.com/emilk/egui/pull/1356)). -* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). -* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)). - ## 0.17.0 - 2022-02-22 * The default painter is now glow instead of WebGL ([#1020](https://github.com/emilk/egui/pull/1020)). diff --git a/egui_web/Cargo.toml b/egui_web/Cargo.toml deleted file mode 100644 index c9e547ea63b..00000000000 --- a/egui_web/Cargo.toml +++ /dev/null @@ -1,104 +0,0 @@ -[package] -name = "egui_web" -version = "0.17.0" -authors = ["Emil Ernerfeldt "] -description = "Bindings for compiling egui code to WASM for a web page" -license = "MIT OR Apache-2.0" -edition = "2021" -rust-version = "1.60" -homepage = "https://github.com/emilk/egui/tree/master/egui_web" -readme = "README.md" -repository = "https://github.com/emilk/egui/tree/master/egui_web" -categories = ["gui", "web-programming"] -keywords = ["wasm", "web", "egui", "gui", "gamedev"] -include = [ - "../LICENSE-APACHE", - "../LICENSE-MIT", - "**/*.rs", - "Cargo.toml", - "src/shader/*.glsl", -] - -[package.metadata.docs.rs] -all-features = true - -[lib] -crate-type = ["cdylib", "rlib"] - - -[features] -default = ["default_fonts"] - -# If set, egui will use `include_bytes!` to bundle some fonts. -# If you plan on specifying your own fonts you may disable this feature. -default_fonts = ["egui/default_fonts"] - -# enable persisting egui memory -persistence = ["egui/persistence", "ron", "serde"] - -# enable screen reader support (requires `ctx.options().screen_reader = true;`) -screen_reader = ["tts"] - - -[dependencies] -egui = { version = "0.17.0", path = "../egui", default-features = false, features = [ - "bytemuck", - "tracing", -] } -egui_glow = { version = "0.17.0", path = "../egui_glow", default-features = false } -epi = { version = "0.17.0", path = "../epi" } - -bytemuck = "1.7" -js-sys = "0.3" -percent-encoding = "2.1" -tracing = "0.1" -wasm-bindgen = "0.2" -wasm-bindgen-futures = "0.4" - -# Optional: -ron = { version = "0.7", optional = true } -serde = { version = "1", optional = true } -tts = { version = "0.20", optional = true } # feature screen_reader - -web-sys = { version = "0.3.52", features = [ - "BinaryType", - "Blob", - "Clipboard", - "ClipboardEvent", - "CompositionEvent", - "console", - "CssStyleDeclaration", - "DataTransfer", - "DataTransferItem", - "DataTransferItemList", - "Document", - "DomRect", - "DragEvent", - "Element", - "Event", - "EventListener", - "EventTarget", - "ExtSRgb", - "File", - "FileList", - "FocusEvent", - "HtmlCanvasElement", - "HtmlElement", - "HtmlInputElement", - "InputEvent", - "KeyboardEvent", - "Location", - "MediaQueryList", - "MouseEvent", - "Navigator", - "Performance", - "Storage", - "Touch", - "TouchEvent", - "TouchList", - "WebGl2RenderingContext", - "WebglDebugRendererInfo", - "WebGlRenderingContext", - "WheelEvent", - "Window", -] } diff --git a/egui_web/README.md b/egui_web/README.md index 2cca8c2c51c..34177e9e32b 100644 --- a/egui_web/README.md +++ b/egui_web/README.md @@ -1,29 +1 @@ -# egui_web - -[![Latest version](https://img.shields.io/crates/v/egui_web.svg)](https://crates.io/crates/egui_web) -[![Documentation](https://docs.rs/egui_web/badge.svg)](https://docs.rs/egui_web) -[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) -![MIT](https://img.shields.io/badge/license-MIT-blue.svg) -![Apache](https://img.shields.io/badge/license-Apache-blue.svg) - -This crates allows you to compile GUI code written with [egui](https://crates.io/crates/egui) to [WASM](https://en.wikipedia.org/wiki/WebAssembly) to run on a web page. - -[Run the web demo](https://www.egui.rs/#demo) to try it now. - -Check out [eframe_template](https://github.com/emilk/eframe_template) for an example of how to set it up. - -## Downsides with using egui on the web - -`egui_web` uses WebGL (via [`glow`](https://crates.io/crates/glow)) and WASM, and almost nothing else from the web tech stack. This has some benefits, but also produces some challenges and serious downsides. - -* Rendering: Getting pixel-perfect rendering right on the web is very difficult. -* Search: you cannot search an egui web page like you would a normal web page. -* Bringing up an on-screen keyboard on mobile: there is no JS function to do this, so `egui_web` fakes it by adding some invisible DOM elements. It doesn't always work. -* Mobile text editing is not as good as for a normal web app. -* Accessibility: There is an experimental screen reader for `egui_web`, but it has to be enabled explicitly. There is no JS function to ask "Does the user want a screen reader?" (and there should probably not be such a function, due to user tracking/integrity concerns). -* No integration with browser settings for colors and fonts. -* On Linux and Mac, Firefox will copy the WebGL render target from GPU, to CPU and then back again (https://bugzilla.mozilla.org/show_bug.cgi?id=1010527#c0), slowing down egui. - -In many ways, `egui_web` is trying to make the browser do something it wasn't designed to do (though there are many things browser vendors could do to improve how well libraries like egui work). - -The suggested use for `egui_web` are for web apps where performance and responsiveness are more important than accessibility and mobile text editing. +`egui_web` used to be a standalone crate, but has now been moved into [`eframe`](https://github.com/emilk/egui/tree/master/eframe). diff --git a/epi/Cargo.toml b/epi/Cargo.toml deleted file mode 100644 index 8c764fcc65b..00000000000 --- a/epi/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -name = "epi" -version = "0.17.0" -authors = ["Emil Ernerfeldt "] -description = "Backend-agnostic interface for writing apps using egui" -edition = "2021" -rust-version = "1.60" -homepage = "https://github.com/emilk/egui/tree/master/epi" -license = "MIT OR Apache-2.0" -readme = "README.md" -repository = "https://github.com/emilk/egui/tree/master/epi" -categories = ["gui", "game-development"] -keywords = ["egui", "gui", "gamedev"] -include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"] - -[package.metadata.docs.rs] -all-features = true - -[lib] - - -[features] -default = [] - -# Persist native window options and egui memory -persistence = ["directories-next", "ron", "serde", "egui/persistence"] - - -[dependencies] -egui = { version = "0.17.0", path = "../egui", default-features = false } -glow = "0.11" -tracing = "0.1" - -# Optional: -ron = { version = "0.7", optional = true } -serde = { version = "1", optional = true } - -# native: -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -directories-next = { version = "2", optional = true } diff --git a/epi/README.md b/epi/README.md deleted file mode 100644 index f4f66b9210a..00000000000 --- a/epi/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# `epi`: the [`egui`](https://github.com/emilk/egui) application programming interface - -[![Latest version](https://img.shields.io/crates/v/epi.svg)](https://crates.io/crates/epi) -[![Documentation](https://docs.rs/epi/badge.svg)](https://docs.rs/epi) -[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) -![MIT](https://img.shields.io/badge/license-MIT-blue.svg) -![Apache](https://img.shields.io/badge/license-Apache-blue.svg) - -`epi` is a backend-agnostic interface for writing apps using `egui` (a platform agnostic GUI library). - -This crate provides a common interface for programming an app using egui, which can then be easily plugged into [`eframe`](https://github.com/emilk/egui/tree/master/eframe) (which is a wrapper over [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web), [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) and [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow)). - -This crate is only for those that want to write an app that can be compiled both natively and for the web. diff --git a/sh/build_demo_web.sh b/sh/build_demo_web.sh index df490bef874..97cad2540e9 100755 --- a/sh/build_demo_web.sh +++ b/sh/build_demo_web.sh @@ -31,7 +31,7 @@ while test $# -gt 0; do esac done -# This is required to enable the web_sys clipboard API which egui_web uses +# This is required to enable the web_sys clipboard API which eframe web uses # https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html # https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html export RUSTFLAGS=--cfg=web_sys_unstable_apis diff --git a/sh/check.sh b/sh/check.sh index 5615b764414..37df816968f 100755 --- a/sh/check.sh +++ b/sh/check.sh @@ -17,8 +17,7 @@ cargo test --workspace --all-targets --all-features cargo test --workspace --doc # slow - checks all doc-tests cargo fmt --all -- --check -cargo doc -p emath -p epaint -p egui -p eframe -p epi -p egui_web -p egui-winit -p egui_glium -p egui_glow --lib --no-deps --all-features -cargo doc -p egui_web --target wasm32-unknown-unknown --lib --no-deps --all-features +cargo doc -p emath -p epaint -p egui -p eframe -p egui-winit -p egui_glium -p egui_glow --lib --no-deps --all-features cargo doc --document-private-items --no-deps --all-features (cd eframe && cargo check --no-default-features) @@ -28,13 +27,10 @@ cargo doc --document-private-items --no-deps --all-features (cd egui_extras && cargo check --no-default-features) (cd egui_glium && cargo check --no-default-features) (cd egui_glow && cargo check --no-default-features) -(cd egui_web && cargo check --no-default-features) (cd egui-winit && cargo check --no-default-features) (cd emath && cargo check --no-default-features) (cd epaint && cargo check --no-default-features --release) (cd epaint && cargo check --no-default-features) -(cd epi && cargo check --no-default-features) - (cd eframe && cargo check --all-features) (cd egui && cargo check --all-features) @@ -42,11 +38,9 @@ cargo doc --document-private-items --no-deps --all-features (cd egui_extras && cargo check --all-features) (cd egui_glium && cargo check --all-features) (cd egui_glow && cargo check --all-features) -(cd egui_web && cargo check --all-features) (cd egui-winit && cargo check --all-features) (cd emath && cargo check --all-features) (cd epaint && cargo check --all-features) -(cd epi && cargo check --all-features) ./sh/wasm_bindgen_check.sh diff --git a/sh/docs.sh b/sh/docs.sh index 6b7379f37ac..33a352f02be 100755 --- a/sh/docs.sh +++ b/sh/docs.sh @@ -3,7 +3,7 @@ set -eu script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) cd "$script_path/.." -cargo doc -p egui_web --target wasm32-unknown-unknown --lib --no-deps --all-features -cargo doc -p emath -p epaint -p egui -p eframe -p epi -p egui_web -p egui-winit -p egui_extras -p egui_glium -p egui_glow --lib --no-deps --all-features --open +cargo doc -p eframe --target wasm32-unknown-unknown --lib --no-deps --all-features +cargo doc -p emath -p epaint -p egui -p eframe -p egui-winit -p egui_extras -p egui_glium -p egui_glow --lib --no-deps --all-features --open # cargo watch -c -x 'doc -p emath -p epaint -p egui --lib --no-deps --all-features' diff --git a/sh/wasm_bindgen_check.sh b/sh/wasm_bindgen_check.sh index 920d5214736..a50947a2cae 100755 --- a/sh/wasm_bindgen_check.sh +++ b/sh/wasm_bindgen_check.sh @@ -6,7 +6,7 @@ cd "$script_path/.." CRATE_NAME="egui_demo_app" FEATURES="http,persistence,screen_reader" -# This is required to enable the web_sys clipboard API which egui_web uses +# This is required to enable the web_sys clipboard API which eframe web uses # https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html # https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html export RUSTFLAGS=--cfg=web_sys_unstable_apis