mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-14 19:27:07 -04:00
Merge pull request #12 from storytold/pr/never-crash-ui
Never crash: UI (ui-egui)
This commit is contained in:
5 files changed
+10
-9
No files matched your search
@@ -245,7 +245,7 @@ pub fn show(app: &mut DesignApp, ui: &mut egui::Ui) {
|
||||
}
|
||||
handle_input(app, ui, &resp, rect);
|
||||
let Some(st) = app.session.active() else { return };
|
||||
let v = *app.view().expect("view");
|
||||
let Some(&v) = app.view() else { return };
|
||||
let xf = Xf::new(rect, &v);
|
||||
let doc = st.doc.clone();
|
||||
let layout = CanvasLayout::new(&doc, st.editing_parents);
|
||||
@@ -400,7 +400,7 @@ fn render_texture(app: &mut DesignApp, ctx: &egui::Context, rect: Rect, xf: &Xf,
|
||||
let doc_changed = app.canvas.shown.is_none_or(|s| s.doc != doc_key);
|
||||
let zoom_same = app.canvas.shown.is_some_and(|s| (s.zoom - xf.zoom).abs() < 1e-9);
|
||||
let job = |app: &DesignApp| {
|
||||
let st = app.session.active().expect("doc");
|
||||
let st = app.session.active()?;
|
||||
let placed: Vec<designcraft_render::Placed> =
|
||||
layout.slots.iter().map(|s| designcraft_render::Placed { spread: s.spread, xf: s.xf }).collect();
|
||||
let w = (target.size.0 as f64 * ppp).round().max(1.0) as u32;
|
||||
@@ -424,7 +424,7 @@ fn render_texture(app: &mut DesignApp, ctx: &egui::Context, rect: Rect, xf: &Xf,
|
||||
blend_space_view: !app.ui.proof_colors,
|
||||
..Default::default()
|
||||
};
|
||||
(st.doc.clone(), placed, w, h, view, opts)
|
||||
Some((st.doc.clone(), placed, w, h, view, opts))
|
||||
};
|
||||
// Synchronous path: document edits (keep editing crisp), first frame, or no worker.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -442,7 +442,7 @@ fn render_texture(app: &mut DesignApp, ctx: &egui::Context, rect: Rect, xf: &Xf,
|
||||
}
|
||||
if !has_worker || app.canvas.shown.is_none() || (doc_changed && zoom_same) {
|
||||
let t0 = crate::now_ms();
|
||||
let (doc, placed, w, h, view, opts) = job(app);
|
||||
let Some((doc, placed, w, h, view, opts)) = job(app) else { return };
|
||||
let img = app.canvas.renderer.render(&doc, &app.session.cache, &placed, w, h, view, &opts);
|
||||
upload(app, ctx, img);
|
||||
app.canvas.shown = Some(target);
|
||||
@@ -463,7 +463,7 @@ fn render_texture(app: &mut DesignApp, ctx: &egui::Context, rect: Rect, xf: &Xf,
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
let (doc, placed, w, h, view, opts) = job(app);
|
||||
let Some((doc, placed, w, h, view, opts)) = job(app) else { return };
|
||||
app.canvas.pending_doc = Some(doc.clone());
|
||||
app.canvas.token += 1;
|
||||
let token = app.canvas.token;
|
||||
|
||||
@@ -198,7 +198,8 @@ pub fn handle(app: &mut DesignApp, ctx: &egui::Context, req: &ControlRequest) ->
|
||||
app.synthetic.push(egui::Event::PointerMoved(a));
|
||||
app.synthetic.push(egui::Event::PointerButton { pos: a, button, pressed: true, modifiers });
|
||||
if req.method == "ui.drag" {
|
||||
let steps = p.get("steps").and_then(Value::as_u64).unwrap_or(8).max(1);
|
||||
// From the caller: a huge count would queue events until memory runs out.
|
||||
let steps = p.get("steps").and_then(Value::as_u64).unwrap_or(8).clamp(1, 10_000);
|
||||
for i in 1..=steps {
|
||||
let t = i as f32 / steps as f32;
|
||||
app.synthetic.push(egui::Event::PointerMoved(a + (end - a) * t));
|
||||
|
||||
@@ -1484,8 +1484,7 @@ pub fn confirm(app: &mut DesignApp) -> Result<Value, String> {
|
||||
"qrCode" => {
|
||||
let mut p = Value::Object(d.fields.clone());
|
||||
// Nothing selected: a 2-inch code at the top left of the page in view.
|
||||
if app.session.active().is_some_and(|s| s.selection.items.is_empty()) {
|
||||
let st = app.session.active().expect("doc");
|
||||
if let Some(st) = app.session.active().filter(|s| s.selection.items.is_empty()) {
|
||||
let abs = crate::canvas::current_page(app).unwrap_or(0);
|
||||
let (si, pi) = st.doc.page_loc(abs).unwrap_or((0, 0));
|
||||
let x = st.doc.spreads.get(si).and_then(|sp| sp.pages.get(pi)).map_or(0.0, |pg| pg.x);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//! The UI is thin: every action goes through [`DesignApp::run`], which dispatches UI commands
|
||||
//! (view/window) here and everything else to the engine. Menus, shortcuts, the ⌘K palette and
|
||||
//! the control channel ([`control`]) share that entry point.
|
||||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
pub mod about;
|
||||
|
||||
@@ -830,7 +830,7 @@ fn text_style_section(app: &mut DesignApp, ui: &mut Ui) {
|
||||
}
|
||||
ui.add_space(5.0);
|
||||
let (names, cur): (Vec<String>, String) = {
|
||||
let st = app.session.active().expect("doc");
|
||||
let Some(st) = app.session.active() else { return };
|
||||
if tab == 0 {
|
||||
(
|
||||
st.doc.styles.paragraph.iter().map(|p| p.name.clone()).filter(|n| n != designcraft_doc::NO_PARA_STYLE).collect(),
|
||||
|
||||
Reference in new issue
Block a user