diff options
Diffstat (limited to 'src/client/views')
| -rw-r--r-- | src/client/views/StyleProp.ts | 1 | ||||
| -rw-r--r-- | src/client/views/StyleProvider.tsx | 51 | ||||
| -rw-r--r-- | src/client/views/global/globalScripts.ts | 55 | ||||
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 21 | ||||
| -rw-r--r-- | src/client/views/nodes/FontIconBox/FontIconBox.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 |
7 files changed, 97 insertions, 36 deletions
diff --git a/src/client/views/StyleProp.ts b/src/client/views/StyleProp.ts index 56367e70b..1ef7a9e1f 100644 --- a/src/client/views/StyleProp.ts +++ b/src/client/views/StyleProp.ts @@ -5,6 +5,7 @@ export enum StyleProp { Opacity = 'opacity', // opacity of the document view BoxShadow = 'boxShadow', // box shadow - used for making collections standout and for showing clusters in free form views BorderRounding = 'borderRounding', // border radius of the document view + Border = 'border', // border of document view Color = 'color', // foreground color of Document view items BackgroundColor = 'backgroundColor', // background color of a document view FillColor = 'fillColor', // fill color of an ink stroke or shape diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index bebc9a341..b04b1ae65 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -206,33 +206,40 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & const rounding = StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : '')); return (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc || doc?.isTemplateDoc) ? StrCast(doc._layout_borderRounding,rounding) : rounding; } + case StyleProp.Border: { + const bcolor = StrCast(doc?.borderColor, StrCast(doc?.[fieldKey + 'borderColor'], StrCast(doc?.layout_borderColor))); + return bcolor + " " + + StrCast(doc?.borderStyle, StrCast(doc?.[fieldKey + 'borderStyle'], StrCast(doc?.layout_borderStyle, "solid"))) + " " + + (StrCast(doc?.borderWidth || doc?.[fieldKey + 'borderWidth'] || doc?.layout_borderWidth) || + (NumCast(doc?.borderWidth, NumCast(doc?.[fieldKey + 'borderWidth'], NumCast(doc?.layout_borderWidth, bcolor ?1:0)))+"px")) + } // Doc.IsComicStyle(doc) && // renderDepth && // !doc?.layout_isSvg && //case StyleProp. - case StyleProp.BorderPath: { - const docWidth = Number(doc?._width); - const borderWidth = Number(StrCast(doc?.borderWidth)); - //console.log(borderWidth); - const ratio = borderWidth / docWidth; - const borderRadius = Number(StrCast(layoutDoc?._layout_borderRounding).replace('px', '')); - const radiusRatio = borderRadius / docWidth; - const radius = radiusRatio * ((2 * borderWidth) + docWidth); + // case StyleProp.BorderPath: { + // const docWidth = Number(doc?._width); + // const borderWidth = Number(StrCast(doc?.borderWidth)); + // //console.log(borderWidth); + // const ratio = borderWidth / docWidth; + // const borderRadius = Number(StrCast(layoutDoc?._layout_borderRounding).replace('px', '')); + // const radiusRatio = borderRadius / docWidth; + // const radius = radiusRatio * ((2 * borderWidth) + docWidth); - const borderPath = doc && border(doc, NumCast(doc._width), NumCast(doc._height), radius, -ratio/2); - return !borderPath - ? null - : { - clipPath: `path('${borderPath}')`, - jsx: ( - <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}> - <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${PanelWidth?.()} ${PanelHeight?.()}`}> - <path d={borderPath} style={{ stroke: StrCast(doc?.borderColor), fill: 'transparent', strokeWidth: `${StrCast(doc?.borderWidth)}px` }} /> - </svg> - </div> - ), - }; - } + // const borderPath = doc && border(doc, NumCast(doc._width), NumCast(doc._height), radius, -ratio/2); + // return !borderPath + // ? null + // : { + // clipPath: `path('${borderPath}')`, + // jsx: ( + // <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}> + // <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${PanelWidth?.()} ${PanelHeight?.()}`}> + // <path d={borderPath} style={{ stroke: StrCast(doc?.borderColor), fill: 'transparent', strokeWidth: `${StrCast(doc?.borderWidth)}px` }} /> + // </svg> + // </div> + // ), + // }; + // } case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._type_collection as CollectionViewType) || (doc?.type === DocumentType.RTF && !layoutShowTitle()?.includes('noMargin')) || diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 79873ed8f..b455f76e4 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -68,6 +68,49 @@ ScriptingGlobals.add(function setView(view: string, shiftKey: boolean, checkResu // toggle: Set overlay status of selected document // eslint-disable-next-line prefer-arrow-callback +ScriptingGlobals.add(function setBorderColor(color?: string, checkResult?: boolean) { + const selectedViews = DocumentView.Selected(); + const defaultBorder = () => StrCast(Doc.UserDoc().borderColor, 'transparent'); + const setDefaultBorder = (c: string) => { Doc.UserDoc().borderColor = c; }; // prettier-ignore + const fieldKey = 'borderColor'; + if (selectedViews.length) { + if (checkResult) { + const selView = selectedViews.lastElement(); + const layoutFrameNumber = Cast(selView.containerViewPath?.().lastElement()?.Document?._currentFrame, 'number'); // frame number that container is at which determines layout frame values + const contentFrameNumber = Cast(selView.Document?._currentFrame, 'number', layoutFrameNumber ?? null); // frame number that content is at which determines what content is displayed + return CollectionFreeFormDocumentView.getStringValues(selView?.Document, contentFrameNumber)[fieldKey] || defaultBorder(); + } + setDefaultBorder(color ?? 'transparent'); + selectedViews.forEach(dv => { + const layoutFrameNumber = Cast(dv.containerViewPath?.().lastElement()?.Document?._currentFrame, 'number'); // frame number that container is at which determines layout frame values + const contentFrameNumber = Cast(dv.Document?._currentFrame, 'number', layoutFrameNumber ?? null); // frame number that content is at which determines what content is displayed + if (contentFrameNumber !== undefined) { + const obj: { [key: string]: Opt<string> } = {}; + obj[fieldKey] = color; + CollectionFreeFormDocumentView.setStringValues(contentFrameNumber, dv.Document, obj); + } else { + const dataKey = Doc.LayoutFieldKey(dv.Document); + const alternate = (dv.layoutDoc[dataKey + '_usePath'] ? '_' + dv.layoutDoc[dataKey + '_usePath'] : '').replace(':hover', ''); + dv.layoutDoc[fieldKey + alternate] = undefined; + dv.dataDoc[fieldKey + alternate] = color; + } + }); + } else { + const selected = DocumentView.SelectedDocs().length ? DocumentView.SelectedDocs() : LinkManager.Instance.currentLink ? [LinkManager.Instance.currentLink] : []; + if (checkResult) { + return (selected.lastElement() ?? Doc.UserDoc()).borderColor ?? defaultBorder(); + } + if (!selected.length) setDefaultBorder(color ?? 'transparent'); + else + selected.forEach(doc => { + doc[DocData].borderColor = color; + }); + } + return ''; +}); + +// toggle: Set overlay status of selected document +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: boolean) { const selectedViews = DocumentView.Selected(); const selectedDoc = selectedViews.lastElement()?.Document; @@ -408,6 +451,18 @@ ScriptingGlobals.add(function activeEraserTool() { return StrCast(Doc.UserDoc().activeEraserTool, InkEraserTool.Stroke); }, 'returns the current eraser tool'); +// eslint-disable-next-line prefer-arrow-callback +ScriptingGlobals.add(function setBorderWidth(value: number, checkResult?: boolean) { + const selected = DocumentView.SelectedDocs().lastElement(); + if (checkResult) return NumCast((selected ?? Doc.UserDoc()).borderWidth); + if (!selected) Doc.UserDoc().borderWidth = value; + else + DocumentView.SelectedDocs().map(doc => { + doc.borderWidth = value; + }); + return undefined; +}, 'sets the border width of the selected document'); + // toggle: Set overlay status of selected document // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function setInkProperty(option: InkProperty, value: string | number, checkResult?: boolean) { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index beea6ab3c..76d6ed80b 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -69,7 +69,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF { key: 'freeform_panX' }, { key: 'freeform_panY' }, ]; // fields that are configured to be animatable using animation frames - public static animStringFields = ['backgroundColor', 'color', 'fillColor']; // fields that are configured to be animatable using animation frames + public static animStringFields = ['backgroundColor', 'borderColor', 'color', 'fillColor']; // fields that are configured to be animatable using animation frames public static animDataFields = (doc: Doc) => (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames public static from(dv?: DocumentView): CollectionFreeFormDocumentView | undefined { return dv?._props.reactParent instanceof CollectionFreeFormDocumentView ? dv._props.reactParent : undefined; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0193fd328..441d6053f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -131,6 +131,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document style = (doc: Doc, sprop: StyleProp | string) => this._props.styleProvider?.(doc, this._props, sprop); @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity) as number; } // prettier-ignore @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow) as string; } // prettier-ignore + @computed get border() { return this.style(this.layoutDoc, StyleProp.Border) as string || ""; } // prettier-ignore @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding) as string; } // prettier-ignore @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations) as JSX.Element; } // prettier-ignore @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView') as string; } // prettier-ignore @@ -684,14 +685,14 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document }; rootSelected = () => this._rootSelected; - panelHeight = () => this._props.PanelHeight() - this.headerMargin; + panelHeight = () => this._props.PanelHeight() - this.headerMargin - 2 * NumCast(this.Document.borderWidth); screenToLocalContent = () => this._props .ScreenToLocalTransform() - .translate(0, -this.headerMargin) + .translate(-NumCast(this.Document.borderWidth), -this.headerMargin - NumCast(this.Document.borderWidth)) .scale(this._props.showAIEditor ? (this._props.PanelHeight() || 1) / this.aiContentsHeight() : 1); onClickFunc = this.disableClickScriptFunc ? undefined : () => this.onClickHdlr; - setHeight = (height: number) => { !this._props.suppressSetHeight && (this.layoutDoc._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), height)); } // prettier-ignore + setHeight = (height: number) => { !this._props.suppressSetHeight && (this.layoutDoc._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), height + 2 * NumCast(this.Document.borderWidth))); } // prettier-ignore setContentView = action((view: ViewBoxInterface<FieldViewProps>) => { this._componentView = view; }); // prettier-ignore isContentActive = (): boolean | undefined => this._isContentActive; childFilters = () => [...this._props.childFilters(), ...StrListCast(this.layoutDoc.childFilters)]; @@ -989,15 +990,11 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document highlightStroke: undefined, }; const { clipPath, jsx } = (borderPath as { clipPath: string; jsx: JSX.Element }) ?? { clipPath: undefined, jsx: undefined }; - const boxShadow = !highlighting - ? this.boxShadow - : highlighting && this.borderRounding && highlightStyle !== 'dashed' - ? `0 0 0 ${highlightIndex}px ${highlightColor}` - : this.boxShadow || (this.Document.isTemplateForField ? 'black 0.2vw 0.2vw 0.8vw' : undefined); + const boxShadow = this.boxShadow; const renderDoc = this.renderDoc({ borderRadius: this.borderRounding, - outline: highlighting && !this.borderRounding && !highlightStroke ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : 'solid 0px', - border: highlighting && this.borderRounding && highlightStyle === 'dashed' ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined, + outline: highlighting && !highlightStroke ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : 'solid 0px', + border: this._componentView?.isUnstyledView?.() ? undefined : this.border, boxShadow, clipPath, }); @@ -1013,7 +1010,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document onPointerOver={() => (!SnappingManager.IsDragging || SnappingManager.CanEmbed) && Doc.BrushDoc(this.Document)} onPointerLeave={e => !isParentOf(this._contentDiv, document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y)) && Doc.UnBrushDoc(this.Document)} style={{ - borderRadius: this.borderRounding, + borderRadius: this._componentView?.isUnstyledView?.() ? undefined : this.borderRounding, pointerEvents: this._pointerEvents === 'visiblePainted' ? 'none' : this._pointerEvents, // visible painted means that the underlying doc contents are irregular and will process their own pointer events (otherwise, the contents are expected to fill the entire doc view box so we can handle pointer events here) }}> {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG || !renderDoc ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)} @@ -1487,7 +1484,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { ShouldNotScale = () => this.shouldNotScale; NativeWidth = () => this.effectiveNativeWidth; NativeHeight = () => this.effectiveNativeHeight; - PanelWidth = () => this.panelWidth; + PanelWidth = () => this.panelWidth - 2 * NumCast(this.Document.borderWidth); PanelHeight = () => this.panelHeight; ReducedPanelWidth = () => this.panelWidth / 2; ReducedPanelHeight = () => this.panelWidth / 2; diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index f58862028..f60c83343 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -134,6 +134,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() { min={NumCast(this.dataDoc.numBtnMin, 0)} max={NumCast(this.dataDoc.numBtnMax, 100)} number={checkResult} + size={Size.XSMALL} setNumber={undoable(value => numScript(value), `${this.Document.title} button set from list`)} fillWidth /> diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 3abb39ff2..da2131940 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1282,7 +1282,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB ); this._disposers.componentHeights = reaction( // set the document height when one of the component heights changes and layout_autoHeight is on - () => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, layoutAutoHeight: this.layout_autoHeight, marginsHeight: this.layout_autoHeightMargins }), + () => ({ border: this._props.PanelHeight(), sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, layoutAutoHeight: this.layout_autoHeight, marginsHeight: this.layout_autoHeightMargins }), ({ sidebarHeight, textHeight, layoutAutoHeight, marginsHeight }) => { const newHeight = this.contentScaling * (marginsHeight + Math.max(sidebarHeight, textHeight)); if ( |
