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
This commit is contained in:
Emil Ernerfeldt 2025-06-16 08:30:46 +02:00 committed by GitHub
parent 699be07978
commit 06760e1b08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 21 deletions

View File

@ -35,7 +35,7 @@ You can test your code locally by running `./scripts/check.sh`.
There are snapshots test that might need to be updated. There are snapshots test that might need to be updated.
Run the tests with `UPDATE_SNAPSHOTS=true cargo test --workspace --all-features` to update all of them. Run the tests with `UPDATE_SNAPSHOTS=true cargo test --workspace --all-features` to update all of them.
If CI keeps complaining about snapshots (which could happen if you don't use macOS, snapshots in CI are currently If CI keeps complaining about snapshots (which could happen if you don't use macOS, snapshots in CI are currently
rendered with macOS), you can instead run `./scripts/update_snapshots_from_ci.sh` to update your local snapshots from rendered with macOS), you can instead run `./scripts/update_snapshots_from_ci.sh` to update your local snapshots from
the last CI run of your PR (which will download the `test_results` artefact). the last CI run of your PR (which will download the `test_results` artefact).
For more info about the tests see [egui_kittest](./crates/egui_kittest/README.md). For more info about the tests see [egui_kittest](./crates/egui_kittest/README.md).
Snapshots and other big files are stored with git lfs. See [Working with git lfs](#working-with-git-lfs) for more info. Snapshots and other big files are stored with git lfs. See [Working with git lfs](#working-with-git-lfs) for more info.
@ -125,6 +125,7 @@ While using an immediate mode gui is simple, implementing one is a lot more tric
* Flip `if !condition {} else {}` * Flip `if !condition {} else {}`
* Sets of things should be lexicographically sorted (e.g. crate dependencies in `Cargo.toml`) * Sets of things should be lexicographically sorted (e.g. crate dependencies in `Cargo.toml`)
* Put each type in their own file, unless they are trivial (e.g. a `struct` with no `impl`) * Put each type in their own file, unless they are trivial (e.g. a `struct` with no `impl`)
* Put most generic arguments first (e.g. `Context`), and most specific last
* Break the above rules when it makes sense * Break the above rules when it makes sense

View File

@ -61,7 +61,7 @@ pub fn show_tooltip_at_pointer<R>(
widget_id: Id, widget_id: Id,
add_contents: impl FnOnce(&mut Ui) -> R, add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> { ) -> Option<R> {
Tooltip::new(widget_id, ctx.clone(), PopupAnchor::Pointer, parent_layer) Tooltip::new(ctx.clone(), parent_layer, widget_id, PopupAnchor::Pointer)
.gap(12.0) .gap(12.0)
.show(add_contents) .show(add_contents)
.map(|response| response.inner) .map(|response| response.inner)
@ -78,7 +78,7 @@ pub fn show_tooltip_for<R>(
widget_rect: &Rect, widget_rect: &Rect,
add_contents: impl FnOnce(&mut Ui) -> R, add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> { ) -> Option<R> {
Tooltip::new(widget_id, ctx.clone(), *widget_rect, parent_layer) Tooltip::new(ctx.clone(), parent_layer, widget_id, *widget_rect)
.show(add_contents) .show(add_contents)
.map(|response| response.inner) .map(|response| response.inner)
} }
@ -94,7 +94,7 @@ pub fn show_tooltip_at<R>(
suggested_position: Pos2, suggested_position: Pos2,
add_contents: impl FnOnce(&mut Ui) -> R, add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> { ) -> Option<R> {
Tooltip::new(widget_id, ctx.clone(), suggested_position, parent_layer) Tooltip::new(ctx.clone(), parent_layer, widget_id, suggested_position)
.show(add_contents) .show(add_contents)
.map(|response| response.inner) .map(|response| response.inner)
} }

View File

@ -7,26 +7,31 @@ use emath::Vec2;
pub struct Tooltip<'a> { pub struct Tooltip<'a> {
pub popup: Popup<'a>, pub popup: Popup<'a>,
layer_id: LayerId,
widget_id: Id, /// The layer of the parent widget.
parent_layer: LayerId,
/// The id of the widget that owns this tooltip.
parent_widget: Id,
} }
impl Tooltip<'_> { impl Tooltip<'_> {
/// Show a tooltip that is always open /// Show a tooltip that is always open.
pub fn new( pub fn new(
widget_id: Id,
ctx: Context, ctx: Context,
parent_layer: LayerId,
parent_widget: Id,
anchor: impl Into<PopupAnchor>, anchor: impl Into<PopupAnchor>,
layer_id: LayerId,
) -> Self { ) -> Self {
let width = ctx.style().spacing.tooltip_width;
Self { Self {
// TODO(lucasmerlin): Set width somehow (we're missing context here) popup: Popup::new(parent_widget, ctx, anchor.into(), parent_layer)
popup: Popup::new(widget_id, ctx, anchor.into(), layer_id)
.kind(PopupKind::Tooltip) .kind(PopupKind::Tooltip)
.gap(4.0) .gap(4.0)
.width(width)
.sense(Sense::hover()), .sense(Sense::hover()),
layer_id, parent_layer,
widget_id, parent_widget,
} }
} }
@ -39,8 +44,8 @@ impl Tooltip<'_> {
.sense(Sense::hover()); .sense(Sense::hover());
Self { Self {
popup, popup,
layer_id: response.layer_id, parent_layer: response.layer_id,
widget_id: response.id, parent_widget: response.id,
} }
} }
@ -96,8 +101,8 @@ impl Tooltip<'_> {
pub fn show<R>(self, content: impl FnOnce(&mut crate::Ui) -> R) -> Option<InnerResponse<R>> { pub fn show<R>(self, content: impl FnOnce(&mut crate::Ui) -> R) -> Option<InnerResponse<R>> {
let Self { let Self {
mut popup, mut popup,
layer_id: parent_layer, parent_layer,
widget_id, parent_widget,
} = self; } = self;
if !popup.is_open() { if !popup.is_open() {
@ -111,11 +116,11 @@ impl Tooltip<'_> {
fs.layers fs.layers
.entry(parent_layer) .entry(parent_layer)
.or_default() .or_default()
.widget_with_tooltip = Some(widget_id); .widget_with_tooltip = Some(parent_widget);
fs.tooltips fs.tooltips
.widget_tooltips .widget_tooltips
.get(&widget_id) .get(&parent_widget)
.copied() .copied()
.unwrap_or(PerWidgetTooltipState { .unwrap_or(PerWidgetTooltipState {
bounding_rect: rect, bounding_rect: rect,
@ -123,7 +128,7 @@ impl Tooltip<'_> {
}) })
}); });
let tooltip_area_id = Self::tooltip_id(widget_id, state.tooltip_count); let tooltip_area_id = Self::tooltip_id(parent_widget, state.tooltip_count);
popup = popup.anchor(state.bounding_rect).id(tooltip_area_id); popup = popup.anchor(state.bounding_rect).id(tooltip_area_id);
let response = popup.show(|ui| { let response = popup.show(|ui| {
@ -144,7 +149,7 @@ impl Tooltip<'_> {
response response
.response .response
.ctx .ctx
.pass_state_mut(|fs| fs.tooltips.widget_tooltips.insert(widget_id, state)); .pass_state_mut(|fs| fs.tooltips.widget_tooltips.insert(parent_widget, state));
Self::remember_that_tooltip_was_shown(&response.response.ctx); Self::remember_that_tooltip_was_shown(&response.response.ctx);
} }