Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Plugin::run() with an egui:Ui #197

Closed
abey79 opened this issue Oct 23, 2024 · 2 comments · Fixed by #205
Closed

Provide Plugin::run() with an egui:Ui #197

abey79 opened this issue Oct 23, 2024 · 2 comments · Fixed by #205

Comments

@abey79
Copy link
Contributor

abey79 commented Oct 23, 2024

Plugins are currently only provided with a painter. Although this is sufficient for drawing, it may building interactive element more complicated, in particular tooltips.

My (possibly naive) suggestion would be:

  • in Map::ui(), allocate a child ui that uses the provided Ui's available_size().
  • pass this child ui directly to Plugin::run(), instead of the Response and Painter (both of which can be obtained from the Ui.

That would, of course, be a breaking change. If that's a concern, one could add a Plugin::run_ui() method which by default delegates to the existing Plugin::run() without changing its signature.

Would you accept such a PR? If so, would be ok with the breaking change or prefer the work-around?

@abey79 abey79 changed the title Provide Plugin with an egui:Ui Provide Plugin::run() with an egui:Ui Oct 23, 2024
@podusowski
Copy link
Owner

We could try this. In general, I was debating with myself what the Map should actually be in the egui;s terminology. Whether it should be a widget, or maybe some sort of container where one could put widgets.

That would, of course, be a breaking change. If that's a concern, one could add a Plugin::run_ui() method which by default delegates to the existing Plugin::run() without changing its signature.

It's fine, I don't mind making breaking changes at this moment.

@abey79
Copy link
Contributor Author

abey79 commented Oct 25, 2024

In a sense, this resemble much a egui::ScrollArea with some background. However, ScrollArea relies on internal egui::Ui stuff and couldn't be implemented externally with the current API (iirc). Also, I'm not sure it would work given the non-euclidian nature of the coordinate system.

Regardless, I wonder if there would be a path to a closure-based API would feel more natural for egui. Something like:

fn some_ui(ui: &mut eguiUi) {
    walkers::Map::new(tile_manager, map_memory)
        .center(centre_position)
        .show(ui, |projector| {
            // create a Ui whose min pos is at provided coordinates and max_rect accounts for the size of the map widget
            projector.ui_at(lat, lon).label("hello");

	        // or more closure things like
            projector.show_at(lat, lon, egui::vec2(width, height), |ui| {
                ui.painter().circle(ui.max_rect().center(), ...);
            });
        });
}

Here show() would generally do something along the lines of:

  • allocate some space for the widget using the provided ui
  • draw the background
  • create a projector which contain the Ui
  • call the closure with that projector
  • the projector creates child Uis as required by calls to its API

egui_extras::Table relies quite a bit on these helper object with further closure. In a newer implementation of a table (here), we opted for a delegate trait instead, but my gut feeling is that approach is not warranted for walkers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants