25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

11KB

Sprint Backlog

Sprint: 10 Dates: 2026-10-28 - 2026-11-01 Sprint Goal: Let an operator select multiple canvas elements at once (rubber-band or modifier-click, mixing standalone elements and Address Controls) and align/distribute them together, while also finishing the epic-4 wrap/clip chain's live visual indicator — the first new selection model this designer has ever had, plus a small, low-risk finish to already-shipped work.

Committed Items

Story Size Status Tasks
Add a live wrap/clip indicator for text elements 3 points Done - [x] Determine, per selected/previewed element with a box, whether the resolved text's natural (unwrapped) GDI+-measured size exceeds the box width (wrapping) and/or the wrapped height exceeds the box height (clipping)
- [x] Draw a small visual indicator (dashed-orange-style, consistent with the existing unmapped-column warning) on TemplateCanvasControl and TemplatePreviewControl when either condition is true for the current sample record, drawn inside the existing per-element rotation transform so it rotates for free
- [x] Unit tests for the wrap/clip detection logic (Desktop.Core, framework-free)
- [x] Live built-form smoke: a narrow (120pt) boxed element's real canvas screenshot shows both genuine multi-line wrap and the dashed-orange indicator appearing correctly
Select multiple elements at once on the canvas 5 points Not Started - [ ] Add a multi-select data structure alongside the existing single-selection state (CanvasElementEditor for standalone elements, TemplateCanvasControl for Address Controls) rather than replacing it, so every existing single-select code path (properties panel, rotate/resize handles, line drill-in) keeps working unchanged when only one item is selected
- [ ] Rubber-band selection: a click-drag starting on empty canvas space (not on any element/handle) draws a selection rectangle and selects every element/control whose bounding box intersects it on release
- [ ] Modifier-click (Ctrl/Shift): adds or removes a single element/control from the current multi-selection without disturbing the rest
- [ ] Visible selection indication for every selected item, not just the primary one
- [ ] Dragging any selected item moves the entire multi-selection together, preserving each item's relative offset (delta-based movement, not absolute repositioning)
- [ ] Properties panel shows a clear “N items selected” state and disables per-item property editing while a multi-selection is active (Development Team's chosen simplest option from the story's own notes)
- [ ] Unit tests: rubber-band hit-testing, modifier-click toggle, multi-drag delta math (Desktop.Core)
- [ ] Live built-form smoke (touches the properties panel's multi-item behavior)
Align and distribute multiple elements 5 points Not Started - [ ] Alignment operations (left/right/top/bottom edges, horizontal/vertical centers) over the current multi-selection, using each item's existing bounding box (Address Control's Width/computed height, standalone elements’ measured or box width/height)
- [ ] Distribution operations (equal horizontal/vertical spacing) over the current multi-selection
- [ ] A toolbar affordance to trigger each operation, enabled only when 2+ items are selected, clearly disabled (not silently a no-op) otherwise
- [ ] Unit tests for the alignment/distribution math (Desktop.Core, framework-free)
- [ ] Live full built-form smoke with a fresh screenshot (this story adds a new toolbar control to TemplateDesignerForm, per the Sprint 7 retrospective's carry-in)

Notes

  • Capacity signal: completed totals across Sprints 1-9 are 20, 19, 18, 18, 15, 18, 18, 13, 13 — nine data points. The 18-20 range remains this team's proven, repeatable velocity; 15 and both 13s are documented, deliberate under-commits (a large/risky story, then two fresh-priority stories), not capacity misses.
  • Why epic 6's pair is finally committed this sprint, explicit reasoning: Ready and waiting since Sprint 7, deferred twice for fresher, more urgent human requests (Sprint 8's Address Control rotation reversal; Sprint 9's wrap/clip request). Neither reason applies a third time — continuing to defer a Ready, sized, 3-sprint-old pair without a stated reason would itself become the anti-pattern this team's practice exists to avoid.
  • Why pairing it with the small indicator story doesn't trip the “two large/novel stories” rule: that caution is about stacking two large, first-of-its-kind, architecturally risky stories in one sprint (e.g., Sprint 8's rejected rotation-drag-handle + multi-select combination). Only multi-select carries that character here; the indicator story is small, additive, and touches no shared foundational state.
  • Impediments: template asset path strategy (absolute vs. relative) and UNC timeout/retry behavior remain open in logs/impediment_log.md. Neither blocks this sprint's committed items.
  • Carried over from previous sprint: none (Sprint 9 completed its one committed story, 13/13 points).
  • Not committed: “Add an adjustable width and height with text wrapping to Address Control lines” (8 pts, epic 4 — depends on this sprint's indicator story landing and its design settling first, deferred to Sprint 11 rather than built under time pressure in the same sprint); “Undo and redo layout changes” (13 pts, epic 6 — a reasonable alternative pairing with the indicator, not chosen given the multi-select/align pair's own 3-sprint-old deferral making it the more overdue commitment); “Complete the first text-only operator workflow” (5 pts, epic 1 — stale label, needs re-verification before ever being pulled).

Execution Order

Sequenced by dependency and risk: the small, independent indicator story first (quick, de-risks nothing else but clears easily), then the hard-dependent multi-select/align pair in order.

Batch Story Why it's gated here
1 Add a live wrap/clip indicator for text elements No dependency on anything else this sprint; small and independent.
2 Select multiple elements at once on the canvas No dependency on Batch 1, but sequenced next as the foundational half of the epic-6 pair.
3 Align and distribute multiple elements Strictly depends on Batch 2's multi-selection existing — there is nothing to align/distribute without it.

Daily Scrum Log

Day Date Completed Planned Blocked/At risk
1 2026-10-27 Batch 1 (“Add a live wrap/clip indicator for text elements”, 3 points) done, all ACs met. New framework-free WrapClipDetector (Desktop.Core) compares an element's natural (unwrapped) GDI+-measured width against its box width, and its GDI+-wrapped height against an explicit clip ceiling when one is set (never flags clipping otherwise, since there is no ceiling to exceed). Wired into TemplateCanvasControl.DrawElement and TemplatePreviewControl.DrawItem's existing box-mode branches, drawing a dashed-orange outline (the unmapped-column warning's visual language) inside the same rotation transform every other per-element visual already uses, so it orbits for free when rotated. Mid-batch, the human product owner raised two live-build issues, addressed together before continuing to Batch 2 (full detail in epics/02_template_designer_gui_foundation.md's and epics/04_live_preview_and_record_navigation.md's post-Sprint-9 correction notes): (1) no way to delete a placed element or Address Control — added CanvasElementEditor.RemoveSelected()/TemplateCanvasControl.RemoveSelectedElement(), wired to the Delete/Backspace key and a new toolbar button; (2) the resize handle should control only box width, font size set elsewhere — removed the Sprint 8 uniform-font-scale handle behavior entirely, ResizeDragTo now only ever sets Width, and TextElementLayout.HasBox/TemplateElement.HasBox were decoupled from Height (a new independent HasHeightClip flag) as a direct consequence, with DebenuPdfRenderer.AddPage gaining a “Width alone” native-wrap-no-clip render path (DrawWrappedText unrotated, GetWrappedText+DrawRotatedMultiLineText rotated). Tests: net +12 (8 obsolete font-scale tests removed, 20 new/updated across CanvasElementEditorTests, TextElementPropertiesEditorTests, TemplateLayoutXmlSerializerTests, TemplateXmlParserTests, DebenuPdfRendererWrapTests, plus the new WrapClipDetectorTests). Full suite 476/476 -> 488/488. Live-verified: a real, licensed end-to-end CLI render of a width-only (no height) template showed correct unrotated and rotated auto-height wrap with no clipping; a reflection-driven built-form harness confirmed a real mouse-driven resize drag sets only Width (Height/FontSize unchanged), the real Delete key removes the selected element, and a real canvas screenshot shows both genuine wrap and the new indicator on a narrow boxed element. One disclosed evidence-depth caveat: the toolbar Delete button's own PerformClick() didn't reliably fire in the synthetic harness (a known WinForms quirk absent a real shown window) — the underlying method was proven correct via a direct call, and the button's wiring matches every other proven-working toolbar button. Batch 2, “Select multiple elements at once on the canvas” (5 points, epic 6). None.
2 2026-10-27 Ad-hoc regression fix, before starting Batch 2: user reported clicking on and moving a dynamic placeholder had become “not smooth any more.” Full detail in epics/02_template_designer_gui_foundation.md's new post-Sprint-10-Batch-1 note. Root cause, found by direct Stopwatch instrumentation of TemplateCanvasControl.OnMouseDown rather than guessing: SelectionChanged fired unconditionally on every left-click, including a click on an already-selected element (the normal way to start a drag), and TemplateDesignerForm's handler runs the full un-gated RefreshPropertiesPanel() every time that fires — a cost that only became perceptible (~40-60ms/click, measured) once this sprint's added property-panel rows made the refresh heavier. Fixed by only raising SelectionChanged when the pre-click and post-click selection identity actually differ. Live-verified with the same instrumented harness: an already-selected element's second click dropped from ~50ms to 0.295ms; a genuine selection change still pays the warranted refresh cost unchanged. Full suite re-run: Desktop.Core 364/364, CLI 124/124 (fix is isolated to the WinForms-only TemplateCanvasControl, which has no automated test project). Batch 2, “Select multiple elements at once on the canvas” (5 points, epic 6). None.

Powered by TurnKey Linux.