Files
kniip/.cursor/plans/vormenknop_d1b7f613.plan.md
2026-11-10 15:33:49 +01:00

6.5 KiB

name, overview, todos, isProject
name overview todos isProject
Vormenknop Een nieuwe werkbalkknop "Vormen" naast Rechthoek en Ellips, met in de eigenschappenbalk een keuzelijst voor 11 vormen (driehoek, pijl, ster, wolk, ballon, hart, maan, druppel, ei, bliksemschicht, spiraal). Je tekent een vorm door een kader te slepen, net als bij een rechthoek.
id content status
model ToolKind.Shape, ShapeKind-enum, StyleSet.ShapeKind en StyleProps.ShapeKind in StyleSet.cs completed
id content status
geometries ShapeGeometries.cs: de 11 vormen in een eenheidsvierkant, plus IsOpen en Icon; ShapeIconConverter completed
id content status
annotation FigureAnnotation.cs: Render met transform, HitTest (open/gesloten), spiegelen completed
id content status
ui Werkbalkknop, ShapeKindTemplate, ShapeGroup/ShapeKindCombo in EditorWindow.xaml completed
id content status
wiring EditorWindow.xaml.cs: CreateAnnotation, UpdatePropsPanel, ShapeKind_Changed, knopicoon, DefaultSplitOrder, sneltoets F, hinttekst completed
id content status
verify Bouwen en handmatig testen: alle vormen tekenen, wisselen, Shift, grepen, spiegelen, kopiëren/plakken, export completed
false

Vormenknop met 11 vormen

Gedrag

  • Er komt een nieuwe gereedschapsknop Vormen direct na Ellips. Rechthoek en Ellips blijven zoals ze zijn.
  • In de eigenschappenbalk staat een keuzelijst Vorm (icoon plus naam): Driehoek, Pijl, Ster, Wolk, Ballon, Hart, Maan, Druppel, Ei, Bliksemschicht, Spiraal.
  • Het icoon op de werkbalkknop toont de laatst gekozen vorm. De keuze wordt per gereedschap onthouden, net als de andere stijlinstellingen.
  • Tekenen gaat door een kader te slepen; de vorm vult dat kader. Met Shift wordt het kader vierkant. Er zijn 8 formaatgrepen, net als bij een rechthoek.
  • Eigenschappen: randkleur, vulkleur, dikte, stippellijn en schaduw. De spiraal is een open lijn en krijgt geen vulling.
  • Bij een geselecteerde vorm kun je via de keuzelijst een andere vorm kiezen (met undo).
  • Spiegelen (horizontaal en verticaal) werkt voor vormen, zodat de pijl, maan, bliksem, ballon en spiraal ook de andere kant op kunnen.
  • Sneltoets F (figuur), want de meeste voor de hand liggende letters zijn al bezet.
  • Aanname: Ballon is hier een tekstballon zonder tekst (afgeronde rechthoek met een staart linksonder) en Wolk een gedachtewolk zonder staart, als losse vorm. Voor een ballon of wolk met tekst blijft het tekstgereedschap bestaan.

Technische aanpak

1. Model in src/Kniip/Editor/StyleSet.cs

  • ToolKind.Shape achteraan toevoegen. Instellingen worden als tekst opgeslagen (JsonStringEnumConverter), dus de volgorde breekt niets.
  • Nieuwe enum ShapeKind { Triangle, BlockArrow, Star, Cloud, Balloon, Heart, Moon, Drop, Egg, Lightning, Spiral }.
  • StyleSet.ShapeKind (standaard Triangle) en vlag StyleProps.ShapeKind.
  • PropsFor(ToolKind.Shape) = Stroke, Fill, Thickness, Dash, Shadow, ShapeKind. DefaultFor gebruikt de gewone standaard (rode rand, geen vulling).

