Skip to content

Instantly share code, notes, and snippets.

@davehorner
Created April 21, 2025 03:48
Show Gist options
  • Save davehorner/04a771086c1bd846d11d3b07245b4aa4 to your computer and use it in GitHub Desktop.
Save davehorner/04a771086c1bd846d11d3b07245b4aa4 to your computer and use it in GitHub Desktop.
cargo-e external library makepad example - currently does not draw anything
#!/usr/bin/env rust-script
//! ```cargo
//! [dependencies]
//! cargo-e = { version = "*", features = ["uses_plugins","uses_rhai"] }
//! makepad-widgets = "0.6.0"
//! num_cpus = "1.16"
//! clap = { version = "4.5", features = ["derive"] }
//! ```
//!
//! A Makepad GUI listing all Cargo-e targets via ExtContext with Run buttons.
use clap::Parser;
use std::sync::{Arc, Mutex};
use std::thread;
use cargo_e::Cli;
use cargo_e::ext::ExtContext;
use cargo_e::e_processmanager::ProcessManager;
use cargo_e::e_target::{CargoTarget, TargetKind};
use makepad_widgets::*;
use makepad_widgets::app_main;
live_design! {
import makepad_widgets::base::*;
import makepad_widgets::theme_desktop_dark::*;
TargetRow = <View> {
height: Fit, flow: Right, spacing: 8.,
label = <Label> { text: "" },
button = <Button> { text: "▶ Run" }
}
App = {{App}} {
ui: <Window> {
show_bg: true, width: Fill, height: Fill,
body = <View> {
flow: Down, spacing: 10., padding: 10.,
list = <FlatList> {},
status = <Label> { text: "" }
}
}
}
}
app_main!(App);
#[derive(Live)]
pub struct App {
#[live] ui: WidgetRef,
#[rust] cli: Option<Cli>,
#[rust] pm: Option<Arc<ProcessManager>>,
#[rust] targets: Arc<Mutex<Vec<CargoTarget>>>,
#[rust] status: Arc<Mutex<String>>,
}
impl LiveHook for App {
fn before_live_design(cx: &mut Cx) {
makepad_widgets::live_design(cx);
}
}
impl AppMain for App {
fn handle_event(&mut self, cx: &mut Cx, event: &Event) {
if let Event::Draw(ev) = event {
if self.cli.is_none() {
// -- Step 1: parse CLI
let cli = Cli::parse();
println!("[debug] Parsed CLI: {:?}", cli);
// -- Step 2: create ProcessManager
let pm = ProcessManager::new(&cli);
println!("[debug] Created ProcessManager");
// -- Step 3: collect targets via ExtContext
let ctx = ExtContext::new(cli.clone(), pm.clone()).unwrap();
let mut ts = ctx.collect_targets().unwrap();
println!("[debug] Collected {} targets", ts.len());
for t in &ts { println!("[debug] target: {} ({:?})", t.display_name, t.kind); }
println!("[debug] {} runnable targets", ts.len());
// store in state
self.targets = Arc::new(Mutex::new(ts));
self.cli = Some(cli);
self.pm = Some(pm);
}
let fl = self.ui.flat_list(id!(list));
let actions = self.ui.handle_widget_event(cx, event);
let guard = self.targets.lock().unwrap();
for (i, tgt) in guard.iter().enumerate() {
println!("[debug] Drawing row {} => {}", i, tgt.display_name);
let entry = LiveId(i as u64);
let tpl = id!(TargetRow)[0];
if let Some(row) = fl.item(cx, entry, tpl) {
row.label(id!(label)).set_text_and_redraw(cx, &tgt.display_name);
if row.button(id!(button)).clicked(&actions) {
println!("[debug] Run button clicked on {}", tgt.display_name);
let sr = self.status.clone();
{ *sr.lock().unwrap() = format!("Running {}", tgt.display_name); }
if let (Some(cli), Some(pm)) = (self.cli.clone(), self.pm.clone()) {
let tclone = tgt.clone();
let run_ref = sr.clone();
thread::spawn(move || {
let ctx = ExtContext::new(cli, pm).unwrap();
let res = ctx.run_target(&tclone);
*run_ref.lock().unwrap() = match res {
Ok(Some(code)) => format!("Exited with {}", code),
Ok(None) => format!("Done {}", tclone.display_name),
Err(e) => format!("Error {}: {}", tclone.display_name, e),
};
});
}
}
}
}
self.ui.draw_widget_all(&mut Cx2d::new(cx, ev));
return;
}
self.ui.handle_widget_event(cx, event);
}
}
fn main(){
app_main()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment