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

239 Commits

Author SHA1 Message Date
Emil Ernerfeldt
1843398cd1 Add back old deprecated panels 2025-11-16 11:39:31 +01:00
Emil Ernerfeldt
f137f48ef5 Merge branch 'main' into common-panels 2025-11-16 11:31:23 +01:00
Ian Hobson
30277233ce Add support for the safe area on iOS (#7578)
This PR is a continuation of #4915 by @frederik-uni and @lucasmerlin
that introduces support for keeping egui content within the 'safe area'
on iOS (avoiding the notch / dynamic island / menu bar etc.), with the
following changes:

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

---------

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

This fixes a bug where a menu could get stuck, not closing at all, when
the currently open submenu stops being shown.
I also added a way to reproduce this to the demo, as well as a test
ensuring that there is no race condition in the fix.
2025-10-07 10:16:35 +02:00
Emil Ernerfeldt
bd45406fad Use a lot more let-else (#7582) 2025-10-02 19:47:00 +02:00
Alan Everett
b0c568a78e Add rotation gesture support for trackpad sources (#7453)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Co-authored-by: Lucas Meurer <hi@lucasmerlin.me>
2025-09-11 12:44:17 +02:00
Emil Ernerfeldt
c2912369ca Improve text demo: more fine control of letter spacing (#7520) 2025-09-09 09:35:25 +02:00
Emil Ernerfeldt
01ee23c1a0 Add Zoom Factor to options panel (#7517) 2025-09-08 18:27:28 +02:00
valadaptive
d5b0a6f446 More even text kerning (#7431)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-09-08 17:29:41 +02:00
ozwaldorf
454af7aa6c fix: SubMenu should not display when ui is disabled (#7428)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

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

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

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

cc @lucasmerlin 

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

---------

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

This example would never close:

```rs
    let mut open = true;

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

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

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

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

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

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

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

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


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

Cursive text will also look nicer.

This unfortunately changes the contract of what
`register_native_texture` expects

---------

Co-authored-by: Adrian Blumer <blumer.adrian@gmail.com>
2025-07-07 17:46:27 +02:00
Emil Ernerfeldt
09596a5e7b egui_kittest: more ergonomic functions taking Impl Into<String> (#7307) 2025-07-07 13:50:53 +02:00
Lucas Meurer
47a2bb10b0 Remove SelectableLabel (#7277)
* part of https://github.com/emilk/egui/issues/7264
* removes SelectableLabel (Use `Button::selectable` instead)
* updates `Ui::selectable_value/label` with IntoAtoms support

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

## Summary

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

### Additions to `SnapshotOptions`:

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

### Integration into snapshot comparison logic:

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

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

---------

Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-07-03 14:23:15 +02:00
Emil Ernerfeldt
8bedaf6e5b Add light-mode Widget Gallery screenshot test (#7288)
Part of some work to improve text rendering in light mode (again!)
2025-07-02 12:00:36 +02:00
Emil Ernerfeldt
b2995dcb83 Use Rust edition 2024 (#7280) 2025-06-30 14:01:57 +02:00
Emil Ernerfeldt
962c8e26a8 Update MSRV to 1.85 (#7279) 2025-06-30 13:43:27 +02:00
Lucas Meurer
0152a87519 Create custom egui_kittest::Node (#7138)
This adds a custom Node struct with proper support for egui types
(`Key`, `Modifiers`, `egui::Event`, `Rect`) instead of needing to use
the kittest / accesskit types.

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

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

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

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

* Closes #7051
2025-06-16 01:42:01 +02:00
Lucas Meurer
6eb7bb6e08 Add AtomLayout, abstracing layouting within widgets (#5830)
Today each widget does its own custom layout, which has some drawbacks:
- not very flexible
- you can add an `Image` to `Button` but it will always be shown on the
left side
  - you can't add a `Image` to a e.g. a `SelectableLabel`
- a lot of duplicated code

This PR introduces `Atoms` and `AtomLayout` which abstracts over "widget
content" and layout within widgets, so it'd be possible to add images /
text / custom rendering (for e.g. the checkbox) to any widget.

A simple custom button implementation is now as easy as this:
```rs
pub struct ALButton<'a> {
    al: AtomicLayout<'a>,
}

impl<'a> ALButton<'a> {
    pub fn new(content: impl IntoAtomics) -> Self {
        Self { al: content.into_atomics() }
    }
}

impl<'a> Widget for ALButton<'a> {
    fn ui(mut self, ui: &mut Ui) -> Response {
        let response = ui.ctx().read_response(ui.next_auto_id());

        let visuals = response.map_or(&ui.style().visuals.widgets.inactive, |response| {
            ui.style().interact(&response)
        });

        self.al.frame = self
            .al
            .frame
            .inner_margin(ui.style().spacing.button_padding)
            .fill(visuals.bg_fill)
            .stroke(visuals.bg_stroke)
            .corner_radius(visuals.corner_radius);

        self.al.show(ui)
    }
}

```

The initial implementation only does very basic layout, just enough to
be able to implement most current egui widgets, so:
- only horizontal layout
- everything is centered
- a single item may grow/shrink based on the available space
- everything can be contained in a Frame


There is a trait `IntoAtoms` that conveniently allows you to construct
`Atoms` from a tuple
```
   ui.button((Image::new("image.png"), "Click me!"))
```
to get a button with image and text.


This PR reimplements three egui widgets based on the new AtomLayout:
 - Button
   - matches the old button pixel-by-pixel
- Button with image is now [properly
aligned](https://github.com/emilk/egui/pull/5830/files#diff-962ce2c68ab50724b01c6b64c683c4067edd9b79fcdcb39a6071021e33ebe772)
in justified layouts
   - selected button style now matches SelecatbleLabel look
- For some reason the DragValue text seems shifted by a pixel almost
everywhere, but I think it's more centered now, yay?
 - Checkbox
- basically pixel-perfect but apparently the check mesh is very slightly
different so I had to update the snapshot
   - somehow needs a bit more space in some snapshot tests?
 - RadioButton
   - pixel-perfect
   - somehow needs a bit more space in some snapshot tests?

I plan on updating TextEdit based on AtomLayout in a separate PR (so
you could use it to add a icon within the textedit frame).
2025-06-13 09:39:52 +02:00
Nicolas
9f9153805d lint: fix lints appearing in rust stable currently (#7118)
* [x] I have followed the instructions in the PR template
2025-06-11 17:38:06 +02:00
Emil Ernerfeldt
2cf6a3a9a6 Track original SVG size (#7098)
This fixes bugs related to how an `Image` follows the size of an SVG.

We track the "source size" of each image, i.e. the original width/height
of the SVG, which can be different from whatever it was rasterized as.
2025-05-28 08:33:01 +02:00
Emil Ernerfeldt
b8334f365b Fix sometimes blurry SVGs (#7071)
* Closes https://github.com/emilk/egui/issues/3501

The problem occurs when you want to render the same SVG at different
scales, either at the same time in different parts of your UI, or at two
different times (e.g. the DPI changes).

The solution is to use the `SizeHint` as part of the key.

However, when you have an SVG in a resizable container, that can lead to
hundreds of versions of the same SVG. So new eviction code is added to
handle this case.
2025-05-21 20:01:40 +02:00
Emil Ernerfeldt
f57cb27386 Include test windows in egui_demo_lib snapshot tests (#7070) 2025-05-21 17:44:27 +02:00
Emil Ernerfeldt
54ae2360ec Fix incorrect color fringe colors on SVG:s (#7069)
This is a problem that affected the fringes on all SVG:s with
transparency, especially on a light background.

## Before

![image](https://github.com/user-attachments/assets/342823ad-005c-4f82-83a6-d2dcccfd3221)


## After

![image](https://github.com/user-attachments/assets/73398265-d333-461b-8c2b-fce405d95a9c)
2025-05-21 17:18:36 +02:00
Emil Ernerfeldt
d0876a1a60 Rename master branch to main (#7034)
For consistency with other repositories, i.e. so I can write `git
checkout main` without worrying which repo I'm browsing.
2025-05-08 09:15:42 +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
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
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
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
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
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
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
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
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
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
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
Bruno Paré-Simard
8e67cd207d Merge branch 'emilk:master' into common-panels 2025-02-06 12:39:22 -05: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
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