mirror of https://codeberg.org/topola/topola.git
chore(egui): get rid of unused imports
This commit is contained in:
parent
bff11a5617
commit
d03e5c63a0
|
|
@ -7,7 +7,6 @@ use topola::{
|
||||||
InvokerStatus,
|
InvokerStatus,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
board::mesadata::AccessMesadata,
|
|
||||||
drawing::graph::PrimitiveIndex,
|
drawing::graph::PrimitiveIndex,
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
router::{navmesh::Navmesh, trace::TraceStepper},
|
router::{navmesh::Navmesh, trace::TraceStepper},
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,15 @@
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
io,
|
io,
|
||||||
sync::{
|
sync::mpsc::{channel, Receiver, Sender},
|
||||||
mpsc::{channel, Receiver, Sender},
|
|
||||||
Arc, Mutex,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use unic_langid::{langid, LanguageIdentifier};
|
use unic_langid::{langid, LanguageIdentifier};
|
||||||
|
|
||||||
use topola::{
|
use topola::specctra::design::{LoadingError as SpecctraLoadingError, SpecctraDesign};
|
||||||
autorouter::{history::History, invoker::Invoker, Autorouter},
|
|
||||||
specctra::{
|
|
||||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
|
||||||
mesadata::SpecctraMesadata,
|
|
||||||
},
|
|
||||||
stepper::Step,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
config::Config, error_dialog::ErrorDialog, menu_bar::MenuBar, status_bar::StatusBar,
|
||||||
config::Config,
|
translator::Translator, viewport::Viewport, workspace::Workspace,
|
||||||
error_dialog::ErrorDialog,
|
|
||||||
interaction::InteractionContext,
|
|
||||||
layers::Layers,
|
|
||||||
menu_bar::MenuBar,
|
|
||||||
overlay::Overlay,
|
|
||||||
status_bar::StatusBar,
|
|
||||||
translator::Translator,
|
|
||||||
viewport::Viewport,
|
|
||||||
workspace::Workspace,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ use topola::{
|
||||||
stepper::{Abort, Step},
|
stepper::{Abort, Step},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::activity::ActivityStepperWithStatus;
|
|
||||||
|
|
||||||
pub struct InteractionContext {
|
pub struct InteractionContext {
|
||||||
// Empty for now.
|
// Empty for now.
|
||||||
// For example, this will contain mouse pointer position.
|
// For example, this will contain mouse pointer position.
|
||||||
|
|
@ -47,7 +45,7 @@ pub enum InteractionStepper {
|
||||||
impl Step<InteractionContext, InteractionStatus, InteractionError, ()> for InteractionStepper {
|
impl Step<InteractionContext, InteractionStatus, InteractionError, ()> for InteractionStepper {
|
||||||
fn step(
|
fn step(
|
||||||
&mut self,
|
&mut self,
|
||||||
invoker: &mut InteractionContext,
|
context: &mut InteractionContext,
|
||||||
) -> Result<InteractionStatus, InteractionError> {
|
) -> Result<InteractionStatus, InteractionError> {
|
||||||
Ok(InteractionStatus::Finished(String::from("")))
|
Ok(InteractionStatus::Finished(String::from("")))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,9 @@
|
||||||
use std::{
|
use std::{path::Path, sync::mpsc::Sender};
|
||||||
path::Path,
|
|
||||||
sync::{mpsc::Sender, Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{
|
autorouter::{execution::Command, invoker::InvokerError, AutorouterOptions},
|
||||||
execution::Command,
|
|
||||||
history::History,
|
|
||||||
invoker::{Invoker, InvokerError},
|
|
||||||
AutorouterOptions,
|
|
||||||
},
|
|
||||||
router::RouterOptions,
|
router::RouterOptions,
|
||||||
specctra::{
|
specctra::design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
||||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
|
||||||
mesadata::SpecctraMesadata,
|
|
||||||
},
|
|
||||||
stepper::Abort,
|
stepper::Abort,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -23,7 +12,6 @@ use crate::{
|
||||||
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
||||||
app::{execute, handle_file},
|
app::{execute, handle_file},
|
||||||
interaction::InteractionContext,
|
interaction::InteractionContext,
|
||||||
overlay::Overlay,
|
|
||||||
translator::Translator,
|
translator::Translator,
|
||||||
viewport::Viewport,
|
viewport::Viewport,
|
||||||
workspace::Workspace,
|
workspace::Workspace,
|
||||||
|
|
|
||||||
|
|
@ -1,390 +0,0 @@
|
||||||
use std::{
|
|
||||||
path::Path,
|
|
||||||
sync::{mpsc::Sender, Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use topola::{
|
|
||||||
autorouter::{
|
|
||||||
execution::Command,
|
|
||||||
history::History,
|
|
||||||
invoker::{Invoker, InvokerError},
|
|
||||||
AutorouterOptions,
|
|
||||||
},
|
|
||||||
router::RouterOptions,
|
|
||||||
specctra::{
|
|
||||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
|
||||||
mesadata::SpecctraMesadata,
|
|
||||||
},
|
|
||||||
stepper::Abort,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
action::{Action, Switch, Trigger},
|
|
||||||
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
|
||||||
app::{execute, handle_file},
|
|
||||||
interaction::InteractionContext,
|
|
||||||
overlay::Overlay,
|
|
||||||
translator::Translator,
|
|
||||||
viewport::Viewport,
|
|
||||||
workspace::Workspace,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct MenuBar {
|
|
||||||
pub autorouter_options: AutorouterOptions,
|
|
||||||
pub is_placing_via: bool,
|
|
||||||
pub show_ratsnest: bool,
|
|
||||||
pub show_navmesh: bool,
|
|
||||||
pub show_bboxes: bool,
|
|
||||||
pub show_origin_destination: bool,
|
|
||||||
pub show_layer_manager: bool,
|
|
||||||
pub frame_timestep: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MenuBar {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
autorouter_options: AutorouterOptions {
|
|
||||||
presort_by_pairwise_detours: false,
|
|
||||||
router_options: RouterOptions {
|
|
||||||
wrap_around_bands: true,
|
|
||||||
squeeze_through_under_bands: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
is_placing_via: false,
|
|
||||||
show_ratsnest: false,
|
|
||||||
show_navmesh: false,
|
|
||||||
show_bboxes: false,
|
|
||||||
show_origin_destination: false,
|
|
||||||
show_layer_manager: true,
|
|
||||||
frame_timestep: 0.1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(
|
|
||||||
&mut self,
|
|
||||||
ctx: &egui::Context,
|
|
||||||
tr: &Translator,
|
|
||||||
content_sender: Sender<Result<SpecctraDesign, SpecctraLoadingError>>,
|
|
||||||
viewport: &mut Viewport,
|
|
||||||
maybe_workspace: Option<&mut Workspace>,
|
|
||||||
) -> Result<(), InvokerError> {
|
|
||||||
let mut open_design = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-file-open"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::O,
|
|
||||||
));
|
|
||||||
let mut export_session = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-file-export-session-file"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::S,
|
|
||||||
));
|
|
||||||
let mut import_history = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-file-import-history"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::I,
|
|
||||||
));
|
|
||||||
let mut export_history = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-file-export-history"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::E,
|
|
||||||
));
|
|
||||||
let mut quit = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-file-quit"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::Q,
|
|
||||||
));
|
|
||||||
let mut undo = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-edit-undo"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::Z,
|
|
||||||
));
|
|
||||||
let mut redo = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-edit-redo"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::Y,
|
|
||||||
));
|
|
||||||
let mut abort = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-edit-abort"),
|
|
||||||
egui::Modifiers::NONE,
|
|
||||||
egui::Key::Escape,
|
|
||||||
));
|
|
||||||
let mut remove_bands = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-edit-remove-bands"),
|
|
||||||
egui::Modifiers::NONE,
|
|
||||||
egui::Key::Delete,
|
|
||||||
));
|
|
||||||
let mut place_via = Switch::new(Action::new(
|
|
||||||
tr.text("tr-menu-place-place-via"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::P,
|
|
||||||
));
|
|
||||||
let mut autoroute = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-route-autoroute"),
|
|
||||||
egui::Modifiers::CTRL,
|
|
||||||
egui::Key::A,
|
|
||||||
));
|
|
||||||
let mut compare_detours = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-inspect-compare-detours"),
|
|
||||||
egui::Modifiers::NONE,
|
|
||||||
egui::Key::Minus,
|
|
||||||
));
|
|
||||||
let mut measure_length = Trigger::new(Action::new(
|
|
||||||
tr.text("tr-menu-inspect-measure-length"),
|
|
||||||
egui::Modifiers::NONE,
|
|
||||||
egui::Key::Plus,
|
|
||||||
));
|
|
||||||
|
|
||||||
egui::TopBottomPanel::top("menu_bar")
|
|
||||||
.show(ctx, |ui| {
|
|
||||||
egui::menu::bar(ui, |ui| {
|
|
||||||
ui.menu_button(tr.text("tr-menu-file"), |ui| {
|
|
||||||
open_design.button(ctx, ui);
|
|
||||||
export_session.button(ctx, ui);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
import_history.button(ctx, ui);
|
|
||||||
export_history.button(ctx, ui);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
// "Quit" button wouldn't work on a Web page.
|
|
||||||
if !cfg!(target_arch = "wasm32") {
|
|
||||||
quit.button(ctx, ui);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.menu_button(tr.text("tr-menu-edit"), |ui| {
|
|
||||||
undo.button(ctx, ui);
|
|
||||||
redo.button(ctx, ui);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
abort.button(ctx, ui);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
remove_bands.button(ctx, ui);
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.menu_button(tr.text("tr-menu-view"), |ui| {
|
|
||||||
ui.toggle_value(
|
|
||||||
&mut viewport.scheduled_zoom_to_fit,
|
|
||||||
tr.text("tr-menu-view-zoom-to-fit"),
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
ui.checkbox(
|
|
||||||
&mut self.show_ratsnest,
|
|
||||||
tr.text("tr-menu-view-show-ratsnest"),
|
|
||||||
);
|
|
||||||
ui.checkbox(&mut self.show_navmesh, tr.text("tr-menu-view-show-navmesh"));
|
|
||||||
ui.checkbox(&mut self.show_bboxes, tr.text("tr-menu-view-show-bboxes"));
|
|
||||||
ui.checkbox(
|
|
||||||
&mut self.show_origin_destination,
|
|
||||||
tr.text("tr-menu-view-show-origin-destination"),
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
ui.checkbox(
|
|
||||||
&mut self.show_layer_manager,
|
|
||||||
tr.text("tr-menu-view-show-layer-manager"),
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
ui.label(tr.text("tr-menu-view-frame-timestep"));
|
|
||||||
ui.add(
|
|
||||||
egui::widgets::Slider::new(&mut self.frame_timestep, 0.0..=3.0)
|
|
||||||
.suffix(" s"),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.menu_button(tr.text("tr-menu-place"), |ui| {
|
|
||||||
place_via.toggle_widget(ctx, ui, &mut self.is_placing_via);
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.menu_button(tr.text("tr-menu-route"), |ui| {
|
|
||||||
autoroute.button(ctx, ui);
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
ui.menu_button(tr.text("tr-menu-options"), |ui| {
|
|
||||||
ui.checkbox(
|
|
||||||
&mut self.autorouter_options.presort_by_pairwise_detours,
|
|
||||||
tr.text("tr-menu-route-options-presort-by-pairwise-detours"),
|
|
||||||
);
|
|
||||||
ui.checkbox(
|
|
||||||
&mut self
|
|
||||||
.autorouter_options
|
|
||||||
.router_options
|
|
||||||
.squeeze_through_under_bands,
|
|
||||||
tr.text("tr-menu-route-options-squeeze-through-under-bands"),
|
|
||||||
);
|
|
||||||
ui.checkbox(
|
|
||||||
&mut self.autorouter_options.router_options.wrap_around_bands,
|
|
||||||
tr.text("tr-menu-route-options-wrap-around-bands"),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.menu_button(tr.text("tr-menu-inspect"), |ui| {
|
|
||||||
compare_detours.button(ctx, ui);
|
|
||||||
measure_length.button(ctx, ui);
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
egui::widgets::global_theme_preference_buttons(ui);
|
|
||||||
});
|
|
||||||
|
|
||||||
if open_design.consume_key_triggered(ctx, ui) {
|
|
||||||
// NOTE: On Linux, this requires Zenity to be installed on your system.
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
let task = rfd::AsyncFileDialog::new().pick_file();
|
|
||||||
|
|
||||||
execute(async move {
|
|
||||||
if let Some(file_handle) = task.await {
|
|
||||||
let data = handle_file(&file_handle)
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
.and_then(SpecctraDesign::load);
|
|
||||||
content_sender.send(data);
|
|
||||||
ctx.request_repaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if quit.consume_key_triggered(ctx, ui) {
|
|
||||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
|
||||||
} else if let Some(workspace) = maybe_workspace {
|
|
||||||
if export_session.consume_key_triggered(ctx, ui) {
|
|
||||||
let ctx = ui.ctx().clone();
|
|
||||||
let board = workspace.invoker.autorouter().board();
|
|
||||||
|
|
||||||
// FIXME: I don't know how to avoid buffering the entire exported file
|
|
||||||
let mut writebuf = vec![];
|
|
||||||
|
|
||||||
workspace.design.write_ses(board, &mut writebuf);
|
|
||||||
|
|
||||||
let mut dialog = rfd::AsyncFileDialog::new();
|
|
||||||
if let Some(filename) = Path::new(workspace.design.get_name()).file_stem() {
|
|
||||||
if let Some(filename) = filename.to_str() {
|
|
||||||
dialog = dialog.set_file_name(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let task = dialog
|
|
||||||
.add_filter(tr.text("tr-menu-open-specctra-session-file"), &["ses"])
|
|
||||||
.save_file();
|
|
||||||
|
|
||||||
execute(async move {
|
|
||||||
if let Some(file_handle) = task.await {
|
|
||||||
file_handle.write(&writebuf).await;
|
|
||||||
ctx.request_repaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if import_history.consume_key_triggered(ctx, ui) {
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
let task = rfd::AsyncFileDialog::new().pick_file();
|
|
||||||
let history_sender = workspace.history_channel.0.clone();
|
|
||||||
|
|
||||||
execute(async move {
|
|
||||||
if let Some(file_handle) = task.await {
|
|
||||||
let data = handle_file(&file_handle).await.and_then(|data| {
|
|
||||||
match serde_json::from_reader(data) {
|
|
||||||
Ok(history) => Ok(Ok(history)),
|
|
||||||
Err(err) if err.is_io() => Err(err.into()),
|
|
||||||
Err(err) => Ok(Err(err)),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
history_sender.send(data);
|
|
||||||
ctx.request_repaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if export_history.consume_key_triggered(ctx, ui) {
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
let task = rfd::AsyncFileDialog::new().save_file();
|
|
||||||
|
|
||||||
// FIXME: I don't think we should be buffering everything in a `Vec<u8>`.
|
|
||||||
let mut writebuf = vec![];
|
|
||||||
serde_json::to_writer_pretty(&mut writebuf, workspace.invoker.history());
|
|
||||||
|
|
||||||
execute(async move {
|
|
||||||
if let Some(file_handle) = task.await {
|
|
||||||
file_handle.write(&writebuf).await;
|
|
||||||
ctx.request_repaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if undo.consume_key_triggered(ctx, ui) {
|
|
||||||
workspace.invoker.undo();
|
|
||||||
} else if redo.consume_key_triggered(ctx, ui) {
|
|
||||||
workspace.invoker.redo();
|
|
||||||
} else if abort.consume_key_triggered(ctx, ui) {
|
|
||||||
if let Some(activity) = &mut workspace.maybe_activity {
|
|
||||||
<<<<<<< HEAD
|
|
||||||
activity.abort(&mut ActivityContext {
|
|
||||||
interaction: InteractionContext {},
|
|
||||||
invoker: &mut *workspace.invoker.lock().unwrap(),
|
|
||||||
});
|
|
||||||
=======
|
|
||||||
activity.abort(&mut workspace.invoker);
|
|
||||||
>>>>>>> 8938ce7 (egui/Workspace: get rid of unnecessary Arc<Mutex<...>>)
|
|
||||||
}
|
|
||||||
} else if remove_bands.consume_key_triggered(ctx, ui) {
|
|
||||||
if workspace.maybe_activity.as_mut().map_or(true, |activity| {
|
|
||||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
|
||||||
}) {
|
|
||||||
let selection = workspace.overlay.take_selection();
|
|
||||||
workspace.maybe_activity =
|
|
||||||
Some(ActivityStepperWithStatus::new_execution(
|
|
||||||
workspace.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 workspace.maybe_activity.as_mut().map_or(true, |activity| {
|
|
||||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
|
||||||
}) {
|
|
||||||
let selection = workspace.overlay.take_selection();
|
|
||||||
workspace.maybe_activity =
|
|
||||||
Some(ActivityStepperWithStatus::new_execution(
|
|
||||||
workspace.invoker.execute_stepper(Command::Autoroute(
|
|
||||||
selection.pin_selection,
|
|
||||||
self.autorouter_options,
|
|
||||||
))?,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else if compare_detours.consume_key_triggered(ctx, ui) {
|
|
||||||
if workspace.maybe_activity.as_mut().map_or(true, |activity| {
|
|
||||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
|
||||||
}) {
|
|
||||||
let selection = workspace.overlay.take_selection();
|
|
||||||
workspace.maybe_activity =
|
|
||||||
Some(ActivityStepperWithStatus::new_execution(
|
|
||||||
workspace.invoker.execute_stepper(Command::CompareDetours(
|
|
||||||
selection.pin_selection,
|
|
||||||
self.autorouter_options,
|
|
||||||
))?,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else if measure_length.consume_key_triggered(ctx, ui) {
|
|
||||||
if workspace.maybe_activity.as_mut().map_or(true, |activity| {
|
|
||||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
|
||||||
}) {
|
|
||||||
let selection = workspace.overlay.take_selection();
|
|
||||||
workspace.maybe_activity =
|
|
||||||
Some(ActivityStepperWithStatus::new_execution(
|
|
||||||
workspace.invoker.execute_stepper(Command::MeasureLength(
|
|
||||||
selection.band_selection,
|
|
||||||
))?,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok::<(), InvokerError>(())
|
|
||||||
})
|
|
||||||
.inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,10 +19,7 @@ use topola::{
|
||||||
specctra::mesadata::SpecctraMesadata,
|
specctra::mesadata::SpecctraMesadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{menu_bar::MenuBar, painter::Painter, workspace::Workspace};
|
||||||
activity::ActivityStepperWithStatus, layers::Layers, menu_bar::MenuBar, overlay::Overlay,
|
|
||||||
painter::Painter, workspace::Workspace,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Viewport {
|
pub struct Viewport {
|
||||||
pub transform: egui::emath::TSTransform,
|
pub transform: egui::emath::TSTransform,
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,8 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use std::{
|
|
||||||
future::Future,
|
|
||||||
io,
|
|
||||||
sync::{
|
|
||||||
mpsc::{channel, Receiver, Sender},
|
|
||||||
Arc, Mutex,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use unic_langid::{langid, LanguageIdentifier};
|
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{history::History, invoker::Invoker, Autorouter},
|
autorouter::{history::History, invoker::Invoker, Autorouter},
|
||||||
specctra::{
|
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
|
||||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
|
||||||
mesadata::SpecctraMesadata,
|
|
||||||
},
|
|
||||||
stepper::Step,
|
stepper::Step,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -25,7 +13,6 @@ use crate::{
|
||||||
layers::Layers,
|
layers::Layers,
|
||||||
overlay::Overlay,
|
overlay::Overlay,
|
||||||
translator::Translator,
|
translator::Translator,
|
||||||
viewport::Viewport,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A loaded design and associated structures
|
/// A loaded design and associated structures
|
||||||
|
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::{
|
|
||||||
future::Future,
|
|
||||||
io,
|
|
||||||
sync::{
|
|
||||||
mpsc::{channel, Receiver, Sender},
|
|
||||||
Arc, Mutex,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use unic_langid::{langid, LanguageIdentifier};
|
|
||||||
|
|
||||||
use topola::{
|
|
||||||
autorouter::{history::History, invoker::Invoker, Autorouter},
|
|
||||||
specctra::{
|
|
||||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
|
||||||
mesadata::SpecctraMesadata,
|
|
||||||
},
|
|
||||||
stepper::Step,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
|
||||||
error_dialog::ErrorDialog,
|
|
||||||
interaction::InteractionContext,
|
|
||||||
layers::Layers,
|
|
||||||
overlay::Overlay,
|
|
||||||
translator::Translator,
|
|
||||||
viewport::Viewport,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A loaded design and associated structures
|
|
||||||
pub struct Workspace {
|
|
||||||
pub design: SpecctraDesign,
|
|
||||||
pub layers: Layers,
|
|
||||||
pub overlay: Overlay,
|
|
||||||
pub invoker: Invoker<SpecctraMesadata>,
|
|
||||||
|
|
||||||
pub maybe_activity: Option<ActivityStepperWithStatus>,
|
|
||||||
|
|
||||||
pub history_channel: (
|
|
||||||
Sender<std::io::Result<Result<History, serde_json::Error>>>,
|
|
||||||
Receiver<std::io::Result<Result<History, serde_json::Error>>>,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Workspace {
|
|
||||||
pub fn new(design: SpecctraDesign, tr: &Translator) -> Result<Self, String> {
|
|
||||||
let board = design.make_board();
|
|
||||||
let overlay = Overlay::new(&board).map_err(|err| {
|
|
||||||
format!(
|
|
||||||
"{}; {}",
|
|
||||||
tr.text("tr-error_unable-to-initialize-overlay"),
|
|
||||||
err
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
let layers = Layers::new(&board);
|
|
||||||
let autorouter = Autorouter::new(board).map_err(|err| {
|
|
||||||
format!(
|
|
||||||
"{}; {}",
|
|
||||||
tr.text("tr-error_unable-to-initialize-autorouter"),
|
|
||||||
err
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
Ok(Self {
|
|
||||||
design,
|
|
||||||
layers,
|
|
||||||
overlay,
|
|
||||||
invoker: Invoker::new(autorouter),
|
|
||||||
maybe_activity: None,
|
|
||||||
history_channel: channel(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_state(&mut self, tr: &Translator, error_dialog: &mut ErrorDialog) -> bool {
|
|
||||||
if let Ok(data) = self.history_channel.1.try_recv() {
|
|
||||||
match data {
|
|
||||||
Ok(Ok(data)) => {
|
|
||||||
self.invoker.replay(data);
|
|
||||||
}
|
|
||||||
Ok(Err(err)) => {
|
|
||||||
error_dialog.push_error(
|
|
||||||
"tr-module-history-file-loader",
|
|
||||||
format!(
|
|
||||||
"{}; {}",
|
|
||||||
tr.text("tr-error_failed-to-parse-as-history-json"),
|
|
||||||
err
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
error_dialog.push_error(
|
|
||||||
"tr-module-history-file-loader",
|
|
||||||
format!("{}; {}", tr.text("tr-error_unable-to-read-file"), err),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(activity) = &mut self.maybe_activity {
|
|
||||||
<<<<<<< HEAD
|
|
||||||
return match activity.step(&mut ActivityContext {
|
|
||||||
interaction: InteractionContext {},
|
|
||||||
invoker: &mut *self.invoker.lock().unwrap(),
|
|
||||||
}) {
|
|
||||||
=======
|
|
||||||
return match activity.step(&mut self.invoker) {
|
|
||||||
>>>>>>> 8938ce7 (egui/Workspace: get rid of unnecessary Arc<Mutex<...>>)
|
|
||||||
Ok(ActivityStatus::Running) => true,
|
|
||||||
Ok(ActivityStatus::Finished(..)) => false,
|
|
||||||
Err(err) => {
|
|
||||||
error_dialog.push_error("tr-module-invoker", format!("{}", err));
|
|
||||||
false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_layers(&mut self, ctx: &egui::Context) {
|
|
||||||
self.layers.update(ctx, self.invoker.autorouter().board());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue