7.8 KiB
7.8 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Tekstballon en -wolk | Het gereedschap "Tekst in kader" krijgt een vormkeuze (kader, ballon, ovale ballon, wolk). Ballon en wolk hebben een staart met een sleepbare greep op de punt, zodat je ermee iets kunt aanwijzen. |
|
false |
Tekstballon en -wolk voor "Tekst in kader"
Gedrag
- In de eigenschappenbalk van het tekstgereedschap (en van een geselecteerd tekstobject) komt een nieuwe keuzelijst Vorm:
- Kader: zoals nu, zonder staart.
- Ballon: een rechthoek met een spitse staart. De bestaande keuze voor afgeronde hoeken blijft hierbij werken.
- Ovale ballon: een ovaal om de tekst, met een spitse staart.
- Wolk: een bolle wolkrand met als staart drie steeds kleinere rondjes (een gedachtewolk).
- De punt van de staart is een greep. Je kunt die met het selectiegereedschap of het tekstgereedschap verslepen naar wat je wilt aanwijzen.
- Als je het hele object verplaatst, schuift de staartpunt mee. Als de tekst langer wordt, blijft de punt op dezelfde plek staan, dus hij blijft naar hetzelfde wijzen.
- Een nieuw object krijgt de staartpunt standaard schuin linksonder het kader.
- Ligt de punt binnen de vorm, dan wordt er geen staart getekend.
- De rand, vulling, stippellijn en schaduw lopen als één doorlopende omtrek om de vorm en de staart heen.
- Formaat aanpassen (geldt voor alle vormen, ook Kader): een geselecteerd tekstobject krijgt 8 formaatgrepen rond de vorm, net als bij een rechthoek. Zodra je die versleept, krijgt het kader een vaste breedte en loopt de tekst daarbinnen door naar de volgende regel.
- De hoogte die je instelt is een minimum. Past de tekst er niet in, dan groeit het kader naar beneden mee.
- Is het kader hoger dan de tekst, dan staat de tekst verticaal in het midden.
- Een nieuw tekstobject begint zoals nu, met een automatische grootte. Dubbelklik op een formaatgreep zet het kader terug naar automatisch.
- De staartpunt blijft op zijn plek als je het formaat aanpast.
Technische aanpak
1. Datamodel in src/Kniip/Editor/StyleSet.cs
- Nieuwe enum
TextShape { Frame, Balloon, Oval, Cloud }. - Nieuwe stijleigenschap
TextShape TextShape(standaardFrame). Oude instellingen blijven daardoor werken. - Nieuwe vlag
StyleProps.TextShape, toe te voegen aanPropsFor(ToolKind.Text). - De gekozen vorm wordt per gereedschap onthouden via de bestaande
ToolStyles.
2. Vorm tekenen in src/Kniip/Editor/Annotations/TextAnnotation.cs
- Nieuwe eigenschap
Point? TailTip. Zolang die leeg is, wordt de standaardpositie onder het kader berekend. - Nieuwe hulpfunctie
BuildShape(Rect box)die deGeometryopbouwt:- Kader: de huidige
RectangleGeometry. - Ballon (zoals in het voorbeeld met het rode kader dat naar het Google-logo wijst): een afgeronde rechthoek, samengevoegd met een spitse driehoekige staart via
Geometry.Combine(..., GeometryCombineMode.Union). De voet van de staart zit op de zijde die naar de punt kijkt (links, rechts, boven of onder, afhankelijk van waar de punt ligt). Hij staat ongeveer midden op die zijde en schuift mee richting de punt, maar blijft buiten de afgeronde hoeken. De voet is ongeveer 25% van die zijde breed en de staart loopt spits uit naar de greep. - Ovaal: een
EllipseGeometrydie zo veel ruimer is dan het tekstvlak (factor ongeveer √2) dat de tekst erin past, plus dezelfde staart. - Wolk: een vereniging van cirkels langs de omtrek van een ovaal, plus het ovaal zelf. De staart bestaat uit drie losse rondjes van de rand naar de punt, die steeds kleiner worden.
- Kader: de huidige
- Nieuwe eigenschappen
double? BoxWidthendouble? BoxHeight. Isnulleen automatische grootte, zoals nu. - Nieuwe hulpfuncties
Box(de rechthoek van de vorm zonder staart, metPositionlinksboven) enTextArea(het tekstvlak daarbinnen):- Bij Kader en Ballon is
TextAreagelijk aanBoxmin dePadding. - Bij Ovaal en Wolk springt
TextAreaextra in, zodat de tekst binnen de ronding blijft. - Bij een vaste breedte krijgt
FormattedText.MaxTextWidthde breedte vanTextArea, zodat de tekst op woorden afbreekt. De hoogte wordtmax(BoxHeight, tekst + padding). - Bij een automatische grootte wordt
Boxuit de tekstmaat berekend, opgeblazen naar de vorm.
- Bij Kader en Ballon is
RendergebruiktBuildShape(Box)in plaats van de vaste rechthoek, en tekent de tekst verticaal gecentreerd inTextArea.BoundsenHitTestnemen de buitengrenzen van de geometrie mee, inclusief de staart.GetHandles()geeft eerst de 8 formaatgrepen vanBox(zelfde volgorde als in RectAnnotation.cs) en daarna, behalve bij Kader, de staartpunt (index 8).BeginHandleDragonthoudt de oorspronkelijkeBox.MoveHandlevoor index 0 tot en met 7 rekent de nieuwe rechthoek uit zoalsRectAnnotation.MoveHandle, via de bestaandeRectAnnotation.FromAnchor. Daarna zet hetPosition,BoxWidthenBoxHeight, met een minimale breedte van ongeveer twee tekens plus padding.- Index 8 past
TailTipaan. RemoveHandle(dubbelklik) op een formaatgreep zetBoxWidthenBoxHeightterug opnull.
Moveverschuift ookTailTip.
3. Editor in src/Kniip/Editor/EditorWindow.xaml en src/Kniip/Editor/EditorWindow.xaml.cs
- Een
TextShapeGroupmetTextShapeComboen eenTextShapeTemplate(klein vormicoontje met een label), naar het voorbeeld vanCursorKindTemplateenCursorKindCombo. TextShapeValuesalsItemsSource. InUpdatePropsPanelworden zichtbaarheid en selectie gezet. Een handlerTextShape_ChangedroeptChangeStyle("textshape", s => s.TextShape = shape)aan.- Bij het aanmaken van een nieuwe tekst (rond regel 842) wordt de standaard
TailTipvastgezet. Het verslepen van de greep loopt via het bestaande generieke handle-mechanisme (rond regel 778), daar hoeft niets aan te veranderen. BeginTextEditenApplyTextEditorStylezetten deTextBoxopTextAreain plaats van opPosition. Bij een vaste breedte krijgt deTextBoxdie breedte enTextWrapping.Wrap, zodat je tijdens het typen dezelfde regelafbreking ziet als in het eindresultaat.- Tijdens het typen blijft de
TextBoxrechthoekig. De staart blijft dan zichtbaar, omdat alleen de tekstlaag verborgen is. Dat is een kleine aanpassing: bij een vorm met staart tekentRenderde omtrek ook alsIsHiddenaan staat, alleen de tekst niet.
flowchart LR
TextShapeCombo --> ChangeStyle --> StyleSetTextShape["StyleSet.TextShape"]
StyleSetTextShape --> BuildShape
TailTip --> BuildShape
BuildShape --> Render
BuildShape --> Bounds
HandleDrag["Greep slepen"] --> TailTip
Buiten scope
- Een explosie- of uitroepvorm en gebogen staarten. Die zijn later toe te voegen als extra
TextShape-waarde. - Draaien van het kader (de draaigreep boven het kader in het voorbeeld).