Skip to content

Commit

Permalink
Pas an owned value and an egui::Ui to Plugin::run()
Browse files Browse the repository at this point in the history
  • Loading branch information
abey79 committed Oct 28, 2024
1 parent f8e91f9 commit 6d0fdad
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Rust
name: Rust

on:
pull_request:
Expand Down
11 changes: 6 additions & 5 deletions demo/src/plugins.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use egui::{Color32, Painter, Response};
use egui::{Color32, Response, Ui};
use walkers::{
extras::{Image, Images, Place, Places, Style, Texture},
Plugin, Position, Projector,
Expand Down Expand Up @@ -57,7 +57,7 @@ pub fn images(images_plugin_data: &mut ImagesPluginData) -> impl Plugin {
pub struct CustomShapes {}

impl Plugin for CustomShapes {
fn run(&mut self, response: &Response, painter: Painter, projector: &Projector) {
fn run(self: Box<Self>, ui: &mut Ui, response: &Response, projector: &Projector) {
// Position of the point we want to put our shapes.
let position = places::capitol();

Expand All @@ -66,12 +66,13 @@ impl Plugin for CustomShapes {

let radius = 30.;


let hovered = response
.hover_pos()
.map(|hover_pos| hover_pos.distance(position) < radius)
.unwrap_or(false);

painter.circle_filled(
ui.painter().circle_filled(
position,
radius,
Color32::BLACK.gamma_multiply(if hovered { 0.5 } else { 0.2 }),
Expand Down Expand Up @@ -101,15 +102,15 @@ impl ClickWatcher {
}

impl Plugin for &mut ClickWatcher {
fn run(&mut self, response: &Response, painter: Painter, projector: &Projector) {
fn run(self: Box<Self>, ui: &mut Ui, response: &Response, projector: &Projector) {
if !response.changed() && response.clicked_by(egui::PointerButton::Primary) {
self.clicked_at = response
.interact_pointer_pos()
.map(|p| projector.unproject(p - response.rect.center()));
}

if let Some(position) = self.clicked_at {
painter.circle_filled(projector.project(position).to_pos2(), 5.0, Color32::BLUE);
ui.painter().circle_filled(projector.project(position).to_pos2(), 5.0, Color32::BLUE);
}
}
}
14 changes: 7 additions & 7 deletions walkers/src/extras/images.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::tiles::Texture;
use crate::{Plugin, Position};
use egui::epaint::emath::Rot2;
use egui::{Painter, Rect, Response, Vec2};
use egui::{Rect, Ui, Vec2, emath::Rot2, Response};

use crate::{Plugin, Position, tiles::Texture};

/// An image to be drawn on the map.
pub struct Image {
Expand Down Expand Up @@ -34,7 +33,8 @@ impl Image {
self.angle = Rot2::from_angle(angle);
}

pub fn draw(&self, _response: &Response, painter: Painter, projector: &crate::Projector) {
pub fn draw(&self, ui: &Ui, projector: &crate::Projector) {
let painter = ui.painter();
let rect = Rect::from_center_size(
projector.project(self.position).to_pos2(),
self.texture.size() * self.scale,
Expand All @@ -60,9 +60,9 @@ impl Images {
}

impl Plugin for Images {
fn run(&mut self, response: &Response, painter: Painter, projector: &crate::Projector) {
fn run(self: Box<Self>, ui: &mut Ui, _response: &Response, projector: &crate::Projector) {
for image in &self.images {
image.draw(response, painter.clone(), projector);
image.draw(ui, projector);
}
}
}
11 changes: 6 additions & 5 deletions walkers/src/extras/places.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use egui::{vec2, Align2, Color32, FontId, Painter, Response, Stroke};
use egui::{vec2, Align2, Color32, FontId, Ui, Stroke, Response};

use crate::{Plugin, Position};

Expand Down Expand Up @@ -45,8 +45,9 @@ pub struct Place {
}

impl Place {
fn draw(&self, _response: &Response, painter: Painter, projector: &crate::Projector) {
fn draw(&self, ui: &Ui, projector: &crate::Projector) {
let screen_position = projector.project(self.position);
let painter = ui.painter();

let label = painter.layout_no_wrap(
self.label.to_owned(),
Expand All @@ -70,7 +71,7 @@ impl Place {
painter.galley(
(screen_position + offset).to_pos2(),
label,
egui::Color32::BLACK,
Color32::BLACK,
);

painter.circle(
Expand Down Expand Up @@ -102,9 +103,9 @@ impl Places {
}

impl Plugin for Places {
fn run(&mut self, response: &Response, painter: Painter, projector: &crate::Projector) {
fn run(self: Box<Self>, ui: &mut Ui, _response: &Response, projector: &crate::Projector) {
for place in &self.places {
place.draw(response, painter.clone(), projector);
place.draw(ui, projector);
}
}
}
20 changes: 14 additions & 6 deletions walkers/src/map.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::{hash_map::Entry, HashMap};

use egui::{Mesh, Painter, Rect, Response, Sense, Ui, Vec2, Widget};
use egui::{Mesh, Rect, Response, Sense, Ui, UiBuilder, Vec2, Widget};

use crate::{
center::Center,
Expand All @@ -14,7 +14,15 @@ use crate::{
/// you can add it to the map with [`Map::with_plugin`]
pub trait Plugin {
/// Function called at each frame.
fn run(&mut self, response: &Response, painter: Painter, projector: &Projector);
///
/// The provided [`Ui`] has its [`egui::Ui::max_rect`] set to the full rect that was allocated
/// by the map widget. Implementations should typically use the provided [`Projector`] to
/// compute target screen coordinates and use one of the various egui methods to draw at these
/// coordinates instead of relying on [`egui:Ui`] layout system.
///
/// The provided [`Response`] is the response of the map widget itself and can be used to test
/// if the mouse is hovering or clicking on the map.
fn run(self: Box<Self>, ui: &mut Ui, response: &Response, projector: &Projector);
}

/// The actual map widget. Instances are to be created on each frame, as all necessary state is
Expand Down Expand Up @@ -223,10 +231,10 @@ impl Widget for Map<'_, '_, '_> {
}
}

for mut plugin in self.plugins {
let projector = Projector::new(response.rect, self.memory, self.my_position);

plugin.run(&response, painter.to_owned(), &projector);
let projector = Projector::new(response.rect, self.memory, self.my_position);
for (idx, plugin) in self.plugins.into_iter().enumerate() {
let mut child_ui = ui.new_child(UiBuilder::new().max_rect(rect).id_salt(idx));
plugin.run(&mut child_ui, &response, &projector);
}

response
Expand Down

0 comments on commit 6d0fdad

Please sign in to comment.