2. Geometrie in een nieuw bestand src/Kniip/Editor/Annotations/ShapeGeometries.cs

  • Geometry For(ShapeKind kind) bouwt elke vorm in een eenheidsvierkant (0..1), gecachet en bevroren, zoals CursorGeometries.cs:
    • Driehoek, Pijl (blokpijl naar rechts), Ster (5 punten), Bliksemschicht: rechte polygonen.
    • Hart, Druppel, Ei, Maan, Ballon: Bezier- en boogsegmenten in een StreamGeometry. De maan wordt een cirkel min een verschoven cirkel (GeometryCombineMode.Exclude).
    • Wolk: een vereniging van cirkels, zoals TextAnnotation dat al doet.
    • Spiraal: een open polyline langs een Archimedes-spiraal (ongeveer 3 omwentelingen).
  • bool IsOpen(ShapeKind) geeft true voor Spiraal.
  • Geometry Icon(ShapeKind) schaalt dezelfde vorm naar 20x20 voor de knop en de keuzelijst. Er komt een ShapeIconConverter naar het voorbeeld van CursorIconConverter.cs.

3. Annotatie: nieuw src/Kniip/Editor/Annotations/FigureAnnotation.cs, afgeleid van RectAnnotation.cs, zodat grepen, verplaatsen en Shift al werken.

  • Kind => ToolKind.Shape. De vorm komt uit Style.ShapeKind, zodat wisselen via ChangeStyle meteen werkt.
  • Render: de eenheidsgeometrie klonen met een MatrixTransform naar Rect (plus een spiegeling met FlipX/FlipY). De lijndikte schaalt daardoor niet mee. Tekenen gebeurt via RenderHelpers.DrawWithShadow, zonder vulling bij een open vorm.
  • HitTest: FillContains voor gesloten vormen, StrokeContains met tolerantie voor de spiraal.
  • CanFlip => true; Flip wisselt FlipX of FlipY.

4. Editor in src/Kniip/Editor/EditorWindow.xaml en EditorWindow.xaml.cs

  • XAML: een RadioButton Tag="Shape" ItemId="Shape" Title="Vormen" na Ellips, met een Path x:Name="ShapeToolIcon". Daarnaast een ShapeKindTemplate (icoon via de converter, plus een label per waarde, net als CursorKindTemplate) en een ShapeGroup met ShapeKindCombo in de eigenschappenbalk.
  • Code:
    • ShapeKindValues als ItemsSource.
    • "Shape" na "Ellipse" in DefaultSplitOrder. MergeToolbarOrder zet de nieuwe knop bij bestaande gebruikers automatisch na Ellips.
    • CreateAnnotation: ToolKind.Shape => new FigureAnnotation { Rect = new Rect(p, p), Style = style }.
    • UpdatePropsPanel: zichtbaarheid van ShapeGroup en selectie van ShapeKindCombo. De vulling wordt verborgen bij Spiraal.
    • Handler ShapeKind_Changed roept ChangeStyle("shape", s => s.ShapeKind = kind) aan en werkt ShapeToolIcon bij. Bij het starten wordt het icoon ook gezet.
    • Sneltoets Key.F en een hinttekst: "Sleep om de gekozen vorm te tekenen. Shift = gelijke breedte en hoogte. Kies een andere vorm in de balk eronder."
flowchart LR
    ShapeKindCombo --> ChangeStyle --> StyleShapeKind["StyleSet.ShapeKind"]
    StyleShapeKind --> ShapeGeometries
    ShapeGeometries --> FigureAnnotation
    ShapeGeometries --> ShapeIconConverter
    ShapeIconConverter --> ShapeToolIcon
    ShapeIconConverter --> ShapeKindTemplate

Buiten scope

  • Draaien van vormen. Een pijl omhoog of omlaag kan daardoor niet; links en rechts wel, via spiegelen.
  • Tekst in een vorm. Daarvoor blijft het tekstgereedschap met ballon en wolk.
  • Instelbare details per vorm, zoals het aantal punten van de ster, de dikte van de maan of het aantal windingen van de spiraal.