refactor(interactor,egui): pass pointer position down to interactions

This commit is contained in:
Mikolaj Wielgus 2024-10-19 02:10:41 +02:00
parent 1638a289ed
commit e62bac69ef
6 changed files with 54 additions and 39 deletions

View File

@ -1,3 +1,4 @@
use geo::point;
use std::{
future::Future,
io,
@ -6,7 +7,10 @@ use std::{
};
use unic_langid::{langid, LanguageIdentifier};
use topola::specctra::design::{LoadingError as SpecctraLoadingError, SpecctraDesign};
use topola::{
interactor::activity::InteractiveInput,
specctra::design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
};
use crate::{
config::Config, error_dialog::ErrorDialog, menu_bar::MenuBar, status_bar::StatusBar,
@ -62,19 +66,19 @@ impl App {
this
}
fn advance_state_by_dt(&mut self, dt: f32) {
self.update_counter += dt;
fn advance_state_by_dt(&mut self, interactive_input: &InteractiveInput) {
self.update_counter += interactive_input.dt;
while self.update_counter >= self.menu_bar.frame_timestep {
self.update_counter -= self.menu_bar.frame_timestep;
if let ControlFlow::Break(()) = self.update_state() {
if let ControlFlow::Break(()) = self.update_state(interactive_input) {
return;
}
}
}
fn update_state(&mut self) -> ControlFlow<()> {
fn update_state(&mut self, interactive_input: &InteractiveInput) -> ControlFlow<()> {
if let Ok(data) = self.content_channel.1.try_recv() {
match data {
Ok(design) => match Workspace::new(design, &self.translator) {
@ -112,7 +116,11 @@ impl App {
}
if let Some(workspace) = &mut self.maybe_workspace {
return workspace.update_state(&self.translator, &mut self.error_dialog);
return workspace.update_state(
&self.translator,
&mut self.error_dialog,
interactive_input,
);
}
ControlFlow::Break(())
@ -135,7 +143,13 @@ impl eframe::App for App {
self.maybe_workspace.as_mut(),
);
self.advance_state_by_dt(ctx.input(|i| i.stable_dt));
let pointer_pos = self.viewport.transform.inverse()
* ctx.input(|i| i.pointer.latest_pos().unwrap_or_default());
self.advance_state_by_dt(&InteractiveInput {
pointer_pos: point! {x: pointer_pos.x as f64, y: pointer_pos.y as f64},
dt: ctx.input(|i| i.stable_dt),
});
self.status_bar.update(
ctx,

View File

@ -8,10 +8,7 @@ use topola::{
autorouter::{
execution::Command, invoker::InvokerError, selection::Selection, AutorouterOptions,
},
interactor::{
activity::{ActivityContext, ActivityStepperWithStatus},
interaction::InteractionContext,
},
interactor::activity::{ActivityContext, ActivityStepperWithStatus, InteractiveInput},
router::RouterOptions,
specctra::design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
stepper::Abort,
@ -277,7 +274,7 @@ impl MenuBar {
} else if actions.edit.redo.consume_key_triggered(ctx, ui) {
workspace.interactor.redo();
} else if actions.edit.abort.consume_key_triggered(ctx, ui) {
workspace.interactor.abort()
workspace.interactor.abort();
} else if actions.place.place_via.consume_key_enabled(
ctx,
ui,

View File

@ -6,8 +6,7 @@ use std::{
use topola::{
autorouter::{history::History, invoker::Invoker, Autorouter},
interactor::{
activity::{ActivityContext, ActivityStepperWithStatus},
interaction::InteractionContext,
activity::{ActivityContext, ActivityStepperWithStatus, InteractiveInput},
Interactor,
},
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
@ -59,6 +58,7 @@ impl Workspace {
&mut self,
tr: &Translator,
error_dialog: &mut ErrorDialog,
interactive_input: &InteractiveInput,
) -> ControlFlow<()> {
if let Ok(data) = self.history_channel.1.try_recv() {
match data {
@ -84,7 +84,7 @@ impl Workspace {
}
}
match self.interactor.update() {
match self.interactor.update(interactive_input) {
ControlFlow::Continue(()) => ControlFlow::Continue(()),
ControlFlow::Break(Ok(())) => ControlFlow::Break(()),
ControlFlow::Break(Err(err)) => {

View File

@ -1,5 +1,6 @@
use std::ops::ControlFlow;
use geo::Point;
use thiserror::Error;
use crate::{
@ -12,13 +13,18 @@ use crate::{
board::mesadata::AccessMesadata,
drawing::graph::PrimitiveIndex,
geometry::primitive::PrimitiveShape,
interactor::interaction::{InteractionContext, InteractionError, InteractionStepper},
interactor::interaction::{InteractionError, InteractionStepper},
router::{navcord::NavcordStepper, navmesh::Navmesh},
stepper::{Abort, Step},
};
pub struct InteractiveInput {
pub pointer_pos: Point,
pub dt: f32,
}
pub struct ActivityContext<'a, M: AccessMesadata> {
pub interaction: InteractionContext,
pub interactive_input: &'a InteractiveInput,
pub invoker: &'a mut Invoker<M>,
}
@ -43,9 +49,7 @@ impl<M: AccessMesadata> Step<ActivityContext<'_, M>, String> for ActivityStepper
context: &mut ActivityContext<M>,
) -> Result<ControlFlow<String>, ActivityError> {
match self {
ActivityStepper::Interaction(interaction) => {
Ok(interaction.step(&mut context.interaction)?)
}
ActivityStepper::Interaction(interaction) => Ok(interaction.step(context)?),
ActivityStepper::Execution(execution) => Ok(execution.step(context.invoker)?),
}
}
@ -54,9 +58,7 @@ impl<M: AccessMesadata> Step<ActivityContext<'_, M>, String> for ActivityStepper
impl<M: AccessMesadata> Abort<ActivityContext<'_, M>> for ActivityStepper {
fn abort(&mut self, context: &mut ActivityContext<M>) {
match self {
ActivityStepper::Interaction(interaction) => {
interaction.abort(&mut context.interaction)
}
ActivityStepper::Interaction(interaction) => interaction.abort(context),
ActivityStepper::Execution(execution) => {
execution.finish(context.invoker);
} // TODO.

View File

@ -4,17 +4,14 @@ use thiserror::Error;
use crate::{
autorouter::invoker::{GetGhosts, GetMaybeNavcord, GetMaybeNavmesh, GetObstacles},
board::mesadata::AccessMesadata,
drawing::graph::PrimitiveIndex,
geometry::primitive::PrimitiveShape,
router::{navcord::NavcordStepper, navmesh::Navmesh},
stepper::{Abort, Step},
};
pub struct InteractionContext {
// Empty for now.
// For example, this will contain mouse pointer position.
// (we will need an additional struct to hold a reference to a `Board<...>`)
}
use super::activity::ActivityContext;
#[derive(Error, Debug, Clone)]
pub enum InteractionError {
@ -29,19 +26,19 @@ pub enum InteractionStepper {
// - interactively moving a footprint.
}
impl Step<InteractionContext, String> for InteractionStepper {
impl<'a, M: AccessMesadata> Step<ActivityContext<'a, M>, String> for InteractionStepper {
type Error = InteractionError;
fn step(
&mut self,
context: &mut InteractionContext,
context: &mut ActivityContext<M>,
) -> Result<ControlFlow<String>, InteractionError> {
Ok(ControlFlow::Break(String::from("")))
}
}
impl Abort<InteractionContext> for InteractionStepper {
fn abort(&mut self, context: &mut InteractionContext) {
impl<'a, M: AccessMesadata> Abort<ActivityContext<'a, M>> for InteractionStepper {
fn abort(&mut self, context: &mut ActivityContext<M>) {
todo!();
}
}

View File

@ -10,9 +10,8 @@ use crate::{
Autorouter,
},
board::{mesadata::AccessMesadata, Board},
interactor::{
activity::{ActivityContext, ActivityError, ActivityStepperWithStatus},
interaction::InteractionContext,
interactor::activity::{
ActivityContext, ActivityError, ActivityStepperWithStatus, InteractiveInput,
},
stepper::{Abort, Step},
};
@ -51,8 +50,11 @@ impl<M: AccessMesadata> Interactor<M> {
pub fn abort(&mut self) {
if let Some(ref mut activity) = self.activity {
activity.abort(&mut ActivityContext {
interaction: InteractionContext {},
activity.abort(&mut ActivityContext::<M> {
interactive_input: &InteractiveInput {
pointer_pos: [0.0, 0.0].into(),
dt: 0.0,
},
invoker: &mut self.invoker,
});
}
@ -62,10 +64,13 @@ impl<M: AccessMesadata> Interactor<M> {
self.invoker.replay(history);
}
pub fn update(&mut self) -> ControlFlow<Result<(), ActivityError>> {
pub fn update(
&mut self,
interactive_input: &InteractiveInput,
) -> ControlFlow<Result<(), ActivityError>> {
if let Some(ref mut activity) = self.activity {
return match activity.step(&mut ActivityContext {
interaction: InteractionContext {},
interactive_input,
invoker: &mut self.invoker,
}) {
Ok(ControlFlow::Continue(())) => ControlFlow::Continue(()),