diff options
author | bobzel <zzzman@gmail.com> | 2025-08-08 12:54:45 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2025-08-08 12:54:45 -0400 |
commit | b3aa4a5b0bbbb87d041b9515bddedbcbf8ae9fc5 (patch) | |
tree | 8622701837c9085d0e7f911e94b745e45b6025db | |
parent | 8ec4e4fbd42be8ba6606d78da25c33f69d30ed63 (diff) |
fixed sizing of arrows and dashes to relate to stroke width. Made link's use fill to set color and default to backgorundColor
-rw-r--r-- | src/client/util/InteractionUtils.tsx | 8 | ||||
-rw-r--r-- | src/client/views/PropertiesView.tsx | 70 | ||||
-rw-r--r-- | src/client/views/StyleProvider.tsx | 17 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/LinkBox.tsx | 7 |
5 files changed, 37 insertions, 67 deletions
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index ca1cb8014..f469f2ef8 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -132,9 +132,9 @@ export namespace InteractionUtils { const Tag = (bezier ? 'path' : 'polyline') as keyof JSX.IntrinsicElements; const markerStrokeWidth = strokeWidth / 2; - const arrowWidthFactor = 3 * (markerScale || 0.5); // used to be 1.5 - const arrowLengthFactor = 5 * (markerScale || 0.5); - const arrowNotchFactor = 2 * (markerScale || 0.5); + const arrowWidthFactor = markerScale || 0.5; // used to be 1.5 + const arrowLengthFactor = (5 / 3) * (markerScale || 0.5); + const arrowNotchFactor = (2 / 3) * (markerScale || 0.5); return ( <svg fill={color || 'transparent'} style={{ transition: 'inherit' }} onPointerDown={downHdlr}> {' '} @@ -148,7 +148,7 @@ export namespace InteractionUtils { )} {arrowStart !== 'dot' && arrowEnd !== 'dot' ? null : ( <marker id={`dot${defGuid}`} orient="auto" markerUnits="userSpaceOnUse" refX={0} refY="0" overflow="visible"> - <circle r={strokeWidth * arrowWidthFactor} fill="context-stroke" /> + <circle r={(strokeWidth * arrowWidthFactor) / 2} fill="context-stroke" /> </marker> )} {arrowStart !== 'arrow' ? null : ( diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index f7c4b464c..b4ea1f07b 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -880,18 +880,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps set colorFil(value) { this.selectedStrokes.forEach(doc => { const inkStroke = DocumentView.getDocumentView(doc)?.ComponentView as InkingStroke; - const { inkData } = inkStroke.inkScaledData(); - if (InkingStroke.IsClosed(inkData)) { + const inkData = inkStroke?.inkScaledData?.().inkData; + if (!inkData || InkingStroke.IsClosed(inkData)) { doc.$fillColor = value || undefined; } }); } @computed get colorStk() { return StrCast(this.selectedStrokes.lastElement()?.$color); } // prettier-ignore - set colorStk(value) { - this.selectedStrokes.forEach(doc => { - doc.$color = value || undefined; - }); - } + set colorStk(value) { this.selectedStrokes.forEach(doc => (doc.$color = value || undefined)); } // prettier-ignore @computed get borderColor() { return StrCast(this.selectedDoc._color); } @@ -1023,47 +1019,21 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps ); } - @computed get dashdStk() { return this.selectedStrokes[0]?.stroke_dash || ''; } // prettier-ignore - set dashdStk(value) { - value && (this._lastDash = value as string); - this.selectedStrokes.forEach(doc => { - doc.$stroke_dash = value ? this._lastDash : undefined; - }); - } - @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore - set widthStk(value) { - this.selectedStrokes.forEach(doc => { - doc.$stroke_width = Number(value); - }); - } - @computed get markScal() { return Number(this.getField('stroke_markerScale') || '1'); } // prettier-ignore - set markScal(value) { - this.selectedStrokes.forEach(doc => { - doc.$stroke_markerScale = Number(value); - }); - } + @computed get dashdStk() { return this.selectedStrokes[0]?.stroke_dash || ''; } // prettier-ignore + set dashdStk(value) { value && (this._lastDash = value as string); + this.selectedStrokes.forEach(doc => (doc.$stroke_dash = value ? this._lastDash : undefined)); } // prettier-ignore + @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore + set widthStk(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_width = Number(value))); } // prettier-ignore + @computed get markScal() { return Number(this.getField('stroke_markerScale') || '1'); } // prettier-ignore + set markScal(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_markerScale = Number(value))); } // prettier-ignore @computed get refStrength() { return Number(this.getField('drawing_refStrength') || '50'); } // prettier-ignore - set refStrength(value) { - this.selectedDoc.$drawing_refStrength = Number(value); - } - @computed get smoothAmt() { return Number(this.getField('stroke_smoothAmount') || '5'); } // prettier-ignore - set smoothAmt(value) { - this.selectedStrokes.forEach(doc => { - doc.$stroke_smoothAmount = Number(value); - }); - } - @computed get markHead() { return this.getField('stroke_startMarker') || ''; } // prettier-ignore - set markHead(value) { - this.selectedStrokes.forEach(doc => { - doc.$stroke_startMarker = value; - }); - } - @computed get markTail() { return this.getField('stroke_endMarker') || ''; } // prettier-ignore - set markTail(value) { - this.selectedStrokes.forEach(doc => { - doc.$stroke_endMarker = value; - }); - } + set refStrength(value) { this.selectedDoc.$drawing_refStrength = Number(value); } // prettier-ignore + @computed get smoothAmt() { return Number(this.getField('stroke_smoothAmount') || '5'); } // prettier-ignore + set smoothAmt(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_smoothAmount = Number(value))) } // prettier-ignore + @computed get markHead() { return this.getField('stroke_startMarker') || ''; } // prettier-ignore + set markHead(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_startMarker = value)); } // prettier-ignore + @computed get markTail() { return this.getField('stroke_endMarker') || ''; } // prettier-ignore + set markTail(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_endMarker = value)); } // prettier-ignore regInput = (key: string, value: string | number | undefined, setter: (val: string) => void) => ( <div className="inputBox"> @@ -1160,16 +1130,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps </div> <div className="dashed"> <div className="dashed-title">Dashed Line:</div> - <input key="markHead" className="dashed-input" type="checkbox" checked={this.dashdStk === '2'} onChange={this.changeDash} /> + <input key="markHead" className="dashed-input" type="checkbox" checked={!!this.dashdStk} onChange={this.changeDash} /> </div> </div> ); } @undoBatch - changeDash = () => { - this.dashdStk = this.dashdStk === '2' ? '0' : '2'; - }; + changeDash = () => (this.dashdStk = this.dashdStk ? '' : '2'); @computed get inkEditor() { return ( diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index b52f17102..ca089a2fc 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -83,7 +83,6 @@ export function SetFilterOpener(func: () => void) { export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string) { const remoteDocHeader = 'author;author_date;noMargin'; const isCaption = property.includes(':caption'); - const isAnchor = property.includes(':anchor'); const isNonTransparent = property.includes(':nonTransparent'); const isNonTransparentLevel = isNonTransparent ? Number(property.replace(/.*:nonTransparent([0-9]+).*/, '$1')) : 0; // property.includes(':nonTransparent'); const isAnnotated = property.includes(':annotated'); @@ -251,14 +250,16 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & const dataKey = doc ? Doc.LayoutDataKey(doc) : ''; const usePath = StrCast(doc?.[dataKey + '_usePath']); const alternate = usePath.includes(':hover') ? ( isHovering?.() ? '_' + usePath.replace(':hover','') : '') : usePath ? "_" +usePath:usePath; - let docColor:Opt<string> = layoutDoc && - StrCast(alternate ? layoutDoc['backgroundColor' + alternate]:undefined, + const colorKey = doc?.layout_isSvg ? "fillColor" : "backgroundColor"; + const docColorFn = (key: string) => layoutDoc && + StrCast(alternate ? layoutDoc[key + alternate]:undefined, DocCast(doc.rootDocument) - ? StrCast(layoutDoc.backgroundColor, StrCast(DocCast(doc.rootDocument)!.backgroundColor)) // for nested templates: use template's color, then root doc's color + ? StrCast(layoutDoc[key], StrCast(DocCast(doc.rootDocument)![key])) // for nested templates: use template's color, then root doc's color : layoutDoc === doc - ? StrCast(doc.backgroundColor) - : StrCast(StrCast(Doc.GetT(layoutDoc, 'backgroundColor', 'string', true), StrCast(doc.backgroundColor, StrCast(layoutDoc.backgroundColor)) // otherwise, use expanded template coloor, then root doc's color, then template's inherited color - ))); + ? StrCast(doc[key]) + : StrCast(StrCast(Doc.GetT(layoutDoc, key, 'string', true), StrCast(doc[key], StrCast(layoutDoc[key])) // otherwise, use expanded template coloor, then root doc's color, then template's inherited color + ))) + let docColor = docColorFn(colorKey); // prettier-ignore switch (layoutDoc?.type) { @@ -266,11 +267,11 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & case DocumentType.PRES: docColor = docColor || 'transparent'; break; case DocumentType.FONTICON: docColor = boxBackground ? undefined : docColor || SnappingManager.userBackgroundColor; break; case DocumentType.RTF: docColor = docColor || StrCast(Doc.UserDoc().textBackgroundColor, Colors.LIGHT_GRAY); break; - case DocumentType.LINK: docColor = (isAnchor ? docColor : undefined); break; case DocumentType.INK: docColor = doc?.stroke_isInkMask ? 'rgba(0,0,0,0.7)' : undefined; break; case DocumentType.EQUATION: docColor = docColor || StrCast(Doc.UserDoc().textBackgroundColor, 'transparent'); break; case DocumentType.LABEL: docColor = docColor || Colors.LIGHT_GRAY; break; case DocumentType.BUTTON: docColor = docColor || Colors.LIGHT_GRAY; break; + case DocumentType.LINK: docColor = docColor || docColorFn('backgroundColor'); break; case DocumentType.IMG: case DocumentType.WEB: case DocumentType.PDF: diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 90edab3a7..d32f55e64 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1651,7 +1651,7 @@ export function ActiveInkColor(): string { return StrCast(Doc.UserDoc()?.[`activ export function ActiveInkArrowStart(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}ArrowStart`], ''); } // prettier-ignore export function ActiveInkArrowEnd(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}ArrowEnd`], ''); } // prettier-ignore export function ActiveInkArrowScale(): number { return NumCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}ArrowScale`], 1); } // prettier-ignore -export function ActiveInkDash(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}Dash`], '0'); } // prettier-ignore +export function ActiveInkDash(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}Dash`], ''); } // prettier-ignore export function ActiveInkWidth(): number { return Number(Doc.UserDoc()?.[`active${Doc.ActiveInk}Width`]); } // prettier-ignore export function ActiveInkBezierApprox(): string { return StrCast(Doc.UserDoc()[`active${Doc.ActiveInk}Bezier`]); } // prettier-ignore diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index d31fadf77..88e327a09 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -164,13 +164,14 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { } const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting) as { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean }; const highlightColor = highlight?.highlightIndex ? highlight?.highlightColor : undefined; - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string; const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) as string; const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) as number; const fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor)); const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document; const strokeWidth = NumCast(strokeRawWidth, 1); + const strokeDashLen = strokeDash ? Number(strokeDash) * strokeWidth : undefined; const linkDesc = StrCast(this.dataDoc.link_description) || ' '; const labelText = linkDesc.substring(0, 50) + (linkDesc.length > 50 ? '...' : ''); return ( @@ -195,7 +196,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() { start={aid} end={bid} // strokeWidth={strokeWidth} - dashness={!!Number(strokeDash)} + dashness={!strokeDashLen ? undefined : { strokeLen: strokeDashLen, nonStrokeLen: strokeDashLen }} showHead={!!strokeStartMarker} showTail={!!strokeEndMarker} headSize={NumCast(strokeMarkerScale, 3)} @@ -299,7 +300,7 @@ Docs.Prototypes.TemplateMap.set(DocumentType.LINK, { _width: 1, link: '', link_description: '', - color: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area + backgroundColor: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area _dropPropertiesToRemove: new List(['onClick']), }, }); |