1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 22:30:03 -04:00
Commit Graph

846 Commits

Author SHA1 Message Date
Emil Ernerfeldt
378e22e6ec Improve the ThemePreference selection UI slightly 2025-07-03 09:16:13 +02:00
Emil Ernerfeldt
dc79998044 Improve text rendering in light mode (#7290)
This changes how we convert glyph coverage to alpha (and ultimately a
color), but only in light mode.

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

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


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



## Before / After

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


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


![image](https://github.com/user-attachments/assets/56a4a4f3-c431-4991-b941-a566a4ae94ed)
![Screenshot 2025-07-02 at 13 59
30](https://github.com/user-attachments/assets/df5a91ad-0bb8-4a0f-81a2-50852e7556c1)
2025-07-02 14:58:37 +02:00
Emil Ernerfeldt
0857527f1d Add Visuals::weak_text_alpha and weak_text_color (#7285)
* Closes https://github.com/emilk/egui/issues/7262

This also makes the default weak color slightly less weak in most cases.
2025-07-01 20:42:54 +02:00
Emil Ernerfeldt
9d1dce51eb Extend .typos.toml to enforce american english (#7284)
More or less the same list we use at Rerun
2025-07-01 15:54:00 +02:00
Emil Ernerfeldt
737c61867b Add Visuals::text_edit_bg_color (#7283)
* Closes https://github.com/emilk/egui/issues/7263
2025-07-01 15:13:16 +02:00
Emil Ernerfeldt
9e021f78da Change ui.disable() to modify opacity (#7282)
* Closes https://github.com/emilk/egui/pull/6765


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

I needed to branch off to update snapshot images

---------

Co-authored-by: tye-exe <tye@mailbox.org>
Co-authored-by: Tye <131195812+tye-exe@users.noreply.github.com>
2025-07-01 14:05:53 +02:00
Emil Ernerfeldt
b2995dcb83 Use Rust edition 2024 (#7280) 2025-06-30 14:01:57 +02:00
Emil Ernerfeldt
962c8e26a8 Update MSRV to 1.85 (#7279) 2025-06-30 13:43:27 +02:00
Emil Ernerfeldt
8ba42f322d Add Context::cumulative_frame_nr (#7278) 2025-06-30 13:29:56 +02:00
Emil Ernerfeldt
d770cd53a6 Add Context::current_pass_index (#7276)
This can be used by developers who wants to add diagnostics when there
is a multi-pass egui frame.
2025-06-30 10:41:27 +02:00
Lukas Rieger
c943720eed Slider: move by at least the next increment when using fixed_decimals (#7066)
fixes https://github.com/emilk/egui/issues/7065
2025-06-29 13:30:39 +02:00
Nicolas
ab9f55ab01 Fix crash in egui_extras::FileLoader after forget_image (#6995)
This pull request modifies the `BytesLoader` implementation for
`FileLoader` in `crates/egui_extras/src/loaders/file_loader.rs` to
improve thread safety and handle unexpected states more gracefully.

### Changes to thread safety and state handling:
* Updated the cache logic to check if the `uri` exists in the cache
before inserting the result. If the `uri` is not found, a log message is
added to indicate the loading was canceled. This change prevents
overwriting cache entries unexpectedly.

* Closes <https://github.com/emilk/egui/issues/6755>
* [x] I have followed the instructions in the PR template
2025-06-27 11:27:03 +02:00
Lucas Meurer
78a8de2e8f Respect StyleModifier in popup Frame style (#7265)
This makes it possible to style the Popup's frame using a StyleModifier
2025-06-25 14:26:36 +02:00
Lucas Meurer
c8b844cd83 Use the new Popup api for the color picker button (#7137)
The color picker popup is now aligned to the bottom left edge (instead
of the bottom right), but I think this makes more sense and is aligned
with ComboBox etc. It also gets the new nice auto positioning.

* closes #5832 
* [x] I have followed the instructions in the PR template
2025-06-18 19:19:05 +02:00
Emil Ernerfeldt
8c2df4802c Add back old Tooltip::new (#7156)
I was a bit too hasty in https://github.com/emilk/egui/pull/7151 and
changed a public API in a breaking way, for no good reason
2025-06-16 19:36:19 +02:00
Lucas Meurer
5194c0df3e Minor atoms improvements (#7145)
Improve some lifetime bounds and add some convenience constructors
2025-06-16 08:42:17 +02:00
Emil Ernerfeldt
06760e1b08 Change API of Tooltip slightly (#7151)
We try to be consistent with our parameter order to reduce surprise for
users.

I also renamed a few things to clarify what is what
2025-06-16 08:30:46 +02:00
Azkellas
96c34139fd Select all text in DragValue when gaining focus via keyboard (#7107)
Previously, the `DragValue` widget selected all text when focus was
gained via a mouse click, but didn't when focus was gained via keyboard.


https://github.com/user-attachments/assets/5e82ca2c-0214-4201-ad2d-056dabc05e92

This PR makes both gained focus behaving the same way by selecting the
text on focus gained via keyboard.


https://github.com/user-attachments/assets/f246c779-3368-428c-a6b2-cec20dbc20a6

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

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-06-16 02:11:26 +02:00
valadaptive
54fded362d Clamp text cursor positions in the same places where we used to (#7081)
Closes #7077.

This fixes the problem shown in #7077 where clearing a `TextEdit`
wouldn't reset its cursor position. I've fixed that by adding back the
`TextCursorState::range` method, which clamps the selection range to
that of the passed `Galley`, and calling it in the same places where it
was called before #5785.

(/cc @juancampa)

* [x] I have followed the instructions in the PR template
2025-06-16 01:53:00 +02:00
ardocrat
742da95bd7 Support for Back button Key on Android (#7073)
When your press a Back button on Android (for example at
`native-activity`), [Winit translates this
key](47b938dbe7/src/platform_impl/android/keycodes.rs (L237C42-L237C53))
as `NamedKey::BrowserBack`. Added convertion to `Key::Escape` at
`egui-winit` module.

---------

Co-authored-by: Advocat <advocat@ogr.local>
2025-06-16 01:28:27 +02:00
Lucas Meurer
4c04996a72 Fix missing repaint after consume_key (#7134)
Usually input events automatically trigger a repaint. But since
consume_key would remove the event egui would think there were no events
and not trigger a repaint. This fixes it by setting a flag on InputState
on consume_key.

* related: https://github.com/rerun-io/rerun/issues/10165
2025-06-13 14:06:50 +02:00
Lucas Meurer
5bc19f3ca3 Report image alt text as text if widget contains no other text (#7142)
- Same as https://github.com/emilk/egui/pull/7136 but now for atomics
2025-06-13 13:54:07 +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
Emil Ernerfeldt
f0abce9bb8 Button inherits the alt_text of the Image in it, if any (#7136)
If a `Button` has an `Image` in it (and no text), then the
`Image::alt_text` will be used as the accessibility label for the
button.
2025-06-11 23:00:59 +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
Rinde van Lon
cfb10a04f5 Improve ComboBox doc example (#7116)
Improves the `ComboBox` example with some code that shows how to handle
changes in the `ComboBox`’s selection. The approach is based on the
advice given in https://github.com/emilk/egui/discussions/923 . I hope
this saves future me (and hopefully others) a web search for how to do
this.

* [x] I have followed the instructions in the PR template
2025-06-11 12:01:34 +02:00
Emil Ernerfeldt
209e818bd8 Improve deprecation message for old egui::menu 2025-06-07 10:24:28 -07:00
Emil Ernerfeldt
6e34152fa0 Add Context::format_modifiers (#7125)
Convenience
2025-06-07 19:22:16 +02:00
Emil Ernerfeldt
53098fad7b Support vertical-only scrolling by holding down Alt (#7124)
* Closes https://github.com/emilk/egui/issues/7120

You can now zoom only the X axis by holding down shift, and zoom only
the Y axis by holding down ALT.

In summary

* `Shift`: horizontal
* `Alt`: vertical
* `Ctrl`: zoom (`Cmd` on Mac)

Thus follows:
* `scroll`: pan both axis (at least for trackpads and mice with two-axis
scroll)
* `Shift + scroll`: pan only horizontal axis
* `Alt + scroll`: pan only vertical axis
* `Ctrl + scroll`: zoom all axes
* `Ctrl + Shift + scroll`: zoom only horizontal axis
* `Ctrl + Alt + scroll`: zoom only vertical axis

This is provided the application uses `zoom_delta_2d` for its zooming
needs.

The modifiers are exposed in `InputOptions`, but it is strongly
recommended that you do not change them.

## Testing
Unfortunately we have no nice way of testing this in egui.
But I've tested it in `egui_plot`.
2025-06-07 19:18:13 +02:00
Emil Ernerfeldt
1d5b011793 Add OperatingSystem::is_mac (#7122)
* Part of https://github.com/emilk/egui/issues/7120
2025-06-07 18:36:23 +02:00
Emil Ernerfeldt
cbd9c60399 Add Modifiers::matches_any (#7123)
* Part of https://github.com/emilk/egui/issues/7120
2025-06-07 18:36:16 +02:00
Emil Ernerfeldt
9681644936 Move all input-related options into InputOptions (#7121) 2025-06-07 18:25:19 +02:00
Emil Ernerfeldt
92fea8a18f Remove things that have been deprecated for over a year (#7099)
Removes all things that were marked `#[deprecated]` more than 12 months
ago
2025-05-28 09:47:15 +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
da67465a6c Add Response::clicked_with_open_in_background (#7093)
Useful for buttons that should act as Hyperlinks
2025-05-26 19:44:55 +02:00
Emil Ernerfeldt
87de733da3 Better define the meaning of SizeHint (#7079) 2025-05-23 13:52:36 +02:00
Emil Ernerfeldt
ec8b41f7ec Make Image::paint_at pixel-perfect crisp for SVG images (#7078) 2025-05-23 10:15:17 +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
b05a40745f Bug fix: make sure end_pass is called for all loaders (#7072)
None of the built-in loaders does any cache eviction (yet), but 3rd
party ones might have
2025-05-21 19:52:59 +02:00
Abdellatif EL MIZEB
cb4acbc262 Fix typo in deprecation message for ComboBox::from_id_source (#7055)
This PR corrects the deprecation note on ComboBox::from_id_source:

Changed:
`#[deprecated = "Renamed id_salt"]`

To:
`#[deprecated = "Renamed from_id_salt"]`
2025-05-18 13:02:58 +02:00
Emil Ernerfeldt
81b7e7f05a Make the default spinner more high-res (#7044)
Make it nice and smooth when big
2025-05-11 22:15:07 +02:00
Lucas Meurer
120d736cfc Add ImageLoader::has_pending and wait_for_pending_images (#7030)
With kittest it was difficult to wait for images to be loaded before
taking a snapshot test.
This PR adds `Harness::with_wait_for_pending_images` (true by default)
which will cause `Harness::run` to sleep until all images are loaded (or
`HarnessBuilder::with_max_steps` is exceeded).

It also adds a new ImageLoader::has_pending and
BytesLoader::has_pending, which should be implemented if things are
loaded / decoded asynchronously.

It reverts https://github.com/emilk/egui/pull/6901 which was my previous
attempt to fix this (but this didn't work since only the tested crate is
compiled with cfg(test) and not it's dependencies)
2025-05-08 09:27:52 +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
7216d0e386 Use mimalloc for benchmarks (#7029)
`mimalloc` is a _much_ faster allocator, especially important when doing
a lot of small allocations (which egui does).

We use `mimalloc` in Rerun, and I recommend everyone to use it.

## The difference it makes

![image](https://github.com/user-attachments/assets/b22e0025-bc5e-4b3c-94e0-74ce46e86f85)
2025-05-06 17:54:06 +02:00
Lucas Meurer
5bb20f511e Fix links and text selection in horizontal_wrapped layout (#6905)
* Closes <https://github.com/emilk/egui/issues/6904>
* [x] I have followed the instructions in the PR template

This was broken in https://github.com/emilk/egui/pull/5411. Not sure if
this is the best fix or if `PlacedRow::rect` should be updated, but I
think it makes sense that PlacedRow::rect ignores leading space.
2025-05-06 17:40:18 +02:00
Lucas Meurer
71e0b0859c Make WidgetText smaller and faster (#6903)
* In preparation of #5830, this should reduce the performance impact of
that PR

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-05-06 17:35:56 +02:00
Lucas Meurer
fdaac16e4a Fix image button panicking with tiny available_space (#6900)
* Fixes <https://github.com/emilk/egui/issues/6772>
* [x] I have followed the instructions in the PR template
2025-04-30 10:40:50 +02:00
mitchmindtree
fed2ab5df3 feat: Add Scene::sense option for customising how Scene should respond to user input (#5893)
Allows for specifying how the `Scene` should respond to user input.

With #5892, closes #5891.

---

Edit: Failing tests unrelated and appear on master:
https://github.com/emilk/egui/actions/runs/14330259861/job/40164414607.

---------

Co-authored-by: Lucas Meurer <lucasmeurer96@gmail.com>
2025-04-29 12:07:39 +02:00
Gaelan McMillan
3a02963c33 Add macOS-specific has_shadow and with_has_shadow to ViewportBuilder (#6850)
* [X] I have followed the instructions in the PR template

This PR fixes a ghosting issue I encountered while making a native macOS
transparent overlay app using egui and eframe by exposing the [existing
macOS window attribute
`has_shadow`](https://docs.rs/winit/latest/winit/platform/macos/trait.WindowExtMacOS.html#tymethod.has_shadow)
to the `ViewportBuilder` via a new `with_has_shadow` option.

## Example of Ghosting Issue

### Before `ViewportBuilder::with_has_shadow`
By default, the underlying `winit` window's `.has_shadow()` defaults to
`true`.


https://github.com/user-attachments/assets/c3dcc2bd-535a-4960-918e-3ae5df503b12

### After `ViewportBuilder::with_has_shadow`


https://github.com/user-attachments/assets/484462a1-ea88-43e6-85b4-0bb9724e5f14

Source code for the above example can be found here:

https://github.com/gaelanmcmillan/egui-overlay-app-with-shadow-artifacts-example/blob/main/src/main.rs


### Further background
By default on macOS, `winit` windows have a drop-shadow effect. When
creating a fully transparent overlay GUI, this drop-shadow can create a
ghosting effect, as the window content has a drop shadow which is not
cleared by the app itself. This issue has been experienced by users of
`bevy`, another Rust project that has an upstream dependency on `winit`:
https://github.com/bevyengine/bevy/issues/18673
2025-04-29 12:02:42 +02:00
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