1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00
Commit Graph

311 Commits

Author SHA1 Message Date
Emil Ernerfeldt
2f6fe9c572 eframe: Replace Frame::update with fn logic and fn ui (#7775)
* Part of https://github.com/emilk/egui/issues/5113
* Part of https://github.com/emilk/egui/issues/3524

## What
This deprecates `eframe::App::update` and replaces it with two new
functions:

```rs
pub trait App {
	/// Called just before `ui`, and in the future this will
    /// also be called for background apps when needed.
	fn logic(&mut self, ctx: &egui::Context, frame: &mut Frame) { }
	
    /// Show your user interface to the user.
	fn ui(&mut self, ui: &mut egui::Ui, frame: &mut Frame);

	…
}
```

Similarly, `Context::run` is deprecated in favor of `Context::run_ui`.

`Plugin`s are now handed a `Ui` instead of just a `Context` in
`on_begin/end_frame`.

## TODO
…either in this PR or a later one
* [x] Deprecate `App::update`
* [x] Deprecate `Context::run`
* [x] Change plugins to get a `Ui`
* [x] Update kittest
* [x] Change viewports to get UI:s (`show_viewport_immediate` etc)
  - https://github.com/emilk/egui/pull/7779

## Later PRs
* [ ] Deprecate `Panel::show`
* [ ] Deprecate `CentralPanel::show`
* [ ] Deprecate `CentralPanel` ?
2025-12-16 17:05:50 +01:00
Emil Ernerfeldt
9487dc35ec Viewports: give the caller a Ui instead of Context (#7779)
* Part of https://github.com/emilk/egui/issues/3524

This is a breaking change, as it changes the how embedded viewports
work.
Before it was up to the user to display a `egui::Window` if they wanted.
Now egui creates an `egui::Window` for you, so you only need to add the
contents.

To signal this change in behavior, `ViewportClass::Embedded` is gone and
is now called `ViewportClass::EmbeddedWindow`.
2025-12-15 18:51:57 +01:00
Emil Ernerfeldt
bfaf1b44f2 Replace ui.ctx().foo with ui.foo in a few places (#7774)
Internal code cleanup after
* https://github.com/emilk/egui/pull/7770
2025-12-14 17:12:10 +01:00
Emil Ernerfeldt
bc48599f65 Rename Context::style to global_style; avoid confusion w/ Ui::style (#7772)
This is important after
* https://github.com/emilk/egui/pull/7770
2025-12-14 16:41:13 +01:00
valadaptive
609dd2d28e Replace ab_glyph with Skrifa + vello_cpu; enable font hinting (#7694)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes N/A
* [x] I have followed the instructions in the PR template

I'll probably come back to this and clean it up a bit. This PR
reimplements ab_glyph's functionality on top of Skrifa, a somewhat
lower-level font API that's being used in Chrome now.

Skrifa doesn't perform rasterization itself, so I'm using
[vello_cpu](https://github.com/linebender/vello) from the Linebender
project for rasterization. It's still in its early days, but I believe
it's already quite fast. It also supports color and gradient fills, so
color emoji support will be easier.

Skrifa also supports font hinting, which should make text look a bit
nicer / less blurry.

Here's the current ab_glyph rendering:

<img width="1592" height="1068" alt="image"
src="https://github.com/user-attachments/assets/2385b66e-23f8-4c6e-b8c2-ea90e0eea4e4"
/>

Here's Skrifa *without* hinting--it looks almost identical, but there
are some subpixel differences, probably due to rasterizer behavior:

<img width="1592" height="1068" alt="image"
src="https://github.com/user-attachments/assets/a815f3e9-65ac-4940-bc00-571177bef53d"
/>

Here's Skrifa  *with* hinting:

<img width="1592" height="1068" alt="image"
src="https://github.com/user-attachments/assets/d6cc0669-3537-4377-bba9-ed5ef09664db"
/>

Hinting does make the horizontal strokes look a bit bolder, which makes
me wonder once again about increasing the font weight from "light" to
"regular".

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-12-06 16:11:33 +01:00
Lucas Meurer
de907612b7 Enforce consistent snapshot updates (#7744)
* Closes https://github.com/emilk/egui/issues/7647


This collects SnapshotResults within the Harness and adds a check to
enforce snapshot results are merged in case multiple Harnesses are
constructed within a test.

This should make snapshot updates via kitdiff/accept_snapshots.sh way
more useful since it should now always update all snapshots instead of
only the first one per test.
2025-11-26 14:56:19 +01:00
Lucas Meurer
a19629ef4a Add kittest.toml config file (#7643)
* part of https://github.com/rerun-io/rerun/issues/10991

---------

Co-authored-by: lucasmerlin <8009393+lucasmerlin@users.noreply.github.com>
2025-11-25 14:51:18 +01:00
Emil Ernerfeldt
a624f37e2d Add Context::run_ui (#7736)
* Part of https://github.com/emilk/egui/issues/3524

Adds `Context::run_ui` as a convenience wrapper around `Context::run`.

This on the path to deprecate `run` and use a top-level `Ui` as the
entry-point for all of egui.
2025-11-25 08:52:16 +01:00
Emil Ernerfeldt
d5869bfeaf Remove some uses of top-level panels in our examples (#7729)
We're phasing out top-level panels (panels that use `Context` directly,
instead of being inside another `Ui`).
As a first step, stop using them in our demo library and application.

* Part of https://github.com/emilk/egui/issues/3524
2025-11-21 20:22:01 +01:00
Bruno Paré-Simard
5b6a0196f9 Add Panel to replace SidePanel and TopBottomPanel (#5659)
This combines `SidePanel` and `TopBottomPanel` into a single `Panel`.

The old types are still there as type aliases, but are deprecated.

`.min_width(…)` etc are now called `.min_size(…)` etc.

Again, the old names are still there, but deprecated.

(edited by @emilk)

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-11-18 15:46:01 +01:00
Emil Ernerfeldt
f74b7c7e79 Paint mouse cursor in kittest snapshot images (#7721)
Very simple triangle shape, but helps understand why a widget has a
hovered effect
2025-11-18 06:24:03 +01:00
Emil Ernerfeldt
dc0acd2dd1 clippy +nightly fix (#7723) 2025-11-17 05:10:43 +01:00
Emil Ernerfeldt
9a073d9399 Prevent widgets sometimes appearing to move relative to each other (#7710)
Sometimes when moving a window, having a tooltip attached to the mouse
pointer, or scrolling a `ScrollArea`, you would see this disturbing
effect:


![drift-bug](https://github.com/user-attachments/assets/013a5f49-ee02-417c-8441-1e1a0369e8bd)

This is caused by us rounding many visual elements (lines, rectangles,
text, …) to physical pixels in order to keep them sharp. If the
window/tooltip itself is not rounded to a physical pixel, then you can
get this behavior.

So from now on the position of all
areas/windows/tooltips/popups/ScrollArea gets rounded to the closes
pixel.

* Unlocked by https://github.com/emilk/egui/pull/7709
2025-11-13 10:52:46 +01:00
Emil Ernerfeldt
fa4cfec777 Change text color of selected text (#7691)
Selected text now gets the color of `visuals.selection.stroke.color`.
This means you can have inverted colors for selected text, like in the
new test:
<img width="154" height="46" alt="image"
src="https://github.com/user-attachments/assets/2666361d-d7e2-4d50-8e4d-2fcc128f1a81"
/>


It also means the color of selected text in labels matches that of the
text color of selected buttons.
2025-11-07 15:34:36 +01:00
Emil Ernerfeldt
92de16a88c Fix kerning snapshot test directory 2025-10-09 15:50:36 +02:00
Emil Ernerfeldt
d50287b83c Add taplo.toml for toml formatting (#7618) 2025-10-09 15:38:00 +02:00
Emil Ernerfeldt
47a437403f Use software texture filtering in kittest (#7602) 2025-10-08 16:24:02 +02:00
Emil Ernerfeldt
683214bfe8 Add kittest snapshot test of italics (#7603) 2025-10-07 17:22:31 +02:00
Emil Ernerfeldt
843ceea90c Use more workspace dependencies (#7596) 2025-10-07 15:07:16 +02:00
Ian Hobson
30277233ce Add support for the safe area on iOS (#7578)
This PR is a continuation of #4915 by @frederik-uni and @lucasmerlin
that introduces support for keeping egui content within the 'safe area'
on iOS (avoiding the notch / dynamic island / menu bar etc.), with the
following changes:

- `SafeArea` now wraps `MarginF32` and has been renamed to
`SafeAreaInsets` to clarify its purpose.
- `InputState::screen_rect` is now marked as deprecated in favour of
either `viewport_rect` (which contains the entire screen), or
`content_rect` (which is the viewport rect with the safe area insets
removed).
- I added some comments to the safe area insets logic pointing out the
[safe area API coming in winit
v0.31](https://github.com/rust-windowing/winit/issues/3910).

---------

Co-authored-by: frederik-uni <147479464+frederik-uni@users.noreply.github.com>
Co-authored-by: Lucas Meurer <hi@lucasmerlin.me>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-10-07 12:30:09 +02:00
Lucas Meurer
65249013c4 Fix stuck menu when submenu vanishes (#7589)
* Closes https://github.com/rerun-io/rerun/issues/11301

This fixes a bug where a menu could get stuck, not closing at all, when
the currently open submenu stops being shown.
I also added a way to reproduce this to the demo, as well as a test
ensuring that there is no race condition in the fix.
2025-10-07 10:16:35 +02:00
Emil Ernerfeldt
bd45406fad Use a lot more let-else (#7582) 2025-10-02 19:47:00 +02:00
Emil Ernerfeldt
603dba29e6 Add snapshot test for text spacing/kerning (#7545) 2025-09-16 13:30:28 +02:00
Alan Everett
b0c568a78e Add rotation gesture support for trackpad sources (#7453)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Co-authored-by: Lucas Meurer <hi@lucasmerlin.me>
2025-09-11 12:44:17 +02:00
Emil Ernerfeldt
72b9b9d750 Increase default text size from 12.5 to 13.0 (#7521) 2025-09-09 15:47:24 +02:00
Emil Ernerfeldt
c2912369ca Improve text demo: more fine control of letter spacing (#7520) 2025-09-09 09:35:25 +02:00
Emil Ernerfeldt
01ee23c1a0 Add Zoom Factor to options panel (#7517) 2025-09-08 18:27:28 +02:00
valadaptive
d5b0a6f446 More even text kerning (#7431)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-09-08 17:29:41 +02:00
Emil Ernerfeldt
aedd43c88f kittest: Add UPDATE_SNAPSHOTS=force (#7508)
This adds a new mode, `UPDATE_SNAPSHOTS=force`, which will lower the
threshold to zero, overwriting every image that is not _exactly_ the
same.

Most comparisons has a threshold because different GPUs render slightly
differently. However, setting that threshold accurately can be hard.

Sometimes a test will pass locally, but fail on CI. In those cases you
want to force an update of the failing test. You can use
`UPDATE_SNAPSHOTS=force` for that.

And sometimes a small change _should_ update all images, but the change
is so tiny that it falls under the threshold. Still, you want to make a
point of showing that these images have changes. You can use
`UPDATE_SNAPSHOTS=force` for that.
2025-09-05 16:45:36 +02:00
ozwaldorf
454af7aa6c fix: SubMenu should not display when ui is disabled (#7428)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

Adds a check for `ui.is_enabled()` when displaying the SubMenu items.
There were a few places the condition could be placed, but I figured
there was simplest. The inner button will already not be able to be
clicked due to ui being disabled.

cc @lucasmerlin 

* [x] I have followed the instructions in the PR template

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-08-24 14:43:31 +02:00
Emil Ernerfeldt
3024c39eaf Enable and fix some more clippy lints (#7426)
One can never have too many lints
2025-08-08 09:57:53 +02:00
Lucas Meurer
e8e99a0bb6 Fix manual Popup not closing (#7383)
Fixes manually created popups (via `Popup::new`) not closing, since
widget_clicked_elsewhere was always false.

This example would never close:

```rs
    let mut open = true;

    eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
        egui::CentralPanel::default().show(ctx, |ui| {
            let response = egui::Popup::new(
                Id::new("popup"),
                ctx.clone(),
                PopupAnchor::Position(Pos2::new(10.0, 10.0)),
                LayerId::new(Order::Foreground, Id::new("popup")),
            )
            .open(open)
            .show(|ui| {
                ui.label("This is a popup!");
                ui.label("You can put anything in here.");
            });

            if let Some(response) = response {
                if response.response.should_close() {
                    open = false;
                }
            }
        });
    })
```

I also noticed that the Color submenu in the popups example had a double
arrow (must have been broken in the atoms PR):

<img width="248" height="110" alt="Screenshot 2025-08-07 at 13 42 28"
src="https://github.com/user-attachments/assets/a4e0c267-ae71-4b2c-a1f0-f53f9662d026"
/>

Also fixed this in the PR.
2025-08-07 14:18:04 +02:00
Emil Ernerfeldt
36a4981f29 Enable clippy::iter_over_hash_type lint (#7421)
This helped discover a few things that _might_ have been buggy.
2025-08-06 13:55:53 +02:00
Emil Ernerfeldt
9478a6223b Rename egui::containers::menu::Bar to egui::MenuBar (#7327)
The old name is still there, just deprecated.
2025-07-10 10:33:48 +02:00
Lucas Meurer
9fd0ad36e0 Implement BitOr and BitOrAssign for Rect (#7319) 2025-07-09 15:29:51 +02:00
Emil Ernerfeldt
a7f14ca176 Deprecate Memory::popup API in favor of new Popup API (#7317)
* Closes  #7037
* Closes #7297

This deprecates all popup-related function in `Memory`, replacing them
with the new `egui::Popup`.

The new API is nicer in all ways, so we should encourage people to use
it.
2025-07-09 12:55:06 +02:00
Emil Ernerfeldt
f46926aaf1 Improve texture filtering by doing it in gamma space (#7311)
* Closes https://github.com/emilk/egui/pull/5839

This makes some transparent images look a lot nicer when blended:


![image](https://github.com/user-attachments/assets/7f370aaf-886a-423c-8391-c378849b63ca)

Cursive text will also look nicer.

This unfortunately changes the contract of what
`register_native_texture` expects

---------

Co-authored-by: Adrian Blumer <blumer.adrian@gmail.com>
2025-07-07 17:46:27 +02:00
Emil Ernerfeldt
dd1052108e Add snapshot test for image blending (#7309)
This adds a test that can be used to see the improvements made by this
PR (if any):
* https://github.com/emilk/egui/pull/5839
2025-07-07 13:58:22 +02:00
Emil Ernerfeldt
09596a5e7b egui_kittest: more ergonomic functions taking Impl Into<String> (#7307) 2025-07-07 13:50:53 +02:00
valadaptive
7ac137bfc1 Make the font atlas use a color image (#7298)
* [x] I have followed the instructions in the PR template

Splitting this out from the Parley work as requested. This removes
`FontImage` and makes the font atlas use a `ColorImage`. It converts
alpha to coverage at glyph-drawing time, not at delta-upload time.

This doesn't do much now, but will allow for color emoji rendering once
we start using Parley.

I've changed things around so that we pass in `text_alpha_to_coverage`
to the `Fonts` the same way we do with `pixels_per_point` and
`max_texture_side`, reusing the existing code to check if the setting
differs and recreating the font atlas if so. I'm not quite sure why this
wasn't done in the first place.

I've left `ImageData` as an enum for now, in case we want to add support
for more texture pixel formats in the future (which I personally think
would be worthwhile). If you'd like, I can just remove that enum
entirely.
2025-07-04 13:15:48 +02:00
Lucas Meurer
47a2bb10b0 Remove SelectableLabel (#7277)
* part of https://github.com/emilk/egui/issues/7264
* removes SelectableLabel (Use `Button::selectable` instead)
* updates `Ui::selectable_value/label` with IntoAtoms support

Had to make some changes to `Button` since the SelecatbleLabel had no
frame unless selected.
2025-07-03 16:34:47 +02:00
Nicolas
77df407f50 egui_kittest: add failed_pixel_count_threshold (#7092)
I thought about this - so we have two options here:
1. adding it to `SnapshotOptions` 
2. adding it to every function which I do not like as this would be a
huge breaking change

## Summary

This pull request introduces a new feature to the `SnapshotOptions`
struct in the `egui_kittest` crate, allowing users to specify a
permissible percentage of pixel differences (`diff_percentage`) before a
snapshot comparison is considered a failure. This feature provides more
flexibility in handling minor visual discrepancies during snapshot
testing.

### Additions to `SnapshotOptions`:

* Added a new field `diff_percentage` of type `Option<f64>` to the
`SnapshotOptions` struct. This field allows users to define a tolerance
for pixel differences, with a default value of `None` (interpreted as 0%
tolerance).
* Updated the `Default` implementation of `SnapshotOptions` to
initialize `diff_percentage` to `None`.

### Integration into snapshot comparison logic:

* Updated the `try_image_snapshot_options` function to handle the new
`diff_percentage` field. If a `diff_percentage` is specified, the
function calculates the percentage of differing pixels and allows the
snapshot to pass if the difference is within the specified tolerance.
[[1]](diffhunk://#diff-6f481b5866b82a4fe126b7df2e6c9669040c79d1d200d76b87f376de5dec5065R204)
[[2]](diffhunk://#diff-6f481b5866b82a4fe126b7df2e6c9669040c79d1d200d76b87f376de5dec5065R294-R301)

* Closes <https://github.com/emilk/egui/issues/5683>
* [x] I have followed the instructions in the PR template

---------

Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-07-03 14:23:15 +02:00
Emil Ernerfeldt
dc79998044 Improve text rendering in light mode (#7290)
This changes how we convert glyph coverage to alpha (and ultimately a
color), but only in light mode.

This is a bit of a hack, because it doesn't fix dark-on-light text in
_dark mode_ (if you have any), but for the common case this PR is a huge
improvement.

You can also tweak this yourself now using
`Visuals::text_alpha_from_coverage` or from the UI (bottom of the
image):


![image](https://github.com/user-attachments/assets/350210d4-c0bb-44b6-84cc-47c2e9d4b9f0)



## Before / After

![widget_gallery_light_x1](https://github.com/user-attachments/assets/21f5a2a0-6b4e-4985-b17f-cd1c7cc01b46)
![widget_gallery_light_x1](https://github.com/user-attachments/assets/5dfec04a-c81c-43ef-8d86-fc48ef7958f1)


## Black text Before/after
If you think the text above looks too weak, it's only because of the
default text color. Here's how it looks like with perfectly `#000000`
black text:


![image](https://github.com/user-attachments/assets/56a4a4f3-c431-4991-b941-a566a4ae94ed)
![Screenshot 2025-07-02 at 13 59
30](https://github.com/user-attachments/assets/df5a91ad-0bb8-4a0f-81a2-50852e7556c1)
2025-07-02 14:58:37 +02:00
Emil Ernerfeldt
8bedaf6e5b Add light-mode Widget Gallery screenshot test (#7288)
Part of some work to improve text rendering in light mode (again!)
2025-07-02 12:00:36 +02:00
Emil Ernerfeldt
0857527f1d Add Visuals::weak_text_alpha and weak_text_color (#7285)
* Closes https://github.com/emilk/egui/issues/7262

This also makes the default weak color slightly less weak in most cases.
2025-07-01 20:42:54 +02:00
Emil Ernerfeldt
9e021f78da Change ui.disable() to modify opacity (#7282)
* Closes https://github.com/emilk/egui/pull/6765


Branched off of https://github.com/emilk/egui/pull/6765 by @tye-exe.

I needed to branch off to update snapshot images

---------

Co-authored-by: tye-exe <tye@mailbox.org>
Co-authored-by: Tye <131195812+tye-exe@users.noreply.github.com>
2025-07-01 14:05:53 +02:00
Emil Ernerfeldt
b2995dcb83 Use Rust edition 2024 (#7280) 2025-06-30 14:01:57 +02:00
Emil Ernerfeldt
962c8e26a8 Update MSRV to 1.85 (#7279) 2025-06-30 13:43:27 +02:00
Lucas Meurer
0152a87519 Create custom egui_kittest::Node (#7138)
This adds a custom Node struct with proper support for egui types
(`Key`, `Modifiers`, `egui::Event`, `Rect`) instead of needing to use
the kittest / accesskit types.

I also changed the `click` function to do a proper mouse move / mouse
down instead of the accesskit click. Also added `accesskit_click` to
trigger the accesskit event. This resulted in some changed snapshots,
since the elements are now hovered.

Also renamed `press_key` to `key_press` for consistency with
`key_down/key_up`.

Also removed the Deref to the AccessKit Node, to make it clearer when to
expect egui and when to expect accesskit types.

* Closes #5705 
* [x] I have followed the instructions in the PR template
2025-06-17 12:17:38 +02:00
Patrick Marks
df2c16ef0a Add anchored text rotation method, and clarify related docs (#7130)
Add a helper method to perform rotation about a specified anchor.

* Closes #7051
2025-06-16 01:42:01 +02:00