mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 14:50:03 -04:00
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).
104 lines
3.5 KiB
TOML
104 lines
3.5 KiB
TOML
[package]
|
|
name = "egui"
|
|
version.workspace = true
|
|
authors = ["Emil Ernerfeldt <emil.ernerfeldt@gmail.com>"]
|
|
description = "An easy-to-use immediate mode GUI that runs on both web and native"
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
homepage = "https://github.com/emilk/egui"
|
|
license.workspace = true
|
|
readme = "../../README.md"
|
|
repository = "https://github.com/emilk/egui"
|
|
categories = ["gui", "game-development"]
|
|
keywords = ["gui", "imgui", "immediate", "portable", "gamedev"]
|
|
include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"]
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[package.metadata.docs.rs]
|
|
all-features = true
|
|
rustdoc-args = ["--generate-link-to-definition"]
|
|
|
|
[lib]
|
|
|
|
|
|
[features]
|
|
default = ["default_fonts"]
|
|
|
|
## Exposes detailed accessibility implementation required by platform
|
|
## accessibility APIs. Also requires support in the egui integration.
|
|
accesskit = ["dep:accesskit"]
|
|
|
|
## [`bytemuck`](https://docs.rs/bytemuck) enables you to cast [`epaint::Vertex`], [`emath::Vec2`] etc to `&[u8]`.
|
|
bytemuck = ["epaint/bytemuck"]
|
|
|
|
## Show a debug-ui on hover including the stacktrace to the hovered item.
|
|
## This is very useful in finding the code that creates a part of the UI.
|
|
## Does not work on web.
|
|
callstack = ["dep:backtrace"]
|
|
|
|
## [`cint`](https://docs.rs/cint) enables interoperability with other color libraries.
|
|
cint = ["epaint/cint"]
|
|
|
|
## Enable the [`hex_color`] macro.
|
|
color-hex = ["epaint/color-hex"]
|
|
|
|
## This will automatically detect deadlocks due to double-locking on the same thread.
|
|
## If your app freezes, you may want to enable this!
|
|
## Only affects [`epaint::mutex::RwLock`] (which egui uses a lot).
|
|
deadlock_detection = ["epaint/deadlock_detection"]
|
|
|
|
## If set, egui will use `include_bytes!` to bundle some fonts.
|
|
## If you plan on specifying your own fonts you may disable this feature.
|
|
default_fonts = ["epaint/default_fonts"]
|
|
|
|
## Turn on the `log` feature, that makes egui log some errors using the [`log`](https://docs.rs/log) crate.
|
|
log = ["dep:log", "epaint/log"]
|
|
|
|
## [`mint`](https://docs.rs/mint) enables interoperability with other math libraries such as [`glam`](https://docs.rs/glam) and [`nalgebra`](https://docs.rs/nalgebra).
|
|
mint = ["epaint/mint"]
|
|
|
|
## Enable persistence of memory (window positions etc).
|
|
persistence = ["serde", "epaint/serde", "ron"]
|
|
|
|
|
|
## Enable parallel tessellation using [`rayon`](https://docs.rs/rayon).
|
|
##
|
|
## This can help performance for graphics-intense applications.
|
|
rayon = ["epaint/rayon"]
|
|
|
|
## Allow serialization using [`serde`](https://docs.rs/serde).
|
|
serde = ["dep:serde", "epaint/serde", "accesskit?/serde"]
|
|
|
|
## Change Vertex layout to be compatible with unity
|
|
unity = ["epaint/unity"]
|
|
|
|
## Override and disable the unity feature
|
|
## This exists, so that when testing with --all-features, snapshots render correctly.
|
|
_override_unity = ["epaint/_override_unity"]
|
|
|
|
|
|
[dependencies]
|
|
emath = { workspace = true, default-features = false }
|
|
epaint = { workspace = true, default-features = false }
|
|
|
|
ahash.workspace = true
|
|
bitflags.workspace = true
|
|
nohash-hasher.workspace = true
|
|
profiling.workspace = true
|
|
smallvec.workspace = true
|
|
unicode-segmentation.workspace = true
|
|
|
|
#! ### Optional dependencies
|
|
accesskit = { workspace = true, optional = true }
|
|
|
|
backtrace = { workspace = true, optional = true }
|
|
|
|
## Enable this when generating docs.
|
|
document-features = { workspace = true, optional = true }
|
|
|
|
log = { workspace = true, optional = true }
|
|
ron = { workspace = true, optional = true }
|
|
serde = { workspace = true, optional = true, features = ["derive", "rc"] }
|