egui_flow 1.0.0

crate that helps you with tasks which cant run directly in the egui ui code
Documentation
use eframe::{App, CreationContext, Frame, NativeOptions};
use egui::{CentralPanel, Context, Id};
use egui_flow::FlowManager;
use std::time::Duration;

const COUNTERS_EXAMPLE_COLUMNS: usize = 10;

#[derive(Default)]
struct MyApp {
	flow: FlowManager,
	simple_example: Option<&'static str>,
	counters_example: [u32; COUNTERS_EXAMPLE_COLUMNS]
}

impl MyApp {
	fn new(cc: &CreationContext) -> Self {
		let mut flow = FlowManager::default();
		flow.set_repaint_on_finish(Some(cc.egui_ctx.clone()));

		Self { flow, ..Default::default() }
	}
}

impl App for MyApp {
	fn update(&mut self, ctx: &Context, _frame: &mut Frame) {
		CentralPanel::default().show(ctx, |ui| {
			ui.heading("egui_flow example");

			let mut repaint = self.flow.get_repaint_on_finish();
			if ui.checkbox(&mut repaint, "Repaint when a flow finishes").changed() {
				self.flow.set_repaint_on_finish(if repaint { Some(ctx.clone()) } else { None });
			}

			ui.add_space(8.0);
			ui.separator();
			ui.add_space(8.0);

			ui.columns_const(|[col1, col2]| {
				col1.label("Simple");
				col1.group(|ui| {
					let id = ui.id();

					if !self.flow.is_active(id) {
						if ui.button("Run long task (2 seconds)").clicked() {
							self.simple_example = None; // clear data

							// start a background flow
							self.flow.start_simple(id, || {
								std::thread::sleep(Duration::from_secs(2));
								"Flow finished!"
							});
						} else {
							// display the results
							if let Some(result) = self.simple_example {
								ui.label(result);
							} else {
								ui.label("Not started.");
							}
						}

					} else {
						ui.strong("Processing...");

						// poll the flow
						if let Some(result) = self.flow.poll(id) {
							self.simple_example = Some(result);
						}
					}
				});

				col2.label("Counters");
				col2.group(|ui| {
					egui::Grid::new(ui.id()).num_columns(COUNTERS_EXAMPLE_COLUMNS).show(ui, |ui| {
						for i in 0..COUNTERS_EXAMPLE_COLUMNS {
							let id = Id::new(i);

							if !self.flow.is_active(id) {
								ui.label(self.counters_example[i].to_string());
								if ui.button("Increment").clicked() {
									// start a background task
									self.flow.start(id, self.counters_example[i], |int| {
										std::thread::sleep(Duration::from_secs(3));
										int + 1
									});
								}
							} else {
								ui.spinner();
								ui.label("Incrementing...");

								// poll the flow
								if let Some(result) = self.flow.poll(id) {
									self.counters_example[i] = result;
								}
							}
							ui.end_row();
						}
					});
				});
			});

			ui.add_space(8.0);
			ui.separator();
			ui.add_space(8.0);

			ui.small(format!("Active Flows:\n{:?}", self.flow.get_active_flow_ids()));
		});
	}
}

fn main() -> eframe::Result {
	eframe::run_native(
		"egui_flow",
		NativeOptions::default(),
		Box::new(|cc| Ok(Box::new(MyApp::new(cc)))))
}