collective

Browse / github.com/storytold/designcraft / patch

Context menu: Generate QR Code… for the object right-clicked

Generate QR Code… is missing from an object's context menu **What happens:** Generate QR Code… is only in the Object menu. Right-clicking a frame doesn't offer it, although the command works on the selected frame: it fills an empty frame, or edits the QR code in it. **Steps:** 1. Draw an empty frame and right-click it. 2. The context menu has Content and Effects, but no Generate QR Code…. **Expected:** The object context menu offers Generate QR Code… for the frame right-clicked, as layout apps do.

Status
open
Score
0.00
Adopters
0 other operators
Author
PiMinusMax (imported from pull request #1822, open)
Base
ed8aabd1dc5a88652a076631c2d46886ca60c031
Size
+51 −1 in 3 files
Review
pending
Shared
2026-10-28
Id
3b82e01253da505235ff2252

How it went

No other operator has reported using it yet.

Diff

raw · ROADMAP.md crates/ui-egui/src/canvas.rs crates/ui-egui/src/menus.rs

diff --git a/ROADMAP.md b/ROADMAP.md--- a/ROADMAP.md+++ b/ROADMAP.md@@ -380,6 +380,7 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m  Newest first. +- **2026-10-24** · An object's context menu has Generate QR Code…, which fills the frame right-clicked (an empty frame, or a QR code to edit it); it was only in the Object menu. No readiness percentage change. - **2026-10-20** · Edit › Keyboard Shortcuts is craft-keymap's shared dialog: commands grouped by menu with Show and Filter, recording that asks before taking a key from another command, undo and redo, named shortcut sets (edits of Default become Custom; an imported set becomes a set of its own), an on-screen US keyboard, InDesign Show Set files reviewed before they apply, JSON export and an HTML summary. ui.json keeps the `shortcuts` map earlier versions read, for the active set. No readiness percentage change. - **2026-10-19** · Import InDesign Set… runs on craft-keymap's importer: a set's Window menu panel items (Layers F7, Pages F12, Swatches F5) and Tools items set the panel and tool shortcuts, all of an item's Default keys apply, and the report adds numeric keypad keys read as main keys and likely commands for unmatched items (`window.importShortcuts`). On InDesign's Windows defaults it matches 366 of 1,629 items (was 233) and changes 23 commands. No readiness percentage change. - **2026-10-19** · Keyboard shortcuts run on the shared craft-keymap crate. Panels take shortcuts, with InDesign's defaults where the key is free (Swatches F5, Color F6, Layers F7, Info F8, Stroke F10, Paragraph Styles F11, Character Styles Shift+F11, Pages F12, Align Shift+F7); tool keys are editable in Edit › Keyboard Shortcuts and `window.setShortcut`, and tools sharing a key take turns (B). Saved shortcuts load unchanged. No readiness percentage change.diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs--- a/crates/ui-egui/src/canvas.rs+++ b/crates/ui-egui/src/canvas.rs@@ -5666,6 +5666,54 @@ mod tests {         assert!(menu_row(&h, "Paste without Formatting").is_some());     } +    /// Generate QR Code… is in an object's context menu, not only in the Object menu, and fills+    /// the frame right-clicked (not the one selected before); again on that frame, it edits its+    /// code in place.+    #[test]+    fn an_objects_context_menu_generates_a_qr_code() {+        let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());+        app.run("file.new", json!({})).unwrap();+        let other = app.run("frame.create", json!({"rect": [300, 36, 400, 136]})).unwrap()["id"].as_u64().unwrap();+        let clicked = app.run("frame.create", json!({"rect": [36, 36, 200, 200]})).unwrap()["id"].as_u64().unwrap();+        app.run("selection.set", json!({"ids": [other]})).unwrap();+        let mut h = harness(app);+        // The codes a frame holds, by what they encode.+        let codes = |h: &Harness<'_, DesignApp>, id: u64| -> Vec<String> {+            let d = &h.state().session.active().unwrap().doc;+            d.item(designcraft_doc::ItemId(id))+                .unwrap()+                .children()+                .iter()+                .filter_map(|c| c.alt_text.strip_prefix("QR code: ").map(str::to_string))+                .collect()+        };+        for content in ["https://example.com", "https://example.org"] {+            let on_frame = screen_of(&h, 60.0, 60.0);+            right_click(&mut h, on_frame);+            // The object menu is taller than the room below the click: scroll it, as the user would.+            let over = menu_row(&h, "Copy").expect("the object menu").rect().center();+            h.hover_at(over);+            h.event(egui::Event::MouseWheel {+                unit: egui::MouseWheelUnit::Point,+                delta: vec2(0.0, -2000.0),+                phase: egui::TouchPhase::Move,+                modifiers: Default::default(),+                source: egui::MouseWheelSource::Unknown,+            });+            h.run_steps(4);+            menu_row(&h, "Generate QR Code…").expect("in the object's context menu").click();+            h.run_steps(3);+            let app = h.state_mut();+            let dialog = app.ui.dialog.as_mut().expect("the QR Code dialog");+            assert_eq!(dialog.id, "qrCode");+            dialog.fields.insert("content".into(), json!(content));+            crate::dialogs::confirm(app).unwrap();+            h.run_steps(2);+            assert_eq!(codes(&h, clicked), [content.to_string()], "one code, in the frame right-clicked");+            assert!(codes(&h, other).is_empty(), "the frame selected before is left alone");+        }+    }+     #[test]     fn rows_hidden_in_the_menu_bar_are_hidden_in_context_menus() {         let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs--- a/crates/ui-egui/src/menus.rs+++ b/crates/ui-egui/src/menus.rs@@ -2996,7 +2996,8 @@ const CONTEXT_OBJECT: &[&str] = &[ ]; /// Added to the object menu when a graphic frame is selected. const CONTEXT_GRAPHIC_FRAME: &[&str] = &["menu:Object/Fitting"];-const CONTEXT_OBJECT_TAIL: &[&str] = &["menu:Object/Content", "menu:Object/Effects"];+/// Generate QR Code… fills the selected frame (an empty one, or a QR code to edit it).+const CONTEXT_OBJECT_TAIL: &[&str] = &["menu:Object/Content", "menu:Object/Effects", "ui:app.qrCode"]; /// Added to the object menu when a text frame is selected. const CONTEXT_TEXT_FRAME: &[&str] = &["-", "cmd:type.fillWithPlaceholder", "cmd:object.textFrameOptions"]; const CONTEXT_TEXT: &[&str] = &[