Commit Graph

1643 Commits

Author SHA1 Message Date
MStarha f2ce6424f3
`ScrollArea` improvements for user configurability (#5443)
* Closes <https://github.com/emilk/egui/issues/5406>
* [x] I have followed the instructions in the PR template

The changes follow what is described in the issue with a couple changes:
- Scroll bars are not hidden when dragging is disabled, for that
`ScrollArea::scroll_bar_visibility()` has to be used, this is as not to
limit the user configurability by imposing a specific function. The user
might want to retain the scrollbars visibility to show the current
position.
- The input for mouse wheel scrolling is unchanged. When I inspected the
code initially I made a mistake in recognizing the source of scrolling.
Current implementation is in fact using
`InputState::smooth_scroll_delta` and not `PassState::scroll_delta`,
therefore it is possible to prevent scrolling by setting the
`InputState::smooth_scroll_delta` to zero before painting the
`ScrollArea`.

A simple demo is available at
https://github.com/MStarha/egui_scroll_area_test
2025-04-25 11:01:22 +02:00
Emil Ernerfeldt f9245954eb
Enable more clippy lints (#6853)
* Follows https://github.com/emilk/egui/pull/6848
2025-04-24 17:32:50 +02:00
TÖRÖK Attila fdb9aa282a
Raise MSRV to 1.84 (#6848)
Prerequisite of https://github.com/emilk/egui/pull/6744.
See: https://github.com/gfx-rs/wgpu/pull/7218,
https://github.com/gfx-rs/wgpu/pull/7425

Please be aware that Rust 1.84 enables some (more) WASM extensions by
default, and ships with an `std` built with them enabled:
https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features/
According to `rustc +1.84 --print=cfg --target wasm32-unknown-unknown`,
these are: `multivalue`, `mutable-globals`, `reference-types`, and
`sign-ext`.
(c.f. `rustc +1.84 --print=cfg --target wasm32-unknown-unknown -C
target-cpu=mvp` enabling none.)
For reference: https://webassembly.org/features/

----

If support is desired for ancient/esoteric browsers that don't have
these implemented, there are two ways to get around this:
- Target `wasm32v1-none` instead, but that's a `no-std` target, and I
suppose a lot of dependencies don't work that way (e.g.
https://github.com/gfx-rs/wgpu/issues/6826)
- Using the `-Ctarget-cpu=mvp` and `-Zbuild-std=panic_abort,std` flags,
and the `RUSTC_BOOTSTRAP=1` escape hatch to allow using the latter with
non-`nightly` toolchains - until
https://github.com/rust-lang/wg-cargo-std-aware is stabilized. (For
reference:
https://github.com/ruffle-rs/ruffle/pull/18528/files#diff-fb2896d189d77b35ace9a079c1ba9b55777d16e0f11ce79f776475a451b1825a)

I don't think either of these is particularly advantageous, so I suggest
just accepting that browsers will have to have some extensions
implemented to run `egui`.
2025-04-24 17:00:29 +02:00
Bennet Bleßmann 6f910f60e9
Protect against NaN in hit-test code (#6851)
* Closes <https://github.com/emilk/egui/issues/6756>
* [x] I have followed the instructions in the PR template
2025-04-24 14:50:34 +02:00
MStarha 69b9f0eede
Rework `TextEdit` arrow navigation to handle Unicode graphemes (#5812)
* [x] I have followed the instructions in the PR template

Previously, navigating text in `TextEdit` with Ctrl + left/right arrow
would jump inside words that contained combining characters (i.e.
diacritics). This PR introduces new dependency of `unicode-segmentation`
to handle grapheme encoding. The new implementation ignores whitespace
and other separators such as `-` (dash) between words, but respects `_`
(underscore).

---------

Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
2025-04-22 17:44:10 +02:00
rustbasic a0f072ab1e
Fix bug in pointer movement detection (#5329)
Fix: Popups do not appear in certain situations.

* Closes #5080
* Related #5107

The root cause is that `last_move_time` is not updated in certain
situations (slow situations?).
2025-04-22 12:00:22 +02:00
Sven Niederberger 61e883be25
Revert "Add `OutputCommand::SetPointerPosition` to set mouse position" (#5867)
Reverts emilk/egui#5776

I noticed that this is already a `ViewportCommand`. Sorry for not seeing
that earlier.
2025-04-22 11:52:20 +02:00
mitchmindtree cd318f0e55
feat: Add `Scene::drag_pan_buttons` option. Allows specifying which pointer buttons pan the scene by dragging. (#5892)
This adds an option for specifying the set of pointer buttons that can
be used to pan the scene via clicking and dragging.

The original behaviour where all buttons can pan the scene by default is
maintained.

Addresses part of #5891.

---

Edit: It looks like the failing test is unrelated and also appears on
master:
https://github.com/emilk/egui/actions/runs/14330259861/job/40164414607.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-04-22 11:42:24 +02:00
mkalte 114460c1de
Change popup memory to be per-viewport (#6753)
Starting with 77244cd4c5 the popup
open-state is cleaned up per memory pass.

This becomes problematic for implementations that share memory between
viewports (i.e. all of them, as far as i understand it), because each
viewport gets a context pass, and thus a memory pass, which cleans out
popup open state.

To illustrate my issue, i have modifed the multiple viewport example to
include a popup menu for the labels:
https://gist.github.com/mkalte666/4ecd6b658003df4c6d532ae2060c7595
(changes not included in this pr).

Then, when i try to use the popups, i get this: 


https://github.com/user-attachments/assets/7d04b872-5396-4823-bf30-824122925528

Immediate viewports just break popup handling in general, while deferred
viewports kinda work, or dont. In this example ill be honest, it kind of
still did, sometimes. In my more complex app with multiple viewports
(where i encountered this first) it also just broke - even when just
showing root and one nother. Probably to do with the order wgpu vs glow
draws the viewports? Im not sure. In any case:

This commit adds `Memory::popup` (now `Memory::popups`) to the
per-viewport state of memory, including viewport aware cleanup, and
adding it to the list of things cleaned if a viewport goes away.

This results in the expected behavior:



https://github.com/user-attachments/assets/fd1f74b7-d3b2-4edc-8dc4-2ad3cfa2160e

I will note that with this, changing focus does not cause a popup to be
closed, which is consistent with current behavior on a single app.

Hope this helps 

~Malte 

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [x] I have followed the instructions in the PR template
* [x] ~~I have run check.sh locally~~ CI on the fork, including checks,
went through.
2025-04-22 11:38:17 +02:00
Marek Bernat 009bfe5ada
Add a `Slider::update_while_editing(bool)` API (#5978)
* Closes #5976
* [x] I have followed the instructions in the PR template
- The `scripts/check.sh` fails in `cargo-deny` because of a security
vulnerability in `crossbeam-channel` but this is also present on
`master`.


https://github.com/user-attachments/assets/a964c968-bb76-4e56-88e1-d1e3d51a401a
2025-04-22 11:28:34 +02:00
Lucas Meurer 501905b60d
Add tests for layout and visuals of most egui widgets (#6752)
This is mostly in preparation for #5830 where I want to ensure that I
don't introduce any regressions
2025-04-16 18:58:58 +02:00
Christopher Cerne 0f1d6c2818
Support SVG Text Rendering in egui_extras (#5979)
**Added**
* Create `svg_text` feature flag to support text rendering & loading of
system fonts.

**Changed**
* Updates `resvg` to `0.45`.
* Adds `usvg::Options` field to the `SvgLoader` structure.
* Change function signatures to support passing `usvg::Options` to
downstream `load_svg_bytes_with_size`.

**Additional Info**
* I used this PR as a reference:
https://github.com/emilk/egui/pull/4659. @xNWP can you see if this
adequately resolves your concern from your original PR?
* Closes https://github.com/emilk/egui/issues/5977 (we may want to open
another issue for my other thoughts in this issue)
* Also, I would like to thank @xNWP and their original PR for being a
good reference for this one.
* [x] I have followed the instructions in the PR template
2025-04-14 11:13:17 +02:00
Lucas Meurer 7055141c18
Update failing snapshot tests (#5894)
For some reason the pipeline in https://github.com/emilk/egui/pull/5698
succeeded even though the snapshots should have been updated. This
updates the snapshots.
2025-04-09 12:11:46 +02:00
giuseppeferrari c6bd30642a
Avoid infinite extension of ColorTest inside a Window (#5698)
Current implementation of ColorTest infinitely expand horizontally at
each redraw if included in a Window.

The effect can be see replacing the Panel in the ColorTestApp::update
with a Window:
```
egui::CentralPanel::default().show(ctx, |ui| {
   egui::Window::new("Colors").vscroll(true).show(ctx, |ui| {
   if frame.is_web() {
      ui.label(
         "NOTE: Some old browsers stuck on WebGL1 without sRGB support will not pass the color test.",
      );
      ui.separator();
   }
   egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| {
      self.color_test.ui(ui);
   });
   self.color_test.ui(ui);
});
```

The cause is the is the _pixel_test_strokes_ function that, at each
redraw, tries to expand the target rectangle of 2.0 points in each
direction.
2025-04-08 11:38:13 +02:00
Aarni Koskela 36e007bd8c
Add overline option for Table rows (#5637)
* Closes no issue, I just needed this for an app and figured it could be
useful.
* [x] I have followed the instructions in the PR template

This PR adds an `overline` option for `egui_extras::TableRow`, which is
useful for visually grouping rows. The overline consumes no layout
space.

A screenshot of the demo app, showing every 7th row getting an overline.

<img width="704" alt="Screenshot 2025-01-25 at 14 40 08"
src="https://github.com/user-attachments/assets/9ccbee3d-296d-4afd-9290-c669e4ede1c0"
/>

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-04-08 11:36:43 +02:00
mitchmindtree 4445497546
`Scene`: Set transform layer before calling user content (#5884)
This changes the `Scene` behaviour to call `set_transform_layer` prior
to calling the user content fn, rather than after.

### Motivation

This provides a simple way for the user to access the `TSTransform` that
will be applied to the `Scene` within the user content function, e.g.

```rust
ui.ctx().layer_transform_to_global(ui.layer_id())
```

Previously getting the transform like this still kind of worked, but
resulted in the user content lagging behind the actual scene position by
a single frame, which looks a bit strange.

With this PR, the user content using the transform no longer lags by a
frame, and matches the scene's transform perfectly.

Accessing the `TSTransform` of the `Scene` within the user content
function is useful for the case where the user may want to instantiate
new `Ui` sublayers that also track the scene (by default, sublayers do
*not* apply the same transform as the scene, likely the cause of #5682).
With these changes, the user can have sublayers track the scene like so:

```rust
let scene_layer = ui.layer_id();
let sub_layer = egui::LayerId::new(scene_layer.order, self.id);
ui.ctx().set_sublayer(scene_layer, sub_layer);
let scene_transform = ui.ctx().layer_transform_to_global(scene_layer).unwrap();
ui.ctx().set_transform_layer(sub_layer, scene_transform);
```

### Tested with

- `egui_demo_app` scene example.
- Local `egui_graph` demo example.

---

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [x] I have followed the instructions in the PR template
2025-04-08 11:16:29 +02:00
kernelkind fe631ff9ea
Use `TextBuffer` for `layouter` in `TextEdit` instead of `&str` (#5712)
This change allows `layouter` to use the `TextBuffer` instead of `&str`
in the closure. It is necessary when layout decisions depend on more
than just the raw string content, such as metadata stored in the
concrete type implementing `TextBuffer`.

In [our use case](https://github.com/damus-io/notedeck/pull/723), we
needed this to support mention highlighting when a user selects a
mention. Since mentions can contain spaces, determining mention
boundaries from the `&str` alone is impossible. Instead, we use the
`TextBuffer` implementation to retrieve the correct bounds.

See the video below for a demonstration:


https://github.com/user-attachments/assets/3cba2906-5546-4b52-b728-1da9c56a83e1


# Breaking change

This PR introduces a breaking change to the `layouter` function in
`TextEdit`.

Previous API:
```rust
pub fn layouter(mut self, layouter: &'t mut dyn FnMut(&Ui, &str, f32) -> Arc<Galley>) -> Self
```

New API:
```rust
pub fn layouter(mut self, layouter: &'t mut dyn FnMut(&Ui, &dyn TextBuffer, f32) -> Arc<Galley>) -> Self
```


## Impact on Existing Code

• Any existing usage of `layouter` will **no longer compile**.
• Callers must update their closures to use `&dyn TextBuffer` instead of
`&str`.

## Migration Guide

Before:
```rust
let mut layouter = |ui: &Ui, text: &str, wrap_width: f32| {
    let layout_job = my_highlighter(text);
    layout_job.wrap.max_width = wrap_width;
    ui.fonts(|f| f.layout_job(layout_job))
};
```

After:
```rust
let mut layouter = |ui: &Ui, text: &dyn TextBuffer, wrap_width: f32| {
    let layout_job = my_highlighter(text.as_str());
    layout_job.wrap.max_width = wrap_width;
    ui.fonts(|f| f.layout_job(layout_job))
};
```

---

* There is not an issue for this change.
* [x]  I have followed the instructions in the PR template

Signed-off-by: kernelkind <kernelkind@gmail.com>
2025-04-06 18:45:20 +02:00
Lucas Meurer d78fc39386
Use lychee link checker instead of linkinator (#5868)
Seems like linkinator doesn't find any files:
https://github.com/emilk/egui/pull/5853#issuecomment-2765526298

This will check all links in .md files (except CHANGELOG.md) and in toml
files
2025-04-03 09:26:49 +02:00
Hubert Głuchowski 557bd56e19
Optimize editing long text by caching each paragraph (#5411)
## What
(written by @emilk)
When editing long text (thousands of line), egui would previously
re-layout the entire text on each edit. This could be slow.

With this PR, we instead split the text into paragraphs (split on `\n`)
and then cache each such paragraph. When editing text then, only the
changed paragraph needs to be laid out again.

Still, there is overhead from splitting the text, hashing each
paragraph, and then joining the results, so the runtime complexity is
still O(N).

In our benchmark, editing a 2000 line string goes from ~8ms to ~300 ms,
a speedup of ~25x.

In the future, we could also consider laying out each paragraph in
parallel, to speed up the initial layout of the text.

## Details
This is an ~~almost complete~~ implementation of the approach described
by emilk [in this
comment](<https://github.com/emilk/egui/issues/3086#issuecomment-1724205777>),
excluding CoW semantics for `LayoutJob` (but including them for `Row`).
It supersedes the previous unsuccessful attempt here:
https://github.com/emilk/egui/pull/4000.

Draft because:
- [X] ~~Currently individual rows will have `ends_with_newline` always
set to false.
This breaks selection with Ctrl+A (and probably many other things)~~
- [X] ~~The whole block for doing the splitting and merging should
probably become a function (I'll do that later).~~
- [X] ~~I haven't run the check script, the tests, and haven't made sure
all of the examples build (although I assume they probably don't rely on
Galley internals).~~
- [x] ~~Layout is sometimes incorrect (missing empty lines, wrapping
sometimes makes text overlap).~~
- A lot of text-related code had to be changed so this needs to be
properly tested to ensure no layout issues were introduced, especially
relating to the now row-relative coordinate system of `Row`s. Also this
requires that we're fine making these very breaking changes.

It does significantly improve the performance of rendering large blocks
of text (if they have many newlines), this is the test program I used to
test it (adapted from <https://github.com/emilk/egui/issues/3086>):
<details>
<summary>code</summary>

```rust
use eframe::egui::{self, CentralPanel, TextEdit};
use std::fmt::Write;

fn main() -> Result<(), eframe::Error> {
    let options = eframe::NativeOptions {
        ..Default::default()
    };

    eframe::run_native(
        "editor big file test",
        options,
        Box::new(|_cc| Ok(Box::<MyApp>::new(MyApp::new()))),
    )
}

struct MyApp {
    text: String,
}

impl MyApp {
    fn new() -> Self {
        let mut string = String::new();
        for line_bytes in (0..50000).map(|_| (0u8..50)) {
            for byte in line_bytes {
                write!(string, " {byte:02x}").unwrap();
            }
            write!(string, "\n").unwrap();
        }
        println!("total bytes: {}", string.len());
        MyApp { text: string }
    }
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        CentralPanel::default().show(ctx, |ui| {
            let start = std::time::Instant::now();
            egui::ScrollArea::vertical().show(ui, |ui| {
                let code_editor = TextEdit::multiline(&mut self.text)
                    .code_editor()
                    .desired_width(f32::INFINITY)
                    .desired_rows(40);
                let response = code_editor.show(ui).response;
                if response.changed() {
                    println!("total bytes now: {}", self.text.len());
                }
            });
            let end = std::time::Instant::now();
            let time_to_update = end - start;
            if time_to_update.as_secs_f32() > 0.5 {
                println!("Long update took {:.3}s", time_to_update.as_secs_f32())
            }
        });
    }
}
```
</details>

I think the way to proceed would be to make a new type, something like
`PositionedRow`, that would wrap an `Arc<Row>` but have a separate `pos`
~~and `ends_with_newline`~~ (that would mean `Row` only holds a `size`
instead of a `rect`). This type would of course have getters that would
allow you to easily get a `Rect` from it and probably a `Deref` to the
underlying `Row`.
~~I haven't done this yet because I wanted to get some opinions whether
this would be an acceptable API first.~~ This is now implemented, but of
course I'm still open to discussion about this approach and whether it's
what we want to do.

Breaking changes (currently):
- The `Galley::rows` field has a different type.
- There is now a `PlacedRow` wrapper for `Row`.
- `Row` now uses a coordinate system relative to itself instead of the
`Galley`.

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

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-04-01 18:55:39 +02:00
Emil Ernerfeldt e275409eb1
Fix: transform `TextShape` underline width (#5865)
Minor bug fix when transforming a `TextShape` with a `underline` (used
for e.g. hyperlinks). Before the underline width would not scale
properly; now it will.
2025-03-30 16:36:03 +02:00
Emil Ernerfeldt e3acd71090
Make text background rects pixel-sharp (#5864)
Small visual teak: make sure the background text color is pixel-aligned.
2025-03-30 16:21:00 +02:00
Hank Jordan 943e3618fc
Improve drag-to-select text (add margins) (#5797)
Might want to draw from `interaction.interact_radius` style instead of
hard-coding the margin, but I didn't want to create a breaking change.
If desired, I can follow up with a separate PR to address that concern.

* Closes <https://github.com/emilk/egui/issues/5796>
* [x] I have followed the instructions in the PR template
2025-03-30 14:03:19 +02:00
Timo von Hartz ab0f0b7b64
Rename `should_propagate_event` & add `should_prevent_default` (#5779)
* [x] I have followed the instructions in the PR template

Currently eframe [calls
`prevent_default()`](962c7c7516/crates/eframe/src/web/events.rs (L307-L369))
for all copy / paste events on the
[*document*](962c7c7516/crates/eframe/src/web/events.rs (L88)),
making embedding an egui application in a page (e.g. an react
application) hard (as all copy & paste functionality for other elements
on the page is broken by this).

I'm not sure what the motivation for this is, if any.

This commit / PR adds a callback (`should_prevent_default`), similar to
`should_propgate_event`, that an egui application can use to overwrite
this behavior. It defaults to returning `true` for all events, to keep
the existing behavior.

I call `should_prevent_default` in every place that
`should_propagate_event` is called (which is not all places that
`prevent_default` is called!). I'm not sure for the motivation of not
calling `should_propagate_event` everywhere that `stop_propagation` is
called, but I kept that behavior for the `should_prevent_default`
callback too.

Please let me know if I'm missing some existing functionality that would
allow me to do this, or if there's a reason that we don't want
applications to be able to customize this (i.e. if there's a reason to
always `prevent_default` for all copy / paste events on the whole
document)
2025-03-30 14:00:46 +02:00
Emil Ernerfeldt 83254718a3 Clean up strikethrough/underline code in epaint 2025-03-30 13:15:41 +02:00
Emil Ernerfeldt 7ea3f762b8
Make text underline and strikethrough pixel perfect crisp (#5857)
Small visual fix: pixel-align any text underline or strikethrough.
Before they could be often be blurry.
2025-03-28 20:37:38 +01:00
Lucas Meurer 884be3491d
Fix color picker button (#5847)
* related to #5832 
(I want to keep that open and actually update the button to use the new
popup, but this should be enough to fix it for now)
* [X] I have followed the instructions in the PR template
2025-03-25 14:38:51 +01:00
TPhoenix 5d6aaa239b
Fix typo in style.rs (#5845)
lien -> line

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [ x ] I have followed the instructions in the PR template
2025-03-25 14:19:23 +01:00
Nicolas 8b62fd9286
Fix Lint for debug-assert (#5846)
Fixes the current ci workflow error
2025-03-25 14:18:45 +01:00
Grayden ddf9d267fc
Fix in `Scene`: make `scene_rect` full size on reset (#5801)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

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

# Overview

This is a small change that supports draggable elements inside a
`Scene`.

When a Scene is initialized with a `Rect::Zero`, following the [example
in the
demo](https://github.com/emilk/egui/blob/master/crates/egui_demo_lib/src/demo/scene.rs#L15),
it will [automatically be reset to the `inner_rect` of the
UI](https://github.com/emilk/egui/blob/master/crates/egui/src/containers/scene.rs#L120-L123).

This centers the scene on the inner-rect contents, however the resulting
`scene_rect` doesn't fill the entire `outer_rect`. This probably isn't
an issue for most users of `Scene`.

However, I want to support draggable elements on a `Scene`, and to do
that I need to map the pointer-position in the window to the scene_rect
position.

As is, the example of draggable elements on Scene works after the user
has modified the scene rect in some way (zoom or pan), when `scene_rect`
is set to `to_global.inverse() * outer_rect`
([here](https://github.com/emilk/egui/blob/master/crates/egui/src/containers/scene.rs#L114-L118)).
Before a user modifies the scene rect, the pointer-position cannot be
reliably mapped to the scene_rect, since the scene_rect doesn't span the
entire window.

This PR just forces that translation to always run after the scene_rect
is reset to `inner_rect`. The practical result is that the scene_rect
will now always span the full outer_rect.

# Example

Here's a small app that demonstrates the functionality I'm trying to
support. I'm new to Egui so there may be better patterns for what I'm
trying to do, but if you run this against `main` and this branch you'll
notice the difference.

```rs
use eframe::egui::*;

/// Map coordinates from the src rect to the target rect
fn map_to_rect(position: Pos2, src_rect: Rect, dest_rect: Rect) -> Pos2 {
    let x = (position.x - src_rect.min.x) / (src_rect.max.x - src_rect.min.x)
        * (dest_rect.max.x - dest_rect.min.x)
        + dest_rect.min.x;
    let y = (position.y - src_rect.min.y) / (src_rect.max.y - src_rect.min.y)
        * (dest_rect.max.y - dest_rect.min.y)
        + dest_rect.min.y;
    Pos2::new(x, y)
}

pub fn draggable_scene_element(
    ui: &mut Ui,
    id: Id,
    position: &mut Rect,
    scene_rect: Rect,
    container_rect: Rect,
) -> Response {
    let is_being_dragged = ui.ctx().is_being_dragged(id);
    if is_being_dragged {
        let r = ui.put(*position, |ui: &mut Ui| ui.label("Draggable"));

        if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
            let pointer_pos = map_to_rect(pointer_pos, container_rect, scene_rect);
            let delta = pointer_pos.to_vec2() - position.center().to_vec2();
            *position = position.translate(delta);
        };
        r
    } else {
        let r = ui.put(*position, |ui: &mut Ui| ui.label("Draggable"));
        ui
            .interact(position.clone(), id, Sense::drag())
            .on_hover_cursor(CursorIcon::Grab);
        r
    }
}

struct MyApp {
    scene_rect: Rect,
    position: Rect,
}
impl MyApp {
    fn new() -> Self {
        Self {
            scene_rect: Rect::ZERO,
            position: Rect::from_min_size(Pos2::new(-50., -50.), Vec2::new(100., 100.)),
        }
    }
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
        CentralPanel::default().show(ctx, |ui| {
            let scene_rect = self.scene_rect.clone();
            let container_rect = ui.min_rect();
            Scene::default().show(ui, &mut self.scene_rect, |ui| {
                ui.put(
                    Rect::from_min_size(Pos2::new(100., 200.), Vec2::new(100., 100.)),
                    |ui: &mut Ui| ui.label("static element"),
                );
                ui.put(self.position, |ui: &mut Ui| {
                    draggable_scene_element(
                        ui,
                        Id::from("demo"),
                        &mut self.position,
                        scene_rect,
                        container_rect,
                    )
                });
            });
        });
    }
}
```

# Summary

I need a way to map pointer coordinates to scene coordinates, in order
to support draggable elements in a scene. This patch makes that easier
by ensuring the scene_rect will always be the full size of the
outer_rect.

If you have a better way to accomplish what I'm after, I'm happy to
close this. Thanks!
2025-03-25 10:26:07 +01:00
Nicolas 2024295f78
Make ImageLoader use background thread (#5394)
This is the same change as in #4069 but as this is stale I wanted to
reopen a non stale PR

Modifies ImageLoader's load function to use background threads for the
image decoding work. This avoids blocking the main thread that is
especially noticeable when loading many images at once.

This was modelled after the other loader implementations that also use
threads.

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

---------

Co-authored-by: lucasmerlin <lucasmeurer96@gmail.com>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-03-25 10:17:31 +01:00
Nicolas 58b2ac88c0
Add assert messages and print bad argument values in asserts (#5216)
Enabled the `missing_assert_message` lint

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

---------

Co-authored-by: Lucas Meurer <lucasmeurer96@gmail.com>
2025-03-25 09:20:29 +01:00
StratusFearMe21 390e0bfc1e
Fix text input on Android (#5759)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

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

This fixes an issue on android where keyboard input is not registered in
text boxes because `winit` does not fill in the `text` field of the
`KeyEvent`

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-03-21 14:35:46 +01:00
rustbasic 91f02f9e87
Enhance stability on Windows (#5723)
Dear emilk,

Programs built with egui on Windows are terminating every hour on
average.
When this commit is applied, it works fine for about 3 to 6 hours on
average.

I've been testing it for over 6 months and have submitted multiple PRs
since 6 months ago,
but they haven't applied it yet.

Thank you.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-03-21 14:32:37 +01:00
GiGaGon 668abc2838
Add `expand_bg` to customize size of text background (#5365)
This removes the `expand(1.0)` on text background colors, since it makes
translucent background colors have bad looking bleeding.

There is probably a smarter solution than disabling the highlighting
entirely, but I don't see a way to do that while keeping the area
consumed consistent between translucent/solid colors, or adding a decent
step up in complexity.

Since this makes it impossible to tell if selected text is highlighted,
this also adds a blanket `0.5` gamma multiply to the text selection
background color. If that is undesirable because it's a bad arbitrary
number choice, or if it's too much of an unexpected change and just the
default values should be changed, please let me know.

These changes cause the tests that use screenshots with highlighted text
to fail, though I am not sure how to update those tests to match the
changes.

<details>
<summary>Comparison Images</summary>

Current:


![image](https://github.com/user-attachments/assets/6dc85492-4f8e-4e7a-84b4-3ee10a48b8b3)

After changes:


![image](https://github.com/user-attachments/assets/9b35bbd3-159d-42a9-b22f-80febb707cfa)
 

</details>

<details>
<summary>Code used to make comparison images</summary>

```rs
fn color_text_format(ui: &Ui, color: Color32) -> TextFormat {
    TextFormat { font_id: FontId::monospace(ui.text_style_height(&egui::TextStyle::Monospace)), background: color, ..Default::default() }
}

fn color_sequence_galley(ui: &Ui, text: &str, colors: [Color32; 3]) -> Arc<Galley> {
    let mut layout_job = LayoutJob::default();
    for color in colors {
        layout_job.append(text, 0.0, color_text_format(ui, color));
    }
    ui.fonts(|f| f.layout_job(layout_job))
}

fn color_sequence_row(ui: &mut Ui, label_text: &str, text: &str, colors: [Color32; 3]) {
    ui.label(label_text);
    ui.label(color_sequence_galley(ui, text, colors));
    ui.end_row();
}

egui::Grid::new("comparison display").show(ui, |ui| {
    ui.ctx().set_pixels_per_point(2.0);
    let transparent = Color32::TRANSPARENT;
    let solid = Color32::RED;
    let solid_2 = Color32::GREEN;
    let translucent_1 = Color32::GRAY.gamma_multiply(0.5);
    let translucent_2 = Color32::GREEN.gamma_multiply(0.5);
    color_sequence_row(ui, "Transparent to Solid:", " ", [transparent, solid, transparent]);
    color_sequence_row(ui, "Translucent to Transparent:", " ", [transparent, translucent_1, transparent]);
    color_sequence_row(ui, "Solid to Transparent:", " ", [solid, solid_2, solid]);
    color_sequence_row(ui, "Solid to Solid:", " ", [solid, transparent, solid]);
    color_sequence_row(ui, "Solid to Translucent:", " ", [solid, translucent_1, solid]);
    color_sequence_row(ui, "Translucent to Translucent:", " ", [translucent_1, translucent_2, translucent_1]);
    
    color_sequence_row(ui, "Transparent to Solid:", "a", [transparent, solid, transparent]);
    color_sequence_row(ui, "Translucent to Transparent:", "a", [transparent, translucent_1, transparent]);
    color_sequence_row(ui, "Solid to Transparent:", "a", [solid, solid_2, solid]);
    color_sequence_row(ui, "Solid to Solid:", "a", [solid, transparent, solid]);
    color_sequence_row(ui, "Solid to Translucent:", "a", [solid, translucent_1, solid]);
    color_sequence_row(ui, "Translucent to Translucent:", "a", [translucent_1, translucent_2, translucent_1]);
})
```
</details>

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

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-03-21 13:45:34 +01:00
Emil Ernerfeldt 2058dcb881
Improve text sharpness (#5838)
This improves the sharpness of text slightly, thanks to
<https://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing.html> by
@hikogui (🙏 ).

The difference is very small, but in dark mode (bright text on dark
background) text is sometimes significantly sharper, and also slightly
brighter.

The difference in light mode (dark text on light background) is much
smaller (barely perceptable).

To compare the before/after I suggest you open both in new tabs, then
quickly change between them.

### Low-DPI
#### Before
![Code Editor
old](https://github.com/user-attachments/assets/e10a3cad-932f-48cd-b7d6-5bfe70954c5e)

#### After
![Code
Editor](https://github.com/user-attachments/assets/2e7383fe-8023-4425-91c8-93df3c22c0fe)

#### Before

![old-white](https://github.com/user-attachments/assets/51c41c59-e897-4831-857a-f3ffe17ce7d4)

#### After

![new-white](https://github.com/user-attachments/assets/4ac6f951-8c57-4bcc-a5d5-788cf52ea7d8)

### High-DPI
The difference is starkest on low-DPI screens (like the above
screenshots). On high-DPI screens, the difference is much smaller

#### Before
![widget_gallery
old](https://github.com/user-attachments/assets/f2149a30-aef8-4383-b48c-73d33a03ca02)

#### After

![widget_gallery](https://github.com/user-attachments/assets/c9ceb8be-8a32-490c-9364-2c6562b741f6)
2025-03-21 12:56:47 +01:00
Emil Ernerfeldt 3f731ec794
Fix semi-transparent colors appearing too bright (#5824)
The bug was in `Color32::from_rgba_unmultiplied` and by extension
affects:

* `Color32::from_rgba_unmultiplied`
* `hex_color!`
* `HexColor`
* `ColorImage::from_rgba_unmultiplied`
* All images with transparency (png, webp, …)
* `Color32::from_white_alpha`

The bug caused translucent colors to appear too bright.

## More
Color is hard.

When I started out egui I thought "linear space is objectively better,
for everything!" and then I've been slowly walking that back for various
reasons:

* sRGB textures not available everywhere
* gamma-space is more _perceptually_ even, so it makes sense to use for
anti-aliasing
* other applications do everything in gamma space, so that's what people
expect (this PR)

Similarly, pre-multiplied alpha _makes sense_ for blending colors. It
also enables additive colors, which is nice. But it does complicate
things. Especially when mixed with sRGB/gamma (As @karhu [points
out](https://github.com/emilk/egui/pull/5824#issuecomment-2738099254)).

## Related
* Closes https://github.com/emilk/egui/issues/5751
* Closes https://github.com/emilk/egui/issues/5771 ? (probably; hard to
tell without a repro)
* But not https://github.com/emilk/egui/issues/5810

## TODO
* [x] I broke the RGBA u8 color picker. Fix it

---------

Co-authored-by: Andreas Reich <andreas@rerun.io>
2025-03-21 10:45:25 +01:00
Jim d54e29d375
macOS: Add `movable_by_window_background` option to viewport (#5412)
Add an option called `movable_by_window_background` alongside a new
builder method. When set to true, the window is movable by dragging its
background ([Apple
Docs](https://developer.apple.com/documentation/appkit/nswindow/ismovablebywindowbackground))

This is exclusive to macOS systems, similar to `fullsize_content_view`.

* [x] I have followed the instructions in the PR template
2025-03-20 11:05:22 +01:00
StratusFearMe21 52732b23a6
impl AsRef<[u8]> for FontData (#5757)
* [x] I have followed the instructions in the PR template

This PR implements `AsRef<[u8]>` for `FontData`, allowing it to be
passed into `fontdb`'s
[`Source`](https://docs.rs/fontdb/0.16.2/fontdb/enum.Source.html) type.
This would allow `egui` and `cosmic_text` to share font data with
eachother
2025-03-20 11:03:17 +01:00
Nicolas Gomez 1545dec7a8
[egui_extra] Allow loading multi-mime formats using the image_loader (#5769)
Hi ! 

I'm using egui and egui_extra to build a demo tool for a crate I'm
building. In this crate I load favicons from a lot of websites, and I
have some failures on some .ico files. After tracking this thing down, I
guess there is two issues (kinda), in the image crate,
'image/vnd.microsoft.icon' isn't recognized as the valid mime for an ico
image (I created a [PR](https://github.com/image-rs/image/pull/2434)),
and the code to detect if a given mime type is compatible with the image
crate decoders in this crate do not support multi-mime type formats.


[ImageFormat::to_mime_type](85f2412d55/src/image.rs (L216C12-L216C24))
is only returning one mime for a given format (which is fine), we
compare the result of this method to guess if the format is
valid/enabled. Retriveing the correct format using
[ImageFormat::from_mime_type](85f2412d55/src/image.rs (L166))
would allow more mime to be considered valid since multiple mime can
match the same format.

The same applies to the extension detection, which I also modified to
stay consistent

Thanks
2025-03-20 11:02:24 +01:00
valadaptive d0bd525b5d
Bump accesskit to 0.18 and make it a workspace dependency (#5783)
This can't be merged until [kittest's accesskit is
bumped](https://github.com/rerun-io/kittest/pull/9) ~~and [a new version
of rfd is released](https://github.com/PolyMeilex/rfd/pull/240)~~.

---------

Co-authored-by: Lucas Meurer <lucasmeurer96@gmail.com>
2025-03-20 11:00:12 +01:00
Juan Campa 77244cd4c5
⚠️ Close popup if `Memory::keep_popup_open` isn't called (#5814)
Breaking changes:
- When using the Memory::popup state, it's now required to call
keep_popup_open each frame or the popup will close.
- Usually handled by the `Popup` struct, but required for custom popups
using the state in `Memory` directly

-----

If a popup is abandoned `Memory::popup` would remain `Some`. This is
problematic if, for example, you have logic that checks
`is_any_popup_open`.

This PR adds a new requirement for popups keeping their open state in
`Memory::popup`. They must call `Memory::keep_popup_open` as long as
they are being rendered. The recent changes in #5716 make this easy to
implement.

Supersedes #4697 which had an awkward implementation

These two videos show a case where a context menu was open when the
underlying widget got removed.

Before (`any_popup_open` remains `true`)
![Screenshot 2025-03-16 at 18 22
50](https://github.com/user-attachments/assets/22db64dd-e6f2-4501-9bda-39f470b9210c)

After
![Screenshot 2025-03-16 at 18 21
14](https://github.com/user-attachments/assets/bd4631b1-a0ad-4047-a14d-cd4999710e07)



* Closes https://github.com/emilk/egui/issues/3657
* [x] I have followed the instructions in the PR template
2025-03-20 10:51:42 +01:00
Sven Niederberger b0bbca4e69
Add `OutputCommand::SetPointerPosition` to set mouse position (#5776)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

This is not supported on the web and not yet on Wayland.

~~I also had to update `ring` and add an exception for `paste` being
unmaintained.~~ Has since been updated on master.

* [x] I have followed the instructions in the PR template
2025-03-20 10:51:02 +01:00
valadaptive 267485976b
Simplify the text cursor API (#5785)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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, but this is part of
https://github.com/emilk/egui/issues/3378
* [x] I have followed the instructions in the PR template

Other text layout libraries in Rust--namely, Parley and Cosmic
Text--have one canonical text cursor type (Parley's is a byte index,
Cosmic Text's also stores the line index). To prepare for migrating egui
to one of those libraries, it should also have only one text cursor
type. I also think simplifying the API is a good idea in and of
itself--having three different cursor types that you have to convert
between (and a `Cursor` struct which contains all three at once) is
confusing.

After a bit of experimentation, I found that the best cursor type to
coalesce around is `CCursor`. In the few places where we need a
paragraph index or row/column position, we can calculate them as
necessary.

I've removed `CursorRange` and `PCursorRange` (the latter appears to
have never been used), merging the functionality with `CCursorRange`. To
preserve the cursor position when navigating row-by-row, `CCursorRange`
now stores the previous horizontal position of the cursor.

I've also removed `PCursor`, and renamed `RowCursor` to `LayoutCursor`
(since it includes not only the row but the column). I have not renamed
either `CCursorRange` or `CCursor` as those names are used in a lot of
places, and I don't want to clutter this PR with a bunch of renames.
I'll leave it for a later PR.

Finally, I've removed the deprecated methods from `TextEditState`--it
made the refactoring easier, and it should be pretty easy to migrate to
the equivalent `TextCursorState` methods.

I'm not sure how many breaking changes people will actually encounter. A
lot of these APIs were technically public, but I don't think many were
useful. The `TextBuffer` trait now takes `&CCursorRange` instead of
`&CursorRange` in a couple of methods, and I renamed
`CCursorRange::sorted` to `CCursorRange::sorted_cursors` to match
`CursorRange`.

I did encounter a couple of apparent minor bugs when testing out text
cursor behavior, but I checked them against the current version of egui
and they're all pre-existing.
2025-03-20 10:49:38 +01:00
Trương Hoàng Long 6a8ee29a4e
Fix disabled `DragValue` eating focus, causing focus to reset (#5826)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 https://github.com/emilk/egui/issues/5507
* [x] I have followed the instructions in the PR template
2025-03-20 10:45:16 +01:00
MStarha f408ccafbc
Fix `DragValue` expansion when editing (#5809)
* [x] I have followed the instructions in the PR template

This PR fixes an issue, where `DragValue` would expand when it enters
editing state. There were 3 contributing problems:
- A workaround introduced in #4276 caused the `DragValue` to report
incorrect outer size.
- The `DragValue` uses `TextEdit` internally and sets both `min_size`
and `desired_width` to the same value - desired width is used **before**
padding is applied - this is in contrast to `Button` (also used
internally by `DragValue`), which only uses `min_size`. This caused the
`DragValue` to expand horizontally by the size of button padding.
- The height of the `TextEdit` is (among other things) determined by the
height of the row, which was not present in `Button`. This caused a
small vertical expansion, when the contents (including padding) were
larger than the `min_size`.


![egui_drag_value_expansion](https://github.com/user-attachments/assets/b6fe9bd8-5755-4a43-8b61-a7e5b24e678d)
Here the dimensions set in code are:
- padding: 20 x 20 pt
- interact size: 80 x 30 pt

*Note: I do not know what's up with the tests. When I ran the check
script, they were failing because of 3 UI missmatches, so I updated the
snapshots. Now, the updated snapshots cause the same failure in CI, that
appeared locally before the update. Now the locally run tests fail with
`The platform you're compiling for is not supported by winit` and couple
more following errors coming from the same source (`winit 0.30.7`).*
2025-03-20 10:40:22 +01:00
Lucas Meurer 93c06c3405
Add color picker menu item example (#5755)
* To be merged after #5756 



https://github.com/user-attachments/assets/ad40c172-cad2-4cc5-a3ef-3284b6545e94
2025-03-19 09:33:17 +01:00
Lucas Meurer a2afc8d092
Make `close_popup` take an `Id` and add `close_all_popups` (#5820)
Ooops, fixes a regression introduced in #5799

* [x] I have followed the instructions in the PR template
2025-03-18 15:32:14 +01:00
Markus Krause 1aced06e47
refactor mime type support detection in image loader to allow for deferred handling and appended encoding info (#5686)
as recommended by @lucasmerlin in #5679

* Closes #5679
* [x] I have followed the instructions in the PR template
2025-03-18 11:51:00 +01:00
Lucas Meurer 9604dae229
Fix kinetic scrolling on touch devices (#5778)
Fixes kinetic scrolling on android (and possibly other touch devices),
by calculating the final velocity before clearing the position history
on PointerGone events.

* Closes #5311 
* [X] I have followed the instructions in the PR template
2025-03-18 11:41:53 +01:00
Lucas Meurer 626cd9e227
Fix `Response::clicked_elsewhere` not returning true sometimes (#5798)
* Closes #5794
2025-03-18 11:40:33 +01:00
Lucas Meurer d3c1ac3798
Fix `context_menu` not closing when clicking widget (#5799)
The rerun timeline context menu wouldn't close when clicking outside,
this fixes it
2025-03-18 11:32:18 +01:00
Lucas Meurer cf756df14d
Clarify what happens when multiple modals are shown in the same frame (#5800)
* Closes #5788 
* [x] I have followed the instructions in the PR template
2025-03-18 11:30:32 +01:00
Lucas Meurer d698365dac
Fix the `StyleModifier` not being passed from popup to menu (#5805)
* [x] I have followed the instructions in the PR template
2025-03-18 11:29:20 +01:00
Sven Niederberger 024dc7b135
Add a toggle for the compact menu style (#5777)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

Menus currently have their own style that removes outlines and
backgrounds. This is nice if the menu only contains buttons. However if
the menu contains other widgets, e.g. a drag value, the style change
makes it quite difficult to identify such widgets. This is a simple way
to make this configurable.


* [x] I have followed the instructions in the PR template
2025-03-18 11:13:59 +01:00
Adrian Blumer eb7ca72534
Fix`TextEdit` selection when placed in a `Scene`. (#5791)
* Closes https://github.com/emilk/egui/issues/5789
* [x] I have followed the instructions in the PR template

While this change fixes the TextEdit specific issue, I'm worried that
the underlying problem is more fundamental and could show up in other
widgets, and I'm wondering if there's a more general solution?
2025-03-17 10:00:47 +01:00
lucasmerlin 962c7c7516
Deprecate `Ui::allocate_new_ui` in favor of `Ui::scope_builder` (#5764)
They had the same signature and slightly different implementations, now
it's streamlined
2025-03-05 12:08:43 +01:00
Gilberto Santos 1dea8fac9b
Fix scroll handle extending outside of `ScrollArea` (#5286)
* [x] I have followed the instructions in the PR template
* Closes https://github.com/emilk/egui/issues/3734

## Info

This PR addresses an issue where resizing a scroll handle can lead to
unwanted overlap.

It is also happening on the egui-demo.

![Screenshot 2024-10-18 at 17 35
25](https://github.com/user-attachments/assets/3a9527d9-fc46-4b25-b95a-9ba2fa54978e)

## Cause

*Note: The following explanation assumes a vertical scroll; however, the
logic applies equally to horizontal scrolling.*

When the scroll handle is positioned at the top or bottom of the scroll
area and the handle is resized to fit the minimum handle size, there is
a risk of overlap. This occurs if the handle’s new size extends beyond
the bounds of the scroll area.

## Proposed Solution

1. Check whether increasing the handle size will cause it to overlap
with the scroll area.
2. If an overlap is detected, adjust the handle’s center position by the
overlap amount, moving it towards the center of the scroll area.
2025-03-05 10:49:04 +01:00
Lucas Meurer 159ccb2fef Release 0.31.1 - text_edit and kittest fixes 2025-03-05 08:37:34 +01:00
lucasmerlin cd22517280
⚠️ Improved menu based on `egui::Popup` (#5716)
Continuation of #5713

**Silently breaking changes:**
- Menus now close on click by default, this is configurable via
`PopupCloseBehavior`

**Additional additions:**
- `Button::right_text`
- `StyleModifier`

This is a rewrite of the egui menus, with the following goals:
- submenu buttons should work everywhere, in a popup, context menu,
area, in some random Ui
- remove the menu state from Ui
- should work just like the previous menu
- ~proper support for keyboard navigation~
  - It's better now but requires further work to be perfect
- support `PopupCloseBehavior`

* Closes #4607 
* [x] I have followed the instructions in the PR template
2025-03-03 14:56:30 +01:00
lucasmerlin 6e3575b4c7
Add `typ` to known words (#5754)
This recently started to fail:
https://github.com/emilk/egui/actions/runs/13628559355/job/38091065444?pr=5706
2025-03-03 11:40:28 +01:00
IaVashik e995c4c5b4
Fix sizing bug in `TextEdit::singleline` (#5640)
This PR reverts a change introduced in PR
https://github.com/emilk/egui/pull/3660 that caused a regression with
`TextEdit::singleline`. The original PR attempted to fix an issue with
the cursor in `TextEdit` inside `ScrollArea`, but it did so by adding
unnecessary size allocation to `TextEdit`, which breaks the layout when
`TextEdit::singleline` is used outside of `ScrollArea`.


![Image](https://github.com/user-attachments/assets/78fdf20a-0763-4b5f-b83b-64522f15b35b)

The regression introduced by #3660 is more severe, as it completely
breaks the layout of applications using `TextEdit::singleline`, as shown
in the following issues:

*   Closes https://github.com/emilk/egui/issues/5500
*   Closes https://github.com/emilk/egui/issues/5597

Furthermore, I was unable to reproduce the original bug from PR #3660 in
the current version of egui using the following code:

```rust
impl eframe::App for MyEguiApp {
    fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
        ctx.set_debug_on_hover(true);
        egui::CentralPanel::default().show(ctx, |ui| {
            ScrollArea::vertical().max_height(100.0).show(ui, |ui| {
                ui.add(TextEdit::multiline(&mut self.text).hint_text("Enter text here..."))
            });
        });
    }
}
```

This code attempts to recreate the layout shown in the video from PR
#3660, using a `ScrollArea` with limited height and a `TextEdit` inside.
However, the cursor hiding issue was not reproducible.

![Video_2025-01-26_17-54-24](https://github.com/user-attachments/assets/ca4750ea-8af8-4ab5-8c10-bdf73a090362)

Therefore, I believe the code added in PR #3660 is no longer necessary
and only creates more problems.

*   Closes https://github.com/emilk/egui/issues/5500
*   Closes https://github.com/emilk/egui/issues/5597
*   [x] I have followed the instructions in the PR template
2025-03-03 09:22:01 +01:00
tyssyt 2428aeccbe
Use enum-map serde feature only when serde is enabled (#5748)
* [x] I have followed the instructions in the PR template
2025-02-27 15:50:45 +01:00
Jack Maguire 05141f8690
Fix typo in comment in `containers/scene.rs` (#5747)
There was a typo in one of the comments in the file, so I fixed it :).
2025-02-27 15:50:16 +01:00
Emil Ernerfeldt 42a88b677c Fix some clippy lints from the future 2025-02-25 14:10:42 +01:00
Emil Ernerfeldt 6a96612cb3
Mark all keys as up if the app loses focus (#5743)
In Rerun, pressing `Cmd+S` brings up a save dialog using `rfd`, but we
get not key-up event for the `S` key (in winit).
This leads to `S` being mistakenly marked as down when we switch back to
the app.

This PR takes the safe route and marks all keys as up when an egui app
loses focus.

* Tested with https://github.com/rerun-io/rerun/pull/9103
2025-02-25 14:05:35 +01:00
Brandon Li 27e7303ebe
Clarify platform-specific details for `Viewport` positioning (#5715)
On Wayland (and android apparently) it is not possible for applications
to position their windows or request the window position (for some
reason). This is not specified in the documentation.

proof: [`winit::set_outer_position`], [`winit::outer_position`],
[`winit::inner_position`] all specify that Android / Wayland are not
supported.

[`winit::set_outer_position`]:
https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_outer_position
[`winit::outer_position`]:
https://docs.rs/winit/latest/winit/window/struct.Window.html#method.outer_position
[`winit::inner_position`]:
https://docs.rs/winit/latest/winit/window/struct.Window.html#method.inner_position

* Maybe closes #4469
* the lack of support makes me sad. I believe this makes some items in
#3556 impossible on Wayland. Oh well!

---------

Co-authored-by: lucasmerlin <lucasmeurer96@gmail.com>
2025-02-20 19:32:34 +01:00
lucasmerlin f5b058b908
Add `Ui::close` and `Response::should_close` (#5729)
This adds a generic way of telling containers to close from their child
`Ui`s.

* Part of #5727 
* [x] I have followed the instructions in the PR template

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-02-20 17:59:29 +01:00
Onè 264749b8af
Fix typo in docstring for `Column::auto_size_this_frame` (#5681)
* [x] I have followed the instructions in the PR template
2025-02-18 18:11:48 +01:00
Piotr Podusowski 9dad7f827d
Align `available_rect` docs with the new reality after #4590 (#5701)
...as after #4590, `Window`/`Area` is not constrained within it.
2025-02-18 18:03:42 +01:00
Michael Grupp b48c7a164b
Implement `Default` for `ThemePreference` (#5702)
Convenient if you store it in an options struct in your app, want to
reset it, etc.

* ~Closes <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>~
* [x] I have followed the instructions in the PR template
2025-02-18 18:03:02 +01:00
Aiden 43261a5396
Add pointer events and focus handling for apps run in a Shadow DOM (#5627)
* [x] I have followed the instructions in the PR template

This PR handles pointer events and focus which did following changes:
- `element_from_point` and focus is now acquired from root node object
by using `get_root_node` from document or a shadow root.
- `TextAgent` is appended individually in each shadow root.

These changes handles pointer events and focus well in a web app that
are running in a shadow dom, or else the hover pointer actions and
keyboard input events are not triggered in a shadow dom.
Helpful for building embeddable/multi-view web-apps.
2025-02-18 18:01:07 +01:00
Bryce Berger 071e090e2b
add Label::show_tooltip_when_elided (#5710)
fixes #5708

Allows the user to disable the automatic tooltip when a Label is elided

* Closes <https://github.com/emilk/egui/issues/5708>
* [x] I have followed the instructions in the PR template
2025-02-18 17:33:27 +01:00
Braden Steffaniak 770c976ed7
Fix image_loader for animated image types (#5688)
Hi, after upgrading to 0.31.0 all of my beautiful static webp images
started failing to load. I use the image_loader to load those via the
`image` crate.

I noticed that with 0.31.0 there are additions to how animated image
types are handled with frames and such. And with those changes the frame
index is attached to the uri at the end. This was problematic for the
image_loader, because it wasn't updated to handle that frame tag at the
end of the uri, so when looking up the bytes, it would fail to match the
uri in the bytes cache (the bytes were being saved without the frame
index, but attempting to be fetched _with_ the frame index).

This fixes the image_loader for me with webp & gif. They don't load the
animations, but I think that is because I don't have the custom
image_loader set up so I'm not worried about that for myself. I'm not
sure if that part is problematic in general, or if its just the way I
have my features set up.

You can recreate the issue on master by swapping out the dependency
features in the `images` example like this:
```
# egui_extras = { workspace = true, features = ["default", "all_loaders"] }
# env_logger = { version = "0.10", default-features = false, features = [
#   "auto-color",
#   "humantime",
# ] }
# image = { workspace = true, features = ["jpeg", "png"] }
egui_extras = { workspace = true, features = ["image", "svg"] }
env_logger = { version = "0.10", default-features = false, features = [
  "auto-color",
  "humantime",
] }
image = { workspace = true, features = ["jpeg", "png", "webp", "gif"] }
```

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

---------

Co-authored-by: lucasmerlin <lucasmeurer96@gmail.com>
2025-02-18 17:30:50 +01:00
lucasmerlin a8e98d3f9b
Add `Popup` and `Tooltip`, unifying the previous behaviours (#5713)
This introduces new `Tooltip` and `Popup` structs that unify and extend
the old popups and tooltips.

`Popup` handles the positioning and optionally stores state on whether
the popup is open (for click based popups like `ComboBox`, menus,
context menus).
`Tooltip` is based on `Popup` and handles state of whether the tooltip
should be shown (which turns out to be quite complex to handles all the
edge cases).

Both `Popup` and `Tooltip` can easily be constructed from a `Response`
and then customized via builder methods.

This also introduces `PositionAlign`, for aligning something outside of
a `Rect` (in contrast to `Align2` for aligning inside a `Rect`). But I
don't like the name, any suggestions? Inspired by [mui's tooltip
positioning](https://mui.com/material-ui/react-tooltip/#positioned-tooltips).

* Part of #4607 
* [x] I have followed the instructions in the PR template

TODOs:
- [x] Automatic tooltip positioning based on available space
- [x] Review / fix / remove all code TODOs 
- [x] ~Update the helper fns on `Response` to be consistent in naming
and parameters (Some use tooltip, some hover_ui, some take &self, some
take self)~ actually, I think the naming and parameter make sense on
second thought
- [x] Make sure all old code is marked deprecated

For discussion during review:
- the following check in `show_tooltip_for` still necessary?:
```rust
     let is_touch_screen = ctx.input(|i| i.any_touches());
     let allow_placing_below = !is_touch_screen; // There is a finger below. TODO: Needed?
```
2025-02-18 15:53:07 +01:00
Nicolas 66c73b9cbf
Set hint_text in WidgetInfo (#5724)
The placeholder in kittest is currently not set for TextEdit Fields.
This resolves it 

* [x] I have followed the instructions in the PR template
2025-02-18 12:01:06 +01:00
Andreas Reich 40f002fe3f
Add guidelines for image comparison tests (#5714)
Guidelines & why images may differ

Based on (but slightly altered):
* https://github.com/rerun-io/rerun/pull/8989
2025-02-18 09:52:24 +01:00
lucasmerlin 08c5a641a1
Run a frame per queued event in egui_kittest (#5704)
This should fix the remaining problems with the modifiers
* [x] I have followed the instructions in the PR template
2025-02-12 14:20:50 +01:00
YgorSouza 982b2580f4
Enable all features for egui_kittest docs (#5711)
- Enable all-features when generating docs
- Add x11 feature so it builds on Linux
- Add double hashes to the feature comments so document-features
includes them in the docs

* Closes <https://github.com/emilk/egui/issues/5709>
* [x] I have followed the instructions in the PR template
2025-02-12 14:20:15 +01:00
lucasmerlin 510b3cdf48
Rename `Marginf` to `MarginF32` for consistency with `CornerRadiusF32` (#5677)
* [x] I have followed the instructions in the PR template
2025-02-11 11:23:59 +01:00
lucasmerlin 1c6e7b1bd0
Fix modifiers not working in kittest (#5693)
* Closes <https://github.com/emilk/egui/issues/5690>
* [x] I have followed the instructions in the PR template

It still isn't ideal, since you have to remember to call key_up on a
separate frame.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-02-10 09:33:36 +01:00
Emil Ernerfeldt 81806c4b86 Add badges to kittest README.md 2025-02-07 09:22:10 +01:00
Pēteris Pakalns 54d00d7d69
Fix panic when rendering thin textured rectangles (#5692)
* Closes https://github.com/emilk/egui/issues/5664
* [x] I have followed the instructions in the PR template
2025-02-06 21:37:32 +01:00
Emil Ernerfeldt 0db56dc9f1 Fix the magnification range of the tessellation test 2025-02-04 17:35:55 +01:00
Emil Ernerfeldt 985e569542 Fix warning 2025-02-04 17:04:29 +01:00
Lucas Meurer 5c372a7b36 Release 0.31.0 - Scene container, improved rendering quality 2025-02-04 16:47:56 +01:00
Emil Ernerfeldt 7ec1fbf467
Fix minor glitch in rendering of selected windows (#5678) 2025-02-04 16:05:36 +01:00
Emil Ernerfeldt c6bda9a38c
Make the ends of vline/hline sharper (#5676)
TL;DR: line caps are annoying in two ways:

A) we only add them for lines wider than a pixel
B) they always make the line longer (if added)
2025-02-04 15:31:51 +01:00
Emil Ernerfeldt c90b97f4ef
Fix sharp corners for rectangles with StrokeKind != Inside (#5675)
Oops!
2025-02-04 14:36:29 +01:00
lucasmerlin b8051cc301
Add `SnapshotResults` struct to egui_kittest (#5672)
I got annoyed by all the slightly different variations of "collect
snapshot results and unwrap them at the end of test" I've written, so I
added a struct to make this nice and simple.

One controversial thing: It panics when dropped. I wanted to ensure
people cannot forget to unwrap the results at the end, and this was the
best thing I could come up with. I don't think this is possible via
clippy lint or something like that.

* [x] I have followed the instructions in the PR template
2025-02-04 14:01:32 +01:00
Emil Ernerfeldt 23ed49334e
⚠️ Rename `Rounding` to `CornerRadius` (#5673)
Breaking change!

* `Rounding` -> `CornerRadius`
* `rounding` -> `corner_radius`

This is to:
* Clarify
* Conform to other systems (e.g. Figma)
* Avoid confusion with `GuiRounding`
2025-02-04 12:53:18 +01:00
Emil Ernerfeldt 3c07e01d08
Improve tessellation quality (#5669)
## Defining what `Rounding` is
This PR defines what `Rounding` means: it is the corner radius of
underlying `RectShape` rectangle. If you use `StrokeKind::Inside`, this
means the rounding is of the outer part of the stroke. Conversely, if
you use `StrokeKind::Outside`, the stroke is outside the rounded
rectangle, so the stroke has an inner radius or `rounding`, and an outer
radius that is larger by `stroke.width`.

This definitions is the same as Figma uses.

## Improving general shape rendering
The rendering of filled shapes (rectangles, circles, paths, bezier) has
been rewritten. Instead of first painting the fill with the stroke on
top, we now paint them as one single mesh with shared vertices at the
border. This has several benefits:

* Less work (faster and with fewer vertices produced)
* No overdraw (nicer rendering of translucent shapes)
* Correct blending of stroke and fill

The logic for rendering thin strokes has also been improved, so that the
width of a stroke of `StrokeKind::Outside` never affects the filled area
(this used to be wrong for thin strokes).

## Improving of rectangle rendering
Rectangles also has specific improvements in how thin rectangles are
painted.
The handling of "Blur width" is also a lot better, and now works for
rectangles with strokes.
There also used to be bugs with specific combinations of corner radius
and stroke width, that are now fixed.

##  But why?
With the new `egui::Scene` we end up with a lot of zoomed out shapes,
with sub-pixel strokes. These need to look good! One thing led to
another, and then I became obsessive 😅

## Tessellation Test
In order to investigate the rendering, I created a Tessellation Test in
the `egui_demo_lib`.

[Try it
here](https://egui-pr-preview.github.io/pr/5669-emilkimprove-tessellator)

![Screenshot 2025-02-04 at 08 45
50](https://github.com/user-attachments/assets/20b47a30-de6a-4ff5-885b-2e2fd6d88321)


![image](https://github.com/user-attachments/assets/e17c50eb-5ae7-48d4-bb0d-4f2165075897)
2025-02-04 11:30:12 +01:00
Juan Campa 9e1117019a
Add `Color32::CYAN` and `Color32::MAGENTA` (#5663)
I often find myself reaching out for these two colors so I figured I'd
just add the constants next to `YELLOW` to have CMYK
2025-02-04 10:29:26 +01:00
lucasmerlin bac8ea09ac
Add docs to `Frame::new` (#5670)
* [x] I have followed the instructions in the PR template
2025-02-04 10:17:15 +01:00
Michael Grupp 99369666ee
Fix typo in kittest docs (#5667)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>~
(just a quick typo fix)
* [x] I have followed the instructions in the PR template
2025-02-03 14:26:02 +01:00
Emil Ernerfeldt 50294b5d9f
Be smarter when rounding rectangles to the pixel grid (#5656) 2025-01-30 21:04:36 +01:00
Emil Ernerfeldt 4b9da5f650
Remove `StrokeKind::default` (#5658)
Since there is no natural default for `RectShape`.
2025-01-30 21:02:50 +01:00
Emil Ernerfeldt 04fca9c324
Remove date button from Scene demo, so as not to fail tests each day (#5657) 2025-01-30 20:51:12 +01:00
Emil Ernerfeldt ee5f0d6d52
eframe web: forward cmd-S/O to egui app (stop default browser action) (#5655)
This allow eframe apps to capture cmd-S and cmd-O to trigger their own
save and open actions, instead of having the browser do something
annoying.
2025-01-30 20:37:29 +01:00
Emil Ernerfeldt 8eda32ec64
egui_kittest: succeed and keep going when `UPDATE_SNAPSHOTS` is set (#5649)
It used to be that `UPDATE_SNAPSHOTS=true cargo test --all-features`
would stop on the first crate with a failure, requiring you to run it
multiple times, which is annoying, and a waste of time.
2025-01-30 09:34:22 +01:00
Emil Ernerfeldt 525d435a84
Require a `StrokeKind` when painting rectangles with strokes (#5648)
This is a breaking change, requiring users to think about wether the
stroke is inside/centered/outside the rect.

When in doubt, add `egui::StrokeKind::Inside` to the function call.
2025-01-29 15:52:49 +01:00
Emil Ernerfeldt 6be17136f2
`RectShape`: add control over where the stoke goes (#5647)
Adds `RectShape::stroke_kind` so you can select if the stroke goes
inside, outside, or is centered on the rectangle.

Also adds `RectShape::round_to_pixels` so you can override
`TessellationOptions::round_rects_to_pixels`.
2025-01-29 12:46:12 +01:00
Emil Ernerfeldt f86f62bb3d Improve deprecation text for `open_url/copied_text` 2025-01-29 08:44:13 +01:00
Jochen Görtler e8f351b729
Add `egui::Scene` for panning/zooming a `Ui` (#5505)
This is similar to `ScrollArea`, but:
* Supports zooming
* Has no scroll bars
* Has no limits on the scrolling

## TODO
* [x] Automatic sizing of `Scene`s outer bounds
* [x] Fix text selection in scenes
* [x] Implement `fit_rect`
* [x] Document / improve API

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-01-28 20:06:10 +01:00
Emil Ernerfeldt 37c564be2c Remove unnecessary profiling scope 2025-01-28 19:50:05 +01:00
Pandicon 93d2144294
Save state on suspend on Android and iOS (#5601)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

This pull request fixes a subset of #5492 by saving the application
state when the `suspended` event is received on Android. This way, even
if the user exits the app and closes it manually right after changing
some state, it will be saved since `suspended` gets fired when the app
is exited. It does not fix the `on_exit` function not being fired - this
seems to be a winit bug (the `exiting` function in the winit application
handler trait is not called on exit). Once it gets fixed, it may be
possible to remove logic introduced by this PR (however, I am not sure
how it would handle the app being killed by the system when in the
background, that would have to be tested).

I've tested the logic by:
* Leaving from the app to the home screen, then killing it from the
"recent apps" menu
 * Leaving from the app to the "recent apps" menu and killing it
 * Restarting the device while the app was running

In all of these instances, the state was saved (the last one being a
pleasant surprise). It was tested on the repository mentioned in #5492
with my forked repository as the source for eframe (I unfortunately am
not able to test it in a larger project of mine due to dependence on
"3rd party" egui libraries (like egui_notify) which do not compile along
with the master branch of eframe (different versions of egui), but I
believe it should work in the same manner in all scenarios). Tests were
conducted on a Galaxy Tab S8 running Android 14, One UI 6.1.1.

CI passed on my fork.

* [x] I have followed the instructions in the PR template
2025-01-27 08:14:49 +01:00
Emil Ernerfeldt bc5f908b80
Fix initial paint of web app (#5633)
* Broke in https://github.com/emilk/egui/pull/5631 (for _some_ apps)
2025-01-23 13:47:52 +01:00
Emil Ernerfeldt 6680e9c079
Web: Fix incorrect scale when moving to screen with new DPI (#5631)
* Closes https://github.com/emilk/egui/issues/5246

Tested on
* [x] Chromium
* [x] Firefox
* [x] Safari

On Chromium and Firefox we get one annoying frame with the wrong size,
which can mess up the layout of egui apps, but this PR is still a huge
improvement, and I don't want to spend more time on this right now.
2025-01-23 12:11:29 +01:00
Joshua Holmes 97bdb2851c
Remove references to glium (#5626)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

* Remove references to `glium` backend, because it is deprecated since
egui v0.18.0
* [x] I have followed the instructions in the PR template
2025-01-22 15:28:23 +01:00
n4n5 bdf7bfddd7
Add keys for `!`, `{`, `}` (#5548)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

* Help on https://github.com/emilk/egui/issues/3653 
* [x] I have followed the instructions in the PR template
2025-01-22 15:20:06 +01:00
Philippe Ombredanne e53bb53795
Update `egui_default_fonts` license (#5361)
Ubuntu-font-1.0 is now in SPDX

Reference: https://spdx.org/licenses/Ubuntu-font-1.0.html
Reference:
824163fa6f/src/licensedcode/data/licenses/ubuntu-font-1.0.LICENSE (L11)

Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
2025-01-22 15:16:50 +01:00
Mads Marquart a04e25af63
Prepare for `objc2` frameworks v0.3 (#5624)
The next version of the `objc2` framework crates will have a bunch of
default features enabled, see
https://github.com/madsmtm/objc2/issues/627, so this PR pre-emptively
disables them, so that your compile times down blow up once you upgrade
to the next version (which is yet to be released, but will be soon).

* [x] I have followed the instructions in the PR template
2025-01-22 15:13:34 +01:00
Emil Ernerfeldt 71f7bdc919
Implement `nohash_hasher::IsEnabled` for `Id` (#5628)
`egui:🆔:IdSet` and `egui:🆔:IdMap` were already optimized to not do
additional hashing (because the `Id` already is a hash), but now they
are just type aliases for `nohash_hasher::IntSet/IntMap`.

See https://crates.io/crates/nohash-hasher for more
2025-01-22 13:18:02 +01:00
Matthias Kronberg 493d5d0982
Fix hovering through custom menu button (#5555)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

This change discards widgets which are fully covered by another widget
in a higher layer from the hit test algorithm.

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

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-01-22 13:17:51 +01:00
Emil Ernerfeldt 5b740f97ac
Remove `egui::special_emojis::TWITTER` (#5622)
Twitter is gone, as is its icon.

Also, fuck Elon Musk

Find me on https://bsky.app/profile/ernerfeldt.bsky.social
2025-01-21 11:56:45 +01:00
Andreas Reich 30e66e4575
Wgpu resources are no longer wrapped in `Arc` (since they are now `Clone`) (#5612)
Co-authored-by: Nicolas <bircni@icloud.com>
2025-01-20 18:06:35 +01:00
TÖRÖK Attila a5d7cf5bd7
Upgrade to wgpu 24 (#5610) 2025-01-16 17:00:29 +01:00
Alix Bott 366900c550
implement Debug for RichText (#5596)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

* Derive Debug for RichText
* [x] I have followed the instructions in the PR template
2025-01-14 08:44:39 +01:00
Emil Ernerfeldt 164f56f554
Fix some clippy issues found by 1.84.0 (#5603) 2025-01-13 08:29:13 +01:00
Andreas Reich 1339639706
Fix Windows clippy issues (#5593)
These have been a lil bit annoying when running `cargo clippy
--all-features --all-targets` on windows
2025-01-11 18:05:57 +01:00
Andreas Reich f0d7c74e83
`response` module is now public, allowing access to `egui::response::Flags` (#5592) 2025-01-08 15:45:46 +01:00
Andreas Reich 443df84a22
Extend `WgpuSetup`, `egui_kittest` now prefers software rasterizers for testing (#5506) 2025-01-08 14:24:58 +01:00
lucasmerlin 7186f72cbe
Add a test for comboboxes (#5574)
* [x] I have followed the instructions in the PR template
2025-01-07 13:26:57 +01:00
Andrew Farkas 329c8f2fc1
Fix panic due to non-total ordering in `Area::compare_order()` (#5569)
[Area::compare_order()](ee4ab08c8a/crates/egui/src/memory/mod.rs (L1174-L1183))
is not a total ordering. If three layers A, B, and C have the same
`order` field but only A and B are present in `order_map`, then `A==C`
and `B==C` but `A!=C`. This can cause a panic in the stdlib sort
function, and does in [my
app](https://github.com/HactarCE/Hyperspeedcube/tree/v2.0) although it's
very difficult to reproduce.

* [x] I have self-reviewed this PR and run `./scripts/check.sh`
* [x] I have followed the instructions in the PR template
2025-01-07 08:37:23 +01:00
Aely 7cb8187ac8
Support RGB WebP images (#5586)
Current WebP loader assumes all WebP images to be RGBA, which is the
case if the image is animated (that's what `image` crate assumes at
least). Static images can instead choose to exclude its alpha channel,
though it seems to be more of a default choice to include it, even if
it's not being utilized. Currently, loading a static RGB WebP image will
cause a panic when `ColorImage::from_rgba_unmultiplied` gets called in
the loader
```
thread 'main' panicked at /home/aely/.cargo/git/checkouts/egui-226fc7cdd51201c1/f87219d/crates/epaint/src/image.rs:97:9:
assertion `left == right` failed
  left: 29184
 right: 21888
```
2025-01-07 08:35:58 +01:00
lucasmerlin 52060c0c41
Change `Harness::run` to run until no more repaints are requested (#5580)
Previously, `Harness::run` just called `Harness::step` 3 times. If that
wasn't enough, tests would often call run multiple times so all
animations would finish properly.

Also, I introduced `HarnessBuilder::with_step_dt` to customize with how
big of a dt each frame is called. I set the default to 1.0 / 6.0 (~6fps)
so we don't waste cpu in tests waiting on animations.

`HarnessBuilder::max_steps` allows us to control how many steps
`Harness::run` should run before panicing.
The default is 6, so we run for up to 1.0 logical seconds (six frames at
6 fps), which should be enough to finish most animations.

Turns out a lot of snapshots where rendered before fully shown and had a
light opacity, those are now fixed.

* [x] I have followed the instructions in the PR template
2025-01-07 08:33:44 +01:00
Pol Welter 35860418ac
Use bitfield instead of bools in `Response` and `Sense` (#5556)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 <https://github.com/emilk/egui/issues/3862>.

Factoring the `bool` members of `Response` into a bitfield, the size of
`Response` is now 96 bytes (down from 104).

I gave `Sense` the same treatment, however this has no effects on
`Response` due to padding. I've decided not to pursue `PointerState`, as
it is quite large (_many_ members that are sized and aligned to
multiples of 8 bytes), so I don't expect any noticeable benefit from
making handful of `bool`s slightly leaner.

In any case, the changes to `Sense` are already quite a bit more
intrusive than those to `Response`.
The previous implementation overloaded the names of the attributes
`click` and `drag` with similarly named methods that _construct_ `Sense`
with the corresponding flag set. Now, that the attributes can no longer
be accessed directly, I had to introduce methods with new names
(`senses_click()`, `senses_drag()` and `is_focusable()`). I don't think
this is the cleanest solution: the old methods are essentially redundant
now that the named constants like `Sense::CLICK` exist. I did however
not want to needlessly break backwards compatibility.
I am happy to revert it (or go further 🙂) if there are concerns.
2025-01-06 19:29:53 +01:00
Markus Ineichen 0fac8eadfc
Avoid allocations for loader cache lookup (#5584)
[ x ] I have ~~followed~~ _read_ the instructions in the PR template

Unfortunately i had several issues:
- Some snapshot-tests didn't run successfully on osx. diff shows errors
around fonts or missing menu items)
- cargo clippy doesn't run successfully (egui_kittest cannot find `wgpu`
and `image`)
- ./scripts/check.sh had other issues on my system (env: python: No such
file or directory), even if python3 can be called via python in my shell
 
Is there a system independent, standard way to run these tools (e.g. via
Docker?)
I submit the pr anyway, because there changes are very simple and
shouldn't cause issues.
2025-01-06 10:03:33 +01:00
Lander Brandt 9073516e30
Serialize window maximized state in `WindowSettings` (#5554)
A user of my Windows application reported a papercut where the
application restores its size on next load, but does not restore its
maximized state. This PR fixes that.

To test, I patched https://github.com/emilk/eframe_template to use my
local code since I knew that template saves/restores window data.
Testing methodology was to simply `cargo run`, maximize the application,
then close the application. `cargo run` again and the application should
start maximized.

Closes #1517.

* [x] I have followed the instructions in the PR template
* * This is mostly true, I had difficulties running `./scripts/check.sh`
for some reason. Possibly a bad Python version?
2025-01-06 09:19:17 +01:00
Emil Ernerfeldt 6607cd95f9
⚠️ `Frame` now includes stroke width as part of padding (#5575)
* Part of https://github.com/emilk/egui/issues/4019

`Frame` now includes the width of the stroke as part of its size. From
the new docs:

### `Frame` docs
The total (outer) size of a frame is `content_size + inner_margin +
2*stroke.width + outer_margin`.

Everything within the stroke is filled with the fill color (if any).

```text
+-----------------^-------------------------------------- -+
|                 | outer_margin                           |
|    +------------v----^------------------------------+    |
|    |                 | stroke width                 |    |
|    |    +------------v---^---------------------+    |    |
|    |    |                | inner_margin        |    |    |
|    |    |    +-----------v----------------+    |    |    |
|    |    |    |             ^              |    |    |    |
|    |    |    |             |              |    |    |    |
|    |    |    |<------ content_size ------>|    |    |    |
|    |    |    |             |              |    |    |    |
|    |    |    |             v              |    |    |    |
|    |    |    +------- content_rect -------+    |    |    |
|    |    |                                      |    |    |
|    |    +-------------fill_rect ---------------+    |    |
|    |                                                |    |
|    +----------------- widget_rect ------------------+    |
|                                                          |
+---------------------- outer_rect ------------------------+
```

The four rectangles, from inside to outside, are:
* `content_rect`: the rectangle that is made available to the inner
[`Ui`] or widget.
* `fill_rect`: the rectangle that is filled with the fill color (inside
the stroke, if any).
* `widget_rect`: is the interactive part of the widget (what sense
clicks etc).
* `outer_rect`: what is allocated in the outer [`Ui`], and is what is
returned by [`Response::rect`].

### Notes
This required rewriting a lot of the layout code for `egui::Window`,
which was a massive pain. But now the window margin and stroke width is
properly accounted for everywhere.
2025-01-04 10:29:22 +01:00
Emil Ernerfeldt 938d8b0d2e
egui_kittest: write `.old.png` files when updating images (#5578)
After running `UPDATE_SNAPSHOTS=1 cargo test --all-features` I want to
compare before/after images before committing them. Now I can!
2025-01-03 16:23:31 +01:00
Emil Ernerfeldt 7519ec7099 Fix: round animating collapsing header height to GUI 2025-01-03 14:54:57 +01:00
Emil Ernerfeldt 4784136fee
Better rounding of rectangles with thin outlines (#5571)
Better positioning of rectangle outline when the stroke width is less
than one pixel
2025-01-02 23:50:40 +01:00
lucasmerlin 46b58e5bcc
Add `Harness::new_eframe` and `TestRenderer` trait (#5539)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
2025-01-02 17:48:39 +01:00
Emil Ernerfeldt ee4ab08c8a
Shrink size of `Shadow` by using `i8/u8` instead of `f32` (#5568)
* Part of https://github.com/emilk/egui/issues/4019
2025-01-02 16:22:44 +01:00
Emil Ernerfeldt d58d13781d
Store `Margin` using `i8` to reduce its size (#5567)
Adds `Marginf` to fill the previous niche.

This is all in a pursuit to shrink the sizes of often-used structs, to
improve performance (less cache misses, less memcpy:s, etc).

* On the path towards https://github.com/emilk/egui/issues/4019
2025-01-02 16:05:52 +01:00
Emil Ernerfeldt aeea70d9e7
Add `epaint::Brush` for controlling `RectShape` texturing (#5565)
Also wraps `Shape::Mesh` in an `Arc`.

No new features, but decreases size of `Shape` from 72 bytes to 64.
2025-01-02 15:34:28 +01:00
Emil Ernerfeldt 64f077588c Improve kittest snapshot output: print absolute path to diff file 2025-01-02 14:56:27 +01:00
Emil Ernerfeldt cf7150c6a3
Refactor: put each shape into its own file (#5564)
Much easier to navigate the code
2025-01-02 14:55:49 +01:00
Emil Ernerfeldt 249f8bcb93
Use `u8` in `Rounding`, and introduce `Roundingf` (#5563)
* Part of https://github.com/emilk/egui/issues/4019

As part of the work on adding a custom `Border` to everything, I want to
make sure that the size of `RectShape`, `Frame` and the future `Border`
is kept small (for performance reasons).

This PR changes the storage of the corner radius of rectangles from four
`f32` (one for each corner) into four `u8`. This mean the corner radius
can only be an integer in the range 0-255 (in ui points). This should be
enough for most people.

If you want to manipulate rounding using `f32`, there is a new
`Roundingf` to fill that niche.
2025-01-02 14:29:50 +01:00
YgorSouza 3ffe1ed774
Re-enable IME support on Linux (#5198)
Reverts #5188 and adds a different fix to restore IME on Linux without
breaking the backspace and arrow keys.

* Closes https://github.com/emilk/egui/issues/5544
* Closes https://github.com/emilk/egui/pull/5198
* [x] I have followed the instructions in the PR template
2024-12-31 13:37:05 +01:00
lucasmerlin e32ca218e8
Add `WidgetType::Image` and `Image::alt_text` (#5534)
This adds `WidgetType::Image` and correctly sets it in the Image widget.
This allows us to query for images in kittest tests and tells accesskit
that a node is an image.
It also adds `Image::alt_text` to set a text that will be shown if the
image fails to load and will be read via screen readers. This also
allows us to query images by label in kittest.


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

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-12-30 12:53:46 +01:00
lucasmerlin 86ea3f8a5c
Fix cargo test --all-features breaking rendering due to unity vertexes (#5542)
* Closes #5297 
* [x] I have followed the instructions in the PR template

It's not great but I wasn't able to come up with a better solution.
2024-12-30 12:39:17 +01:00
Emil Ernerfeldt bf6ed3adfc
Add `Context::copy_image` (#5533)
* Closes https://github.com/emilk/egui/issues/5424

This adds support for copying images to the system clipboard on native
and on web using `Context::copy_image`.
2024-12-29 18:03:32 +01:00
Emil Ernerfeldt e2c7e9e733
Add `OutputCommand` for copying text and opening URL:s (#5532)
Add `OutputCommand` for copying text and opening URL:s

* Part of https://github.com/emilk/egui/issues/5424
* Adds `egui::OutputComm
* Part of https://github.com/emilk/egui/issues/5424and`
* Adds `PlatformOutput::commands`
* Deprecates `PlatformOutput::open_url`
* Deprecates `PlatformOutput::copied_text`
2024-12-29 11:59:51 +01:00
Aely 1e0f3a5e2d
Animated WebP support (#5470)
Adds support for animated WebP images. Used the already existing GIF
implementation as a template for most of it.

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

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-12-29 11:46:08 +01:00
Emil Ernerfeldt 01a7e31b13 Update test snapshot 2024-12-29 11:27:01 +01:00
Tom Maffia 13676ea35f
Fix minor typo 2024-12-29 11:25:51 +01:00
Emil Ernerfeldt 2356ae8819 Remove colons from widget gallery 2024-12-28 23:26:26 +01:00
Emil Ernerfeldt fa95351675
Slight improvements to the demo (#5527) 2024-12-28 22:11:41 +01:00
Ryan Bluth 8131b7b898
Make image extension lowercase before checking if it is supported (#5501)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

* Images with capitalized extensions do not load because the list of
extensions they are checked against is lowercase. The image extension is
now converted to lowercase before comparing
* [x ] I have followed the instructions in the PR template
2024-12-28 16:01:30 +01:00
Emil Ernerfeldt c37125f835
Tweak window resize handles (#5524)
This makes it easier to hit the corners.
Previously the corner response-area was covered by the response-areas of
the edges.

* Related to https://github.com/emilk/egui/pull/5523
2024-12-27 15:50:34 +01:00
Emil Ernerfeldt 4d945f78ba
Fix widgets sometimes being incorrectly marked as hovered (#5523)
An interactive widget should only be marked hovered if a click/drag
would start an interaction with it.

egui 0.30 introduced a feature where a thin interactive widget could be
hit even if it was partially behind a larger interactive widget.
Unfortunately, this introduced a bug where the top widget would still be
marked as hovered, even though a click would go through to the thin
widget below.

This bug was most notacible when trying to reisize a window by dragging
its corner, which often would result in dragging one of its sides
instead.

This PR fixes this bug.
2024-12-27 14:47:18 +01:00
Emil Ernerfeldt d20f93e9bf
Make all lines and rectangles crisp (#5518)
* Merge this first: https://github.com/emilk/egui/pull/5517

This aligns all rectangles and (horizontal or vertical) line segments to
the physical pixel grid in the `epaint::Tessellator`, making these
shapes appear crisp everywhere.

* Closes https://github.com/emilk/egui/issues/5164
* Closes https://github.com/emilk/egui/issues/3667

This undoes a lot of the explicit, egui-side aligning added in:
* https://github.com/emilk/egui/pull/4943

The new approach has several benefits over the old one:

* It is done automatically by epaint, so it is applied to everything (no
longer opt-in)
* It is applied after any layer transforms (so it always works)
* It makes line segments crisper on high-DPI screens
* All filled rectangles now has sides that end on pixel boundaries
2024-12-26 21:02:27 +01:00
Emil Ernerfeldt dfcc679d5a
Round widget coordinates to even multiple of 1/32 (#5517)
* Closes https://github.com/emilk/egui/pull/5197
* Closes https://github.com/emilk/egui/issues/5163

This should help prevent rounding errors in layout code.

@lucasmerlin you may wanna test this with `egui_flex`
2024-12-26 20:54:24 +01:00
Jochen Görtler 7f711668b4
Provide better `debug_assert`s for ray intersections (#5504)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

Title. This would have helped me debug bugs quicker.

* [x] I have followed the instructions in the PR template
2024-12-19 13:39:14 +01:00
Onè 27a5803dd3
docs: remove "a" (#5499)
Was a duplicate article in the sentence. Already has "the"

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [ ] I have followed the instructions in the PR template
2024-12-17 18:29:41 +01:00
Emil Ernerfeldt cfc341fabd
Revert "Revert "forward x11 and wayland features to glutin" (#5391)" (#5490)
* https://github.com/emilk/egui/pull/5391
* https://github.com/emilk/egui/pull/5488
* https://github.com/emilk/egui/pull/5490
2024-12-17 09:36:03 +01:00
Emil Ernerfeldt adfc0bebfc
Revert "forward x11 and wayland features to glutin" (#5391) (#5488)
* Reverts https://github.com/emilk/egui/pull/5391

Because it causes head-ache:
https://github.com/emilk/eframe_template/actions/runs/12357896151/job/34487194281
2024-12-16 19:25:21 +01:00
Emil Ernerfeldt 629f64551a Remove cyclic dependency of egui_demo_lib on itself 2024-12-16 18:10:01 +01:00
Emil Ernerfeldt 5b2b8cfb34 Remove cylic dependency of egui_kittest on itself 2024-12-16 18:10:01 +01:00
Emil Ernerfeldt eb403655ce Move egui tests to avoid cyclic dependency 2024-12-16 18:10:01 +01:00
lucasmerlin 69dbb00087
Simplify kittest readme example (#5486)
Updates the example using the new_ui function, and call fit_contents
- [x] I have followed the instructions in the PR template
2024-12-16 18:02:21 +01:00
Emil Ernerfeldt 320377e3ca
Release 0.30 - egui_kittest and modals (#5487) 2024-12-16 17:45:35 +01:00
Emil Ernerfeldt 045ed41efc
Fix zero-width strokes still affecting the feathering color of boxes (#5485) 2024-12-16 16:54:18 +01:00
Emil Ernerfeldt e8029178b6
Reduce aliasing when painting thin box outlines (#5484)
* Part of https://github.com/emilk/egui/issues/5164
2024-12-16 16:28:15 +01:00
Emil Ernerfeldt 450c6242e4 Improve error message in ColorImage::region 2024-12-16 15:14:50 +01:00
Emil Ernerfeldt 0823a36952
Fix: ui.new_child should now respect 'disabled' (#5483)
* Closes https://github.com/emilk/egui/issues/5475
2024-12-16 15:07:14 +01:00
Andreas Reich b1d2551e7e
Make frame delay on screenshots consistently one frame on web as well (#5482)
Native is already delayed by a frame because it calls
`handle_viewport_output` -> `egui_winit::process_viewport_commands`
after drawing. On web however, we process input including viewport
commands separately from drawing.
This adds an arbitrary frame delay mechanism for web and then uses this
with 1 frame delay always
2024-12-16 15:03:01 +01:00
Emil Ernerfeldt 3995491212
Revert "Workaround for egui having wrong scale in firefox" (#5481)
* Reverts emilk/egui#5466

Restores pixel-perfect rendering on chromium, Mac
2024-12-16 14:41:02 +01:00
Emil Ernerfeldt f0ec2f05c4
Fix broken images on egui.rs (move from git lfs to normal git) (#5480)
The images in the widget gallery on egui.rs are broken:

![image](https://github.com/user-attachments/assets/305e1041-e3e3-472d-9a52-1b90e8da053d)

~Not sure why yet, and I fail to reproduce locally.~
It's because they are on git lfs.
2024-12-16 14:16:54 +01:00
lucasmerlin 3bdb19e864
Workaround for egui having wrong scale in firefox (#5466)
* [x] I have followed the instructions in the PR template
2024-12-16 11:38:08 +01:00
Emil Ernerfeldt f7efb2186d
Improve hit-test of thin widgets, and widgets across layers (#5468)
When there are multiple layers (e.g. with custom transforms) close to
each other, the hit test code used to only consider widgets in the layer
directly under the mouse. This can make it difficult to hit thin widgets
just on the outside of a transform layer.

This PR fixes that.

It also prioritizes thin widgets, so that if there is both a thin widget
and a thick widget under the mouse cursor, you will always hit the thin
widgets, even if the thin widgets is layered behind the thick one. This
makes it easier to hit thin resize-handles.

In theory this should allow us to make `resize_grab_radius_side` and
`resize_grab_radius_corner` smaller in a future PR, if we want to.
2024-12-16 09:33:25 +01:00
Ted de Munnik 3af907919b
Use `profiling` crate to support more profiler backends (#5150)
Hey! I am not sure if this is something that's been considered before
and decided against (I couldn't find any PR's or issues).

This change removes the internal profiling macros in library crates and
the `puffin` feature and replaces it with similar functions in the
[profiling](https://github.com/aclysma/profiling) crate. This crate
provides a layer of abstraction over various profiler instrumentation
crates and allows library users to pick their favorite (supported)
profiler.

An additional benefit for puffin users is that dependencies of egui are
included in the instrumentation output too (mainly wgpu which uses the
profiling crate), so more details might be available when profiling.

A breaking change is that instead of using the `puffin` feature on egui,
users that want to profile the crate with puffin instead have to enable
the `profile-with-puffin` feature on the profiling crate. Similarly they
could instead choose to use `profile-with-tracy` etc.

I tried to add a 'tracy' feature to egui_demo_app in order to showcase ,
however the /scripts/check.sh currently breaks on mutually exclusive
features (which this introduces), so I decided against including it for
the initial PR. I'm happy to iterate more on this if there is interest
in taking this PR though.

Screenshot showing the additional info for wgpu now available when using
puffin

![image](https://github.com/user-attachments/assets/49fc0e7e-8f88-40cb-a69e-74ca2e3f90f3)
2024-12-16 09:15:54 +01:00
Emil Ernerfeldt 9aae14cdf4 Shorter `Debug` formatting of `LayerId` 2024-12-13 08:15:13 +01:00
Antoine Beyeler ba060a2c87
Drag-and-drop: keep cursor set by user, if any (#5467)
We used to always set the cursor to `Grabbing` when a drag and drop
payload is set, but this shadows user code trying to set an alternative
cursor (e.g. `NoDrop`). This PR no only change the cursor to `Grabbing`
if is way previously set to `Default`.
2024-12-12 19:47:41 +01:00
Jay Oster ea89c2935e
Android support for eframe (#5318)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

Android support is "almost there". This PR pushes it just a bit further
by allowing `eframe` to be used on Android. It works by smuggling the
`AndroidApp` required by `winit` through `NativeOptions`.

The example isn't great because it doesn't leave space on the display
for Android's top status bar or the lower navigation bar. I don't know
what to do about that, yet. This is as far as I've managed to get it
working.

Another problem is that the development environment setup is completely
awful for Android unless you happen to already be a full-time Android
developer with everything configured on your build host. As a Rustacean,
this makes me very sad.

I've had some luck moving all of that mess to a container, adapted from
https://github.com/SergioRibera/docker-rust-android. It takes care of
all of the build dependencies, Android SDK, and the `cargo-apk` patches
for bugs that I hit while getting the example to work on my device. (I
also had to install an adb driver on my host and downloaded the Android
platform-tools to get access to `adb`. An alternative is exposing the
USB device to Docker. On Windows hosts, that means [installing
`usbipd`](https://learn.microsoft.com/en-us/windows/wsl/connect-usb). A
second alternative is using an `mtp` client to upload the APK as a file
with USB file transfer enabled, then manually install it through the
device's file manager.)

I'm not including the docker stuff in this PR, but here are the files
and instructions for future reference (and it will probably simplify
manual testing and CI, FWIW!)

<details><summary><code>Dockerfile</code></summary>

```dockerfile
FROM rust:1.76.0-slim

# Variable arguments
ARG JAVA_VERSION=17
ARG NDK_VERSION=25.1.8937393
ARG BUILDTOOLS_VERSION=30.0.0
ARG PLATFORM_VERSION=android-30
ARG CLITOOLS_VERSION=8512546_latest

# Install Android requirements
RUN apt-get update -yqq && \
    apt-get install -y --no-install-recommends \
    libcurl4-openssl-dev libssl-dev pkg-config build-essential git python3 wget zip unzip openjdk-${JAVA_VERSION}-jdk && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Install android targets
RUN rustup target add armv7-linux-androideabi aarch64-linux-android

# Install cargo-apk
RUN git clone -b fix/bin-targets-workspace-members https://github.com/parasyte/cargo-apk.git /tmp/cargo-apk && \
    cargo install --path /tmp/cargo-apk/cargo-apk

# Generate Environment Variables
ENV JAVA_VERSION=${JAVA_VERSION}
ENV ANDROID_HOME=/opt/Android
ENV NDK_HOME=/opt/Android/ndk/${NDK_VERSION}
ENV ANDROID_NDK_ROOT=${NDK_HOME}
ENV PATH=$PATH:${ANDROID_HOME}:${ANDROID_NDK_ROOT}:${ANDROID_HOME}/build-tools/${BUILDTOOLS_VERSION}:${ANDROID_HOME}/cmdline-tools/bin

# Install command line tools
RUN mkdir -p ${ANDROID_HOME}/cmdline-tools && \
    wget -qc "https://dl.google.com/android/repository/commandlinetools-linux-${CLITOOLS_VERSION}.zip" -P /tmp && \
    unzip -d ${ANDROID_HOME} /tmp/commandlinetools-linux-${CLITOOLS_VERSION}.zip && \
    rm -fr /tmp/commandlinetools-linux-${CLITOOLS_VERSION}.zip
# Install sdk requirements
RUN echo y | sdkmanager --sdk_root=${ANDROID_HOME} --install \
    "build-tools;${BUILDTOOLS_VERSION}" "ndk;${NDK_VERSION}" "platforms;${PLATFORM_VERSION}"

# Create APK keystore for debug profile
# Adapted from caa806283d/ndk-build/src/ndk.rs (L393-L423)
RUN keytool -genkey -v -keystore ${HOME}/.android/debug.keystore -storepass android -alias androiddebugkey \
    -keypass android -dname 'CN=Android Debug,O=Android,C=US' -keyalg RSA -keysize 2048 -validity 10000

# Cleanup
RUN rm -rf /tmp/*

WORKDIR /src

ENTRYPOINT [ "cargo", "apk", "build" ]
```
</details>

<details><summary><code>.dockerignore</code></summary>

```ignore
# Ignore everything, only the Dockerfile is needed to build the container
*
```
</details>

```sh
docker build -t rust-android:latest .
docker run --rm -it -v "$PWD:/src" rust-android:latest -p hello_android
adb install target/debug/apk/hello_android.apk
```

* Part of #2066
* [x] I have followed the instructions in the PR template
2024-12-12 19:24:26 +01:00
lucasmerlin 6c1d695fc6
Add screenshot support for eframe web (#5438)
This implements web support for taking screenshots in an eframe app (and
adds a nice demo).
It also updates the native screenshot implementation to work with the
wgpu gl backend.

The wgpu implementation is quite different than the native one because
we can't block to wait for the screenshot result, so instead I use a
channel to pass the result to a future frame asynchronously.

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


https://github.com/user-attachments/assets/67cad40b-0384-431d-96a3-075cc3cb98fb
2024-12-12 19:17:42 +01:00
Emil Ernerfeldt de8ac88c0e
Add `Context::layer_transform_to_global` & `layer_transform_from_global` (#5465)
This makes it easy to get the current transform of a layer, and uses
consistent naming everywhere.

`Memory::layer_transforms` is now called `Memory::to_global`, because
the old name was ambiguous (transform into what direction?)
2024-12-12 18:29:13 +01:00
Michael "Scott" McBee d3ea922cc6
Fix: don't interact with `Area` outside its `constrain_rect` (#5459)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* [x] I have followed the instructions in the PR template

This PR makes an area's interact rect intersect its constrain rect. This
fixes an issue where masked areas would still intercept input.


Before:

![before](https://github.com/user-attachments/assets/6b790a04-8a15-44fe-a7ae-4adda189ecba)

After:

![after](https://github.com/user-attachments/assets/98010d89-e680-44cb-8717-faf31b0912d3)
2024-12-12 11:42:32 +01:00
Tristan Guichaoua 4362a242b0
web_demo: make hash anchor case insensitive (#5446)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

* [X] I have followed the instructions in the PR template
2024-12-11 13:44:37 +01:00
Emil Ernerfeldt f28080c675
Update some crates to fix CI (#5456)
> cargo update -p url

```
     Locking 28 packages to latest compatible versions
      Adding displaydoc v0.2.5
      Adding icu_collections v1.5.0
      Adding icu_locid v1.5.0
      Adding icu_locid_transform v1.5.0
      Adding icu_locid_transform_data v1.5.0
      Adding icu_normalizer v1.5.0
      Adding icu_normalizer_data v1.5.0
      Adding icu_properties v1.5.1
      Adding icu_properties_data v1.5.0
      Adding icu_provider v1.5.0
      Adding icu_provider_macros v1.5.0
    Updating idna v0.5.0 -> v1.0.3
      Adding idna_adapter v1.2.0
      Adding litemap v0.7.4
      Adding stable_deref_trait v1.2.0
      Adding synstructure v0.13.1
      Adding tinystr v0.7.6 (latest: v0.8.0)
    Removing tinyvec v1.8.0
    Removing tinyvec_macros v0.1.1
    Removing unicode-bidi v0.3.17
    Removing unicode-normalization v0.1.24
    Updating url v2.5.2 -> v2.5.4
      Adding utf16_iter v1.0.5
      Adding utf8_iter v1.0.4
      Adding write16 v1.0.0
      Adding writeable v0.5.5 (latest: v0.6.0)
      Adding yoke v0.7.5
      Adding yoke-derive v0.7.5
      Adding zerofrom v0.1.5
      Adding zerofrom-derive v0.1.5
      Adding zerovec v0.10.4 (latest: v0.11.0)
      Adding zerovec-derive v0.10.3 (latest: v0.11.0)
```

holy hell that's a lot of new crates 😭 


* Waiting for https://github.com/emilk/egui/pull/5457
2024-12-10 17:16:38 +01:00
Emil Ernerfeldt 53a926a428
Update MSRV to 1.80 (#5457)
Because some dependencies now require it, see:
* https://github.com/emilk/egui/pull/5456
2024-12-10 16:09:03 +01:00
Emil Ernerfeldt 9b1ae6b880 Add CHANGELOG.md for egui_kittest 2024-12-10 16:06:29 +01:00
Emil Ernerfeldt a7539b270a
Remove `Order::PanelResizeLine` (#5455)
This was a hack that is no longer in use
2024-12-10 15:32:43 +01:00
Antoine Beyeler 13352d6064
Fix drag-and-drop termination condition bug (#5452)
I introduced this in #5433.

TL;DR: there are two termination conditions for drag-and-drop
operations:
- ESC
- release mouse

The former _must_ happen at frame start (to properly capture the
keystroke). The latter _must_ happen at end-of-frame (to _not_ shadow
the mouse release event from user code).

This is now properly documented.
2024-12-09 12:12:14 +01:00
Emil Ernerfeldt 5384600fa2 cargo fmt 2024-12-09 12:11:27 +01:00
EriKWDev 39d6b3367b
Support wgpu-tracing with same mechanism as wgpu examples (#5450)
Gets the WGPU_TRACE env variable and gives it as an optional argument
to request_device. Same mechanism as the wgpu-examples:


11b51693d3/examples/src/framework.rs (L316)
2024-12-09 11:58:33 +01:00
Emil Ernerfeldt 046034f902
Add `Color32::mul` (#5437)
Multiply two `Color32` together quickly, in gamma-space
2024-12-05 13:53:20 +01:00
lucasmerlin 291b83b7be
Support loading images with weird urls and improve error message (#5431)
* Closes #5341
* [x] I have followed the instructions in the PR template
2024-12-05 07:33:02 +01:00
Antoine Beyeler f687b27efc
Consume escape keystroke when bailing out from a drag operation (#5433) 2024-12-04 17:35:24 +01:00
Emil Ernerfeldt 577ee8d228
Add `Button::image_tint_follows_text_color` (#5430)
For when you have a white icon/image that should respond to hover just
like the text does.
2024-12-04 15:24:29 +01:00
Emil Ernerfeldt c5ac7d301a
Fix `on_hover_text_at_pointer` for transformed layers (#5429) 2024-12-04 14:23:05 +01:00
Juan Campa cd0f5859b2
Make text cursor always appear on click (#5420)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

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

### Problem
When clicking on a TextEdit sometimes the cursor doesn't appear
immediately which makes it feel like the click was not registered for a
second. This is because the start time for the blinking animation is
only reset on keyboard input, but not on mouse interaction.

It's hard to tell on the video but the cursor doesn't show immediately
after clicking if the blink timer happens to be off.


https://github.com/user-attachments/assets/9f049bd0-0375-4291-b2ef-697777fb854d


### Solution
Reset the click timer every time a `TextEdit` is clicked. 

Additionally, the cursor is now correctly painted on the pixel boundary.
IMO we should default to 1px cursor (instead of 2px) but that's not
included in this PR. Happy to make that change too.


https://github.com/user-attachments/assets/6c489414-f2c4-4dc6-85dd-f8bc457edad0
2024-12-04 14:18:49 +01:00
Emil Ernerfeldt eac7ba01fa
Move `egui::util::cache` to `egui::cache`; add `FramePublisher` (#5426)
This moves `egui::util::cache` to `egui::cache` (the old path is
deprecated, but still works).

It also adds the `FramePublisher` helper, which can be used to publish a
value which will be retained for this frame and the next:

``` rs
pub type MyPublisher = egui::cache::FramePublisher<MyKey, MyValue>;

// Publish:
ctx.memory_mut(|mem| {
    mem.caches.cache::<MyPublisher>().set(key, value);
});

// Retrieve:
let value: Option<MyValue> = ctx.memory_mut(|mem| {
    mem.caches
        .cache::<MyPublisher>()
        .get(key)
        .clone()
})
```
2024-12-03 14:28:12 +01:00
Emil Ernerfeldt c7224aab26
Improve error message when kittest fails (#5427)
* Closes https://github.com/emilk/egui/issues/5423

New output is actionable

```
failures:

---- demo::demo_app_windows::tests::demos_should_match_snapshot stdout ----
thread 'demo::demo_app_windows::tests::demos_should_match_snapshot' panicked at crates/egui_demo_lib/src/demo/demo_app_windows.rs:433:9:
Errors: [
    "'demos/Code Example' Image size did not match snapshot. Expected: (402, 574), Actual: (415, 574).
     Run `UPDATE_SNAPSHOTS=1 cargo test` to update the snapshots.",
]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    demo::demo_app_windows::tests::demos_should_match_snapshot
```
2024-12-03 13:40:51 +01:00
Antoine Beyeler 3411aba768
Modals: Add `UiKind::Modal`, and consume escape-key properly (#5414)
Small fixes/improvements to `Modal`

- Fixes #5413
2024-12-03 11:46:37 +01:00
Emil Ernerfeldt 8647b56b31 Update snapshot for `Code Example` 2024-12-03 10:33:10 +01:00
Emil Ernerfeldt a9c76ba7a6
Allow attaching custom user data to a screenshot command (#5416)
This lets users trigger a screenshot from anywhere, and then when they
get back the results they have some context about what part of their
code triggered the screenshot.
2024-12-03 10:08:55 +01:00
Emil Ernerfeldt 6a1131f1c9 Fix docstring backticks 2024-12-03 09:55:25 +01:00
Juan Campa 4f7f23ef5e
Fix cursor clipping in `TextEdit` inside a `ScrollArea` (#3660)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* 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 add commits to your PR.
* Remember to run `cargo fmt` and `cargo cranky`.
* 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 #1531

### Before
Notice how the cursor hides after third enter and when the line is long.


https://github.com/user-attachments/assets/8e45736e-d6c7-4dc6-94d0-213188c199ff

### After
Cursor is always visible


https://github.com/user-attachments/assets/43200683-3524-471b-990a-eb7b49385fa9


- `ScrollArea` now checks if there's a `scroll_target` in `begin`, if
there is, it saves it because it's not from its children, then restore
it in `end`.
- `TextEdit` now allocates additional space if its galley grows during
the frame. This is needed so that any surrounding `ScrollArea` can bring
the cursor to view, otherwise the cursor lays outside the the
`ScrollArea`'s `content_ui`.
2024-12-02 09:29:06 +01:00
Jochen Görtler 6833cf56e1
Add new `Rect::intersects_ray_from_center` method (#5415)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
Title.

* [x] I have followed the instructions in the PR template
2024-12-02 09:20:59 +01:00
Emil Ernerfeldt 328422dc62
Update MSRV to Rust 1.79 (#5421)
Mostly to fix `cargo-machete` CI
2024-12-01 18:58:35 +01:00
Valentin c86d0e5918
fix accidental change of FallbackEgl to PreferEgl (#5408)
I accidentally changed this in a previous commit when I meant to only
change the comment above it.

https://github.com/emilk/egui/pull/5392#discussion_r1859383653
2024-11-30 12:56:23 +01:00
lucasmerlin 10791cc43d
Add `Modal` and `Memory::set_modal_layer` (#5358)
* Closes #686 
* Closes #839 
* #5370 should be merged before this
* [x] I have followed the instructions in the PR template

This adds modals to egui. 
This PR
- adds a new `Modal` struct
- adds `Memory::set_modal_layer` to limit focus to a layer and above
(used by the modal struct, but could also be used by custom modal
implementations)
- adds `Memory::allows_interaction` to check if a layer is behind a
modal layer, deprecating `Layer::allows_interaction`



Current problems:
- ~When a button is focused before the modal opens, it stays focused and
you also can't hit tab to focus the next widget. Seems like focus is
"stuck" on that widget until you hit escape. This might be related to
https://github.com/emilk/egui/issues/5359~ fixed!

Possible future improvements: 
- The titlebar from `window` should be made into a separate widget and
added to the modal
- The state whether the modal is open should be stored in egui
(optionally), similar to popup and menu. Ideally before this we would
refactor popup state to unify popup and menu

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-11-28 16:52:05 +01:00
Samson 84cc1572b1
Update glow to 0.16 (#5395)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

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

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
2024-11-26 21:00:34 +01:00
Nicolas 88543270e0
Fix CI failures (#5407)
Fixes the RUSTSEC-2024-0399 issue with rustls and the errors in the
regression test
See:
https://rustsec.org/advisories/RUSTSEC-2024-0399.html
https://github.com/rustls/rustls/issues/2227

This also fixes the cargo deny runs which are currently failing

* [x] I have followed the instructions in the PR template
2024-11-26 20:09:59 +01:00
Valentin 7cee35c02a
document justification for FallbackEgl (#5392)
The previous link does not explain why we chose FallbackEgl. This is a
better link.
2024-11-26 15:23:43 +01:00
Valentin 6359ba7e66
forward x11 and wayland features to glutin (#5391)
eframe has features for selecting between x11 and wayland. eframe does
not forward the features to glutin. This makes glutin always compile
with both backends enabled. This change forwards the feature. This
allows users of egui to compile less dependencies when they only need
one of x11, wayland.

To understand this change, read the glutin Cargo.toml [1] and the glutin
build.rs [2]. You always have to enable glutin's glx feature with the
x11 feature. The other default features (egl, wgl) stay enabled. This is
intentional so that everything continues to work as before. We could
further minimize when egl and wgl are enabled, but that is not part of
this change. There is little reason to do so because those feature
already only add dependencies when you compile glutin for the right
platform (for example wgl on windows).

[1]
https://github.com/rust-windowing/glutin/blob/v0.32.1/glutin/Cargo.toml
[2]
https://github.com/rust-windowing/glutin/blob/v0.32.1/glutin/build.rs
2024-11-26 15:22:44 +01:00
Nicolas 12f9d6f42c
add painter.line() (#5291)
* Closes <https://github.com/emilk/egui/issues/5273>
* [x] I have followed the instructions in the PR template
2024-11-26 15:17:47 +01:00
lucasmerlin e28505077d
Update accesskit to 0.17 (#5372)
Updates accesskit and kittest. 

* [x] I have followed the instructions in the PR template
2024-11-26 15:16:08 +01:00
lucasmerlin 9ecc0b232c
Fix disabled widgets "eating" focus (#5370)
- fixes https://github.com/emilk/egui/issues/5359

For the test I added a `Harness::press_key` function. We should
eventually add these to kittest, probably via a trait one can implement
for the `Harness` but for now this should do.
2024-11-26 14:31:30 +01:00
GiGaGon 1787952a83
Create gray -> grey doc aliases (#5362)
As someone who uses "grey" instead of "gray", it is annoying that my
autocomplete can never find any of the "gray" color related things, so
this adds doc aliases for that.

* [x] I have followed the instructions in the PR template
2024-11-11 13:21:58 +01:00
lucasmerlin 3c7ad0ee12
egui_kittest: Allow passing state to the app closure (#5313)
The allows us to pass any state to the ui closure. While it is possible
to just store state in the closure itself, accessing that state after
the harness was created to e.g. read or modify it would require interior
mutability. With this change there are new `Harness::new_state`,
`Harness::run_state`, ... methods that allow passing state on each run.

This builds on top of #5301, which should be merged first

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-11-06 14:43:41 +01:00
Emil Ernerfeldt fc743d63b4 Add link to helpful article in font alpha TODO 2024-11-06 13:33:43 +01:00
lucasmerlin 5d6a58b917
Fix some typos (#5339)
The spell check pipeline in #5313 suddenly failed, this fixes these
typos and some more found via my IDEs spell checker tool
2024-11-04 09:51:34 +01:00
lucasmerlin ad14bf2490
Add `Harness::new_ui`, `Harness::fit_contents` (#5301)
This adds a `Harness::new_ui`, which accepts a Ui closure and shows the
ui in a central panel. One big benefit is that this allows us to add a
fit_contents method that can run the ui closure with a sizing pass and
resize the "screen" based on the content size.

I also used this to add a snapshot test for the rendering_test at
different scales.
2024-11-01 18:30:40 +01:00
Cody Neiman 21826bec18
Use proper `image` crate URI and MIME support detection (#5324)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

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

I removed the webp supported URI test given that the webp feature would
have to be enabled. I kept that webp is not supported in the other
tests.

There might need to be an additional warning in the changelog that image
support detection is now stricter.
2024-11-01 13:33:12 +01:00
StarStarJ 3f5cd74de7
Put font data into Arc to reduce memory consumption (#5276)
egui never accesses the `FontDefinitions`' member fields mutably, except
in `fonts_tweak_ui` where it cloned the `FontDefinitions` object anyway.

This patch reduces system memory consumption for shared font
definitions.
And also removes some overhead from copying (e.g. for the per
`pixel_per_points` font atlas)

Also it allows to keep a copy of the font definitions outside of egui.

In my App that uses international fonts:
Before:

![image](https://github.com/user-attachments/assets/f8dfb4f4-a21c-447c-8cf9-83025ad6e960)

New:

![image](https://github.com/user-attachments/assets/9f297fbd-e620-4b7e-a32a-65073ee805ed)


Note: If `Arc` is not wanted, then it could ofc be abstracted away.

I know this is quite a breaking change API wise, but would like to hear
your opinion.
2024-11-01 13:30:02 +01:00
YgorSouza 444c21a437
Prevent panic when copying text outside of a secure context (#5326)
* Closes <https://github.com/emilk/egui/issues/5293>
* [x] I have followed the instructions in the PR template
2024-11-01 13:21:59 +01:00
lucasmerlin bbbd936f50
Exclude icon.png from lfs (#5336)
* Closes #5331 
* [x] I have followed the instructions in the PR template
2024-11-01 13:21:05 +01:00
Emil Ernerfeldt 42652e223c
Update some crates (#5337) 2024-11-01 13:07:01 +01:00
TÖRÖK Attila 67c82ed5f2
wgpu: Bump to wgpu 23.0.0 and wasm-bindgen to 0.2.95 (#5330)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
2024-10-30 18:53:22 +01:00
valadaptive 5bfff316c9
Fix documentation for file drag and drop (#5328)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

The `RawInput::dropped_files` documentation referred to `NativeOptions`,
but the `drag_and_drop` option was moved to `ViewportBuilder` and is now
enabled by default.

Note that drag-and-drop is not *explicitly* enabled by default here, but
rather is enabled by default in winit. We only override winit's default
if the API consumer specifies it. It might be a good idea in general to
provide explicit defaults for everything in `ViewportBuilder` so we're
not relying on winit's behavior, but that's best left for another PR.

* Closes N/A
* [x] I have followed the instructions in the PR template
2024-10-30 15:24:45 +01:00
Cody Neiman 2cd3485dd4
Update MSRV from 1.76 to 1.77 (#5322)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

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

I am preparing a separate PR that adds support for JXL with `jxl-oxide`,
which is unlikely to be added to the `image` crate anytime soon (more
context will be provided in that PR).

`jxl-oxide` makes use of the
[`array::each_mut`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_mut)
API which was stabilized in 1.77, which is the motivation for this MSRV
bump.

Rust 1.77 was officially released to stable on 21 March, 2024.
2024-10-30 09:06:34 +01:00
lucasmerlin dafcfdad80
egui_kittest: Allow customizing the snapshot threshold and path (#5304)
This adds `egui_kittest::try_image_snapshot_options` and
`egui_kittest::image_snapshot_options`, as well as
`Harness::wgpu_snapshot_options` and
`Harness::try_wgpu_snapshot_options`

* [X] I have followed the instructions in the PR template
2024-10-29 19:52:21 +01:00
Arthur Brussee 759a0b2a21
Add option to initialize on existing wgpu setup (#5319)
When mixing and matching eframe with other wgpu applications
(https://github.com/tracel-ai/burn in my case), it can be helpful to use
an existing wgpu setup to initialize eframe with. This PR changes the
WpuConfiguration (in a non-backwards compat way :/), to either take some
options how to create a wgpu setup, or an existing wgpu setup
(consisting of an instance, adapter, device and queue).

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

---------

Co-authored-by: Andreas Reich <r_andreas2@web.de>
2024-10-29 17:12:28 +01:00
Bruce Mitchener fba2dc85a3
egui-winit: Remove implicit `accesskit_winit` feature (#5316)
This is controlled by the `accesskit` feature and nothing needs the
implicit `accesskit_winit` feature, so use `dep:` syntax to prevent it
from being created.

* [x] I have followed the instructions in the PR template
2024-10-29 13:09:31 +01:00
MStarha 44877d490e
Respect `Style::override_font_id` in `RichText` (#5310)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

Currently `Style::override_font_id` does not affect widgets with their
`TextStyle` like `Button`s, `ComboBox`es, `CheckBox`es, etc. This PR
fixes this behavior such that all widgets using default configuration of
`RichText` are affected by this setting.
* [x] I have followed the instructions in the PR template
2024-10-29 12:51:17 +01:00
rustbasic 926799a167
Fix: Popup incorrectly calculates possible min width of popup causing panic (#5208)
Fix: Popup incorrectly calculates possible min width of popup causing
panic

* Closes #5206
2024-10-29 12:43:05 +01:00
zhatuokun c7d46ac9f9
Fix: `Sides` did not apply the layout position correctly. (#5303)
Same as last time, but use `available_rect_before_wrap` to avoid
containing infinity.
2024-10-29 12:42:02 +01:00
rustbasic 3f2bd14554
Fix: Window::default_pos does not work (#5315)
Fix: Window::default_pos does not work

Issues: Since `default_size` is not applied to `area`,
`style.spacing.default_area_size` is applied, causing problems.

* Closes #5314
2024-10-29 12:40:51 +01:00
Adrian Valcarcel-Schott 98916489f7
Add `ComboBox::close_behavior` (#5305)
Exposed the underlying PopupCloseBehavior of ComboBox in order to allow
more control of ComboBox behavior.

This allows ComboBox to be used rather than manually managing a popup
directly, while also gaining the convenience features of ComboBox such
as popup auto-sizing.

* [x] I have followed the instructions in the PR template
2024-10-29 12:39:44 +01:00
Zeenobit ce05b59689
Add `Window::scroll_bar_visibility` (#5231)
Trivial changelist to allow setting the scroll visibility on `Window`.
2024-10-29 12:35:48 +01:00
Dimitris Papaioannou ebb4646358
Impl from Box<str> for WidgetText, RichText (#5309)
`Box<str>` is an immutable heap-allocated string slice.
This PR makes it more convenient to use them in labels for example.

Before this PR
```rust
let text: Box<str> = "Hello".into();
ui.label(text.into_string());

let text_ref: &Box<str> = &"Hello".into();
ui.label(text_ref.clone().into_string());
// or
ui.label(text_ref.as_ref());
// or
ui.label(&**text_ref);
```
After this PR
```rust
let text: Box<str> = "Hello".into();
ui.label(text);

let text_ref: &Box<str> = &"Hello".into();
ui.label(text_ref);
```

* [x] I have followed the instructions in the PR template
2024-10-29 10:50:06 +01:00
rustbasic 288c74e332
Expand max font atlas size from 8k to 16k (#5257)
When using fonts with an average of 50,000 characters,
'epaint texture atlas overflowed!' may be printed and cause problems.
It is necessary to expand the max value related to texture.

* Closes #5256

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-10-29 10:42:28 +01:00
Emil Ernerfeldt 7b69ec3473
Move all existing .png images to git LGS (#5320)
* Sibling PR: https://github.com/emilk/egui/pull/5321
2024-10-29 10:04:07 +01:00
Wybe Westra 4622fff28c
Report egui::Window contents as children to accesskit (#5240)
Previously, all widgets would be listed in accesskit as children of the
toplevel window.
With this change, they will be reported as child of the `egui::Window`
they are in, Which should increase parseability of the ui for
screenreaders and integration tests.

Added an accesskit test to check that it is indeed working.

Co-authored-by: Wybe Westra <w.westra@kwantcontrols.nl>
2024-10-29 09:52:06 +01:00
lucasmerlin 4e101d25cd
Fix textedit intrinsic size metric (#5275)
Since textedit is doing the justify layout calculation itself, we need
to report the original desired_size as intrinsic size, instead of the
value passed to allocate_space.

I wonder though, is it still necessary that the TextEdit does the
justify calculation itself instead of relying on the ui layout to do it?
As far as I understand it, justify should be handled by the
ui.allocate_space call.
2024-10-28 13:58:34 +01:00
YgorSouza f75a235c90
Use boxed slice for lookup table to avoid stack overflow (#5212)
* Closes <https://github.com/emilk/egui/issues/5210>
* [x] I have followed the instructions in the PR template
2024-10-23 14:42:47 +02:00
frederik-uni 04ab5e7574
`Context::add_font` (#5228)
make it easier to add fonts. 

For example if I want to add a custom FontFamily or if the user wants to
add a Chinese fallback
* [x] I have followed the instructions in the PR template

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-10-23 14:29:44 +02:00
lucasmerlin d9a35a7289
Increase the threshold for snapshot tests (#5298)
* Related to #5295 
* [x] I have followed the instructions in the PR template
2024-10-23 11:19:39 +02:00
Emil Ernerfeldt 68d312d043
Revert "Fix: `Sides` did not apply the layout position correctly." (#5300)
Reverts emilk/egui#5232

I should have tested it first. `cursor` can contain infinites. There is
a better fix to be found @zhatuokun
2024-10-23 11:18:36 +02:00
frederik-uni e02be45007
iOS: Support putting UI next to the dynamic island (#5211)
winit::Window::inner_size returns size of safe area on iOS. use
winit::Window::outer_size on iOS
The dimensions of outer_size include the title bar and borders, but as
far as I know there is no way to actually display the title bar or
borders on iOS so it should be fine.

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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 #3547 
* [X] I have followed the instructions in the PR template

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-10-23 11:10:12 +02:00
lucasmerlin 13e65eb55b
Expose center position in `MultiTouchInfo` (#5247)
Expose the center / average position in MultiTouchInfo
2024-10-23 11:03:53 +02:00
YgorSouza e5c502f21e
Fix Ctrl+Shift+Z redo shortcut (#5258)
This shortcut was previously triggering the Undo action due to the
matches_logically method ignoring the state of the Shift key. This was
solved by simply inverting the order of the undo and redo arms, so the
undo is not matched if the shortcut corresponds to redo.

* Closes <https://github.com/emilk/egui/issues/5255>
* [x] I have followed the instructions in the PR template
2024-10-23 10:56:12 +02:00
zhatuokun 6add64e144
Fix: `Sides` did not apply the layout position correctly. (#5232)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->

Run this code

```rs
        CentralPanel::default().show(ctx, |ui| {
            Sides::new().show(
                ui,
                |ui| {
                    ui.label("1");
                },
                |ui| {
                    ui.label("2");
                },
            );
            Sides::new().show(
                ui,
                |ui| {
                    ui.label("11");
                },
                |ui| {
                    ui.label("22");
                },
            );
            Sides::new().show(
                ui,
                |ui| {
                    ui.label("111");
                },
                |ui| {
                    ui.label("222");
                },
            );
        });
```

Before


![before](https://github.com/user-attachments/assets/2678f937-859e-422a-9171-5f2a63166c8f)

After


![after](https://github.com/user-attachments/assets/879892f1-a69d-4540-8e56-8b2448e939ed)
2024-10-23 10:54:27 +02:00
zhatuokun 3a0859b817
Fix: `Ui::new_child` does not consider the sizing_pass field of `UiBuilder` (#5262)
During the sizing pass we want widgets to use up as little space as
possible, but it does not consider the sizing_pass field of `UiBuilder`.
2024-10-23 10:53:26 +02:00
Justin Whear 7c1f06941e
Use id_salt on Table ScrollArea (#5282)
The salt is based on the table's `state_id`.

* Closes https://github.com/emilk/egui/issues/5281
* [x] I have followed the instructions in the PR template
2024-10-23 10:48:09 +02:00
lucasmerlin 67a54ec5ce
Improve egui_kittest documentation and update CONTRIBUTING.md (#5296)
This should hopefully make it easier for egui contributors and
egui_kittest users to understand the snapshot tests


* [X] I have followed the instructions in the PR template
2024-10-23 08:54:43 +02:00
lucasmerlin 70a01138b7
Add egui testing library (#5166)
- closes #3491 
- closes #3926

This adds a testing library to egui based on
[kittest](https://github.com/rerun-io/kittest). Kittest is a new
[AccessKit](https://github.com/AccessKit/accesskit/)-based testing
library. The api is inspired by the js
[testing-library](https://testing-library.com/) where the idea is also
to query the dom based on accessibility attributes.
We made kittest with egui in mind but it should work with any rust gui
framework with AccessKit support.

It currently has support for:
- running the egui app, frame by frame
- building the AccessKit tree
- ergonomic queries via kittest
  - via e.g. get_by_name, get_by_role
- simulating events based on the accesskit node id
- creating arbitrary events based on Harness::input_mut
- rendering screenshots via wgpu
- snapshot tests with these screenshots

A simple test looks like this: 
```rust
fn main() {
    let mut checked = false;
    let app = |ctx: &Context| {
        CentralPanel::default().show(ctx, |ui| {
            ui.checkbox(&mut checked, "Check me!");
        });
    };

    let mut harness = Harness::builder().with_size(egui::Vec2::new(200.0, 100.0)).build(app);
    
    let checkbox = harness.get_by_name("Check me!");
    assert_eq!(checkbox.toggled(), Some(Toggled::False));
    checkbox.click();
    
    harness.run();

    let checkbox = harness.get_by_name("Check me!");
    assert_eq!(checkbox.toggled(), Some(Toggled::True));

    // You can even render the ui and do image snapshot tests
    #[cfg(all(feature = "wgpu", feature = "snapshot"))]
    egui_kittest::image_snapshot(&egui_kittest::wgpu::TestRenderer::new().render(&harness), "readme_example");
}
```

~Since getting wgpu to run in ci is a hassle, I'm taking another shot at
creating a software renderer for egui (ideally without a huge dependency
like skia)~ (this didn't work as well as I hoped and it turns out in CI
you can just run tests on a mac runner which comes with a real GPU)
 
Here is a example of a failed snapshot test in ci, it will say which
snapshot failed and upload an artifact with the before / after and diff
images:

https://github.com/emilk/egui/actions/runs/11183049487/job/31090724606?pr=5166
2024-10-22 12:39:00 +02:00