egui: keep activity status after activity finished

This commit is contained in:
Alain Emilia Anna Zscheile 2024-10-05 13:41:06 +02:00
parent 76537e7dfa
commit 8a372c4a7a
5 changed files with 156 additions and 155 deletions

View File

@ -106,21 +106,29 @@ impl GetObstacles for ActivityStepper {
}
}
#[derive(Default)]
pub struct ActivityStepperWithStatus {
activity: ActivityStepper,
maybe_status: Option<Poll<String>>,
pub maybe_activity: Option<ActivityStepper>,
pub maybe_status: Option<Poll<String>>,
}
impl ActivityStepperWithStatus {
pub fn new_execution(execution: ExecutionStepper) -> ActivityStepperWithStatus {
Self {
activity: ActivityStepper::Execution(execution),
maybe_activity: Some(ActivityStepper::Execution(execution)),
maybe_status: None,
}
}
pub fn maybe_status(&self) -> Option<Poll<String>> {
self.maybe_status.clone()
pub fn is_busy(&self) -> bool {
if self.maybe_activity.is_none() {
return false;
}
// this might be left over from a previous execution
//if let Some(Poll::Ready(_)) = &self.maybe_status {
// return false;
//}
true
}
}
@ -133,7 +141,14 @@ impl PollStep<ActivityContext<'_>, String> for ActivityStepperWithStatus {
&mut self,
context: &mut ActivityContext<'_>,
) -> Poll<Result<String, ActivityError>> {
let res = self.activity.poll_step(context);
let res = match &mut self.maybe_activity {
None => return Poll::Pending,
Some(act) => act.poll_step(context),
};
// fused stepping
if let Poll::Ready(_) = &res {
self.maybe_activity = None;
}
self.maybe_status = match &res {
Poll::Pending => Some(Poll::Pending),
Poll::Ready(Ok(msg)) => Some(Poll::Ready(msg.clone())),
@ -145,31 +160,39 @@ impl PollStep<ActivityContext<'_>, String> for ActivityStepperWithStatus {
impl Abort<ActivityContext<'_>> for ActivityStepperWithStatus {
fn abort(&mut self, context: &mut ActivityContext<'_>) {
if let Some(mut act) = self.maybe_activity.take() {
self.maybe_status = Some(Poll::Ready("aborted".to_string()));
self.activity.abort(context);
act.abort(context);
}
}
}
impl GetMaybeNavmesh for ActivityStepperWithStatus {
fn maybe_navmesh(&self) -> Option<&Navmesh> {
self.activity.maybe_navmesh()
self.maybe_activity.as_ref()?.maybe_navmesh()
}
}
impl GetMaybeTrace for ActivityStepperWithStatus {
fn maybe_trace(&self) -> Option<&TraceStepper> {
self.activity.maybe_trace()
self.maybe_activity.as_ref()?.maybe_trace()
}
}
impl GetGhosts for ActivityStepperWithStatus {
fn ghosts(&self) -> &[PrimitiveShape] {
self.activity.ghosts()
match &self.maybe_activity {
None => &[],
Some(act) => act.ghosts(),
}
}
}
impl GetObstacles for ActivityStepperWithStatus {
fn obstacles(&self) -> &[PrimitiveIndex] {
self.activity.obstacles()
match &self.maybe_activity {
None => &[],
Some(act) => act.obstacles(),
}
}
}

View File

@ -40,7 +40,7 @@ pub struct App {
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
maybe_activity: Option<ActivityStepperWithStatus>,
activity: ActivityStepperWithStatus,
content_channel: (
Sender<Result<SpecctraDesign, SpecctraLoadingError>>,
@ -71,7 +71,7 @@ impl Default for App {
translator: Translator::new(langid!("en-US")),
maybe_overlay: None,
arc_mutex_maybe_invoker: Arc::new(Mutex::new(None)),
maybe_activity: None,
activity: ActivityStepperWithStatus::default(),
content_channel: channel(),
history_channel: channel(),
viewport: Viewport::new(),
@ -171,8 +171,11 @@ impl App {
}
}
if let Some(ref mut activity) = self.maybe_activity {
return match activity.poll_step(&mut ActivityContext {
if self.activity.maybe_activity.is_none() {
return false;
}
return match self.activity.poll_step(&mut ActivityContext {
interaction: InteractionContext {},
invoker,
}) {
@ -182,12 +185,11 @@ impl App {
self.error_dialog
.push_error("tr-module-invoker", format!("{}", err));
}
self.maybe_activity = None;
self.activity.maybe_activity = None;
false
}
};
}
}
false
}
@ -233,7 +235,7 @@ impl eframe::App for App {
self.content_channel.0.clone(),
self.history_channel.0.clone(),
self.arc_mutex_maybe_invoker.clone(),
&mut self.maybe_activity,
&mut self.activity,
&mut self.viewport,
&mut self.maybe_overlay,
&self.maybe_design,
@ -242,7 +244,7 @@ impl eframe::App for App {
self.advance_state_by_dt(ctx.input(|i| i.stable_dt));
self.status_bar
.update(ctx, &self.translator, &self.viewport, &self.maybe_activity);
.update(ctx, &self.translator, &self.viewport, &self.activity);
if self.menu_bar.show_layer_manager {
if let Some(ref mut layers) = self.maybe_layers {
@ -258,7 +260,7 @@ impl eframe::App for App {
ctx,
&self.menu_bar,
&mut self.arc_mutex_maybe_invoker.lock().unwrap(),
&mut self.maybe_activity,
&mut self.activity,
&mut self.maybe_overlay,
&self.maybe_layers,
);

View File

@ -21,7 +21,7 @@ use topola::{
use crate::{
action::{Action, Switch, Trigger},
activity::{ActivityContext, ActivityStepperWithStatus},
activity::{ActivityContext, ActivityStepper, ActivityStepperWithStatus},
app::{execute, handle_file},
interaction::InteractionContext,
overlay::Overlay,
@ -67,7 +67,7 @@ impl MenuBar {
content_sender: Sender<Result<SpecctraDesign, SpecctraLoadingError>>,
history_sender: Sender<std::io::Result<Result<History, serde_json::Error>>>,
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
maybe_activity: &mut Option<ActivityStepperWithStatus>,
activity: &mut ActivityStepperWithStatus,
viewport: &mut Viewport,
maybe_overlay: &mut Option<Overlay>,
maybe_design: &Option<SpecctraDesign>,
@ -331,41 +331,34 @@ impl MenuBar {
invoker.redo();
}
} else if abort.consume_key_triggered(ctx, ui) {
if let Some(activity) = maybe_activity {
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
activity.abort(&mut ActivityContext {
interaction: InteractionContext {},
invoker,
});
}
}
} else if remove_bands.consume_key_triggered(ctx, ui) {
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
}) {
if !activity.is_busy() {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
maybe_overlay,
) {
let selection = overlay.take_selection();
*maybe_activity = Some(ActivityStepperWithStatus::new_execution(
invoker.execute_stepper(Command::RemoveBands(
selection.band_selection,
))?,
));
activity.maybe_activity =
Some(ActivityStepper::Execution(invoker.execute_stepper(
Command::RemoveBands(selection.band_selection),
)?));
}
}
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
} else if autoroute.consume_key_triggered(ctx, ui) {
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
}) {
if !activity.is_busy() {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
maybe_overlay,
) {
let selection = overlay.take_selection();
*maybe_activity = Some(ActivityStepperWithStatus::new_execution(
activity.maybe_activity = Some(ActivityStepper::Execution(
invoker.execute_stepper(Command::Autoroute(
selection.pin_selection,
self.autorouter_options,
@ -374,15 +367,13 @@ impl MenuBar {
}
}
} else if compare_detours.consume_key_triggered(ctx, ui) {
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
}) {
if !activity.is_busy() {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
maybe_overlay,
) {
let selection = overlay.take_selection();
*maybe_activity = Some(ActivityStepperWithStatus::new_execution(
activity.maybe_activity = Some(ActivityStepper::Execution(
invoker.execute_stepper(Command::CompareDetours(
selection.pin_selection,
self.autorouter_options,
@ -391,19 +382,16 @@ impl MenuBar {
}
}
} else if measure_length.consume_key_triggered(ctx, ui) {
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
}) {
if !activity.is_busy() {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
maybe_overlay,
) {
let selection = overlay.take_selection();
*maybe_activity = Some(ActivityStepperWithStatus::new_execution(
invoker.execute_stepper(Command::MeasureLength(
selection.band_selection,
))?,
));
activity.maybe_activity =
Some(ActivityStepper::Execution(invoker.execute_stepper(
Command::MeasureLength(selection.band_selection),
)?));
}
}
}

View File

@ -13,7 +13,7 @@ impl StatusBar {
ctx: &egui::Context,
tr: &Translator,
viewport: &Viewport,
maybe_activity: &Option<ActivityStepperWithStatus>,
activity: &ActivityStepperWithStatus,
) {
egui::TopBottomPanel::bottom("status_bar").show(ctx, |ui| {
let latest_pos = viewport.transform.inverse()
@ -21,10 +21,8 @@ impl StatusBar {
let mut message = String::new();
if let Some(activity) = maybe_activity {
if let Some(Poll::Ready(msg)) = activity.maybe_status() {
message = msg;
}
if let Some(Poll::Ready(msg)) = &activity.maybe_status {
message = msg.clone();
}
ui.label(format!(

View File

@ -42,7 +42,7 @@ impl Viewport {
ctx: &egui::Context,
top: &MenuBar,
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
maybe_activity: &mut Option<ActivityStepperWithStatus>,
activity: &mut ActivityStepperWithStatus,
maybe_overlay: &mut Option<Overlay>,
maybe_layers: &Option<Layers>,
) -> egui::Rect {
@ -50,7 +50,7 @@ impl Viewport {
ctx,
top,
maybe_invoker,
maybe_activity,
activity,
maybe_overlay,
maybe_layers,
);
@ -67,7 +67,7 @@ impl Viewport {
ctx: &egui::Context,
top: &MenuBar,
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
maybe_activity: &mut Option<ActivityStepperWithStatus>,
activity: &mut ActivityStepperWithStatus,
maybe_overlay: &mut Option<Overlay>,
maybe_layers: &Option<Layers>,
) -> egui::Rect {
@ -125,16 +125,10 @@ impl Viewport {
.contains_node(board, GenericNode::Primitive(primitive))
{
layers.highlight_colors[i]
} else {
if let Some(activity) = maybe_activity {
if activity.obstacles().contains(&primitive) {
} else if activity.obstacles().contains(&primitive) {
layers.highlight_colors[i]
} else {
layers.colors[i]
}
} else {
layers.colors[i]
}
};
painter.paint_primitive(&shape, color);
@ -180,7 +174,6 @@ impl Viewport {
}
if top.show_navmesh {
if let Some(activity) = maybe_activity {
if let Some(navmesh) = activity.maybe_navmesh() {
for edge in navmesh.edge_references() {
let mut from = PrimitiveIndex::from(navmesh.node_weight(edge.source()).unwrap().node)
@ -236,7 +229,6 @@ impl Viewport {
}
}
}
}
if top.show_bboxes {
let root_bbox3d = board.layout().drawing().rtree().root().envelope();
@ -245,8 +237,7 @@ impl Viewport {
painter.paint_bbox(root_bbox);
}
if let Some(activity) = maybe_activity {
for ghost in activity.ghosts().iter() {
for ghost in activity.ghosts() {
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
}
@ -271,7 +262,6 @@ impl Viewport {
}
}
}
}
viewport_rect
})