copying now uses it's own thread to avoid freezing the ui for larger images
This commit is contained in:
+59
-13
@@ -37,6 +37,8 @@ pub struct TerrainApp {
|
||||
generated: Option<GeneratedImages>,
|
||||
generation_receiver: Option<Receiver<Result<GeneratedImages, String>>>,
|
||||
generation_in_progress: bool,
|
||||
copy_receiver: Option<Receiver<Result<String, String>>>,
|
||||
copy_in_progress: bool,
|
||||
status_message: String,
|
||||
}
|
||||
|
||||
@@ -51,6 +53,8 @@ impl TerrainApp {
|
||||
generated: None,
|
||||
generation_receiver: None,
|
||||
generation_in_progress: false,
|
||||
copy_receiver: None,
|
||||
copy_in_progress: false,
|
||||
status_message: String::from("Adjust parameters and click Generate."),
|
||||
}
|
||||
}
|
||||
@@ -108,6 +112,33 @@ impl TerrainApp {
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_copy(&mut self, ctx: &Context) {
|
||||
let Some(receiver) = &self.copy_receiver else {
|
||||
return;
|
||||
};
|
||||
|
||||
match receiver.try_recv() {
|
||||
Ok(Ok(message)) => {
|
||||
self.status_message = message;
|
||||
self.copy_receiver = None;
|
||||
self.copy_in_progress = false;
|
||||
}
|
||||
Ok(Err(error)) => {
|
||||
self.status_message = error;
|
||||
self.copy_receiver = None;
|
||||
self.copy_in_progress = false;
|
||||
}
|
||||
Err(TryRecvError::Empty) => {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
Err(TryRecvError::Disconnected) => {
|
||||
self.status_message = String::from("Copy worker disconnected.");
|
||||
self.copy_receiver = None;
|
||||
self.copy_in_progress = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn install_textures(&mut self, ctx: &Context, images: &GeneratedImages) {
|
||||
let heightmap = gray_to_color_image(&images.heightmap_image);
|
||||
let bumpmap = gray_to_color_image(&images.bumpmap_image);
|
||||
@@ -119,27 +150,37 @@ impl TerrainApp {
|
||||
}
|
||||
|
||||
fn copy_preview(&mut self, preview: PreviewFocus) {
|
||||
if self.copy_in_progress {
|
||||
self.status_message = String::from("Copy already in progress...");
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(generated) = &self.generated else {
|
||||
self.status_message = String::from("No generated image is available to copy.");
|
||||
return;
|
||||
};
|
||||
|
||||
let image = match preview {
|
||||
PreviewFocus::Heightmap => &generated.heightmap_image,
|
||||
PreviewFocus::Bumpmap => &generated.bumpmap_image,
|
||||
PreviewFocus::Heightmap => generated.heightmap_image.clone(),
|
||||
PreviewFocus::Bumpmap => generated.bumpmap_image.clone(),
|
||||
};
|
||||
let success_message = match preview {
|
||||
PreviewFocus::Heightmap => String::from("Heightmap copied to clipboard."),
|
||||
PreviewFocus::Bumpmap => String::from("Bumpmap copied to clipboard."),
|
||||
};
|
||||
|
||||
match copy_gray_image_to_clipboard(image) {
|
||||
Ok(()) => {
|
||||
self.status_message = match preview {
|
||||
PreviewFocus::Heightmap => String::from("Heightmap copied to clipboard."),
|
||||
PreviewFocus::Bumpmap => String::from("Bumpmap copied to clipboard."),
|
||||
};
|
||||
}
|
||||
Err(error) => {
|
||||
self.status_message = format!("Failed to copy image: {error}");
|
||||
}
|
||||
}
|
||||
let (tx, rx) = mpsc::channel();
|
||||
self.copy_receiver = Some(rx);
|
||||
self.copy_in_progress = true;
|
||||
self.status_message = match preview {
|
||||
PreviewFocus::Heightmap => String::from("Copying heightmap to clipboard..."),
|
||||
PreviewFocus::Bumpmap => String::from("Copying bumpmap to clipboard..."),
|
||||
};
|
||||
|
||||
thread::spawn(move || {
|
||||
let result = copy_gray_image_to_clipboard(&image).map(|_| success_message);
|
||||
let _ = tx.send(result);
|
||||
});
|
||||
}
|
||||
|
||||
fn preview_context_menu(response: &Response) -> bool {
|
||||
@@ -236,6 +277,10 @@ impl TerrainApp {
|
||||
ui.add_space(8.0);
|
||||
ui.spinner();
|
||||
}
|
||||
if self.copy_in_progress {
|
||||
ui.add_space(4.0);
|
||||
ui.spinner();
|
||||
}
|
||||
|
||||
ui.add_space(8.0);
|
||||
ui.label(&self.status_message);
|
||||
@@ -392,6 +437,7 @@ impl eframe::App for TerrainApp {
|
||||
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||
self.hovered_preview = None;
|
||||
self.poll_generation(ctx);
|
||||
self.poll_copy(ctx);
|
||||
self.ui_left_panel(ctx);
|
||||
self.ui_right_panel(ctx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user