From a8664face6f19cd2373bd928c2a2b3043bb6278d Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 2 Jul 2019 19:02:51 -0400 Subject: Added arrange script to freeform views --- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 858959d81..8556817cc 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -9,6 +9,10 @@ import "./DocumentView.scss"; import React = require("react"); export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { + x?: number; + y?: number; + width?: number; + height?: number; } const schema = createSchema({ @@ -23,13 +27,13 @@ const FreeformDocument = makeInterface(schema, positionSchema); @observer export class CollectionFreeFormDocumentView extends DocComponent(FreeformDocument) { @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) scale(${this.zoom}) `; } - @computed get X() { return FieldValue(this.Document.x, 0); } - @computed get Y() { return FieldValue(this.Document.y, 0); } + @computed get X() { return this.props.x !== undefined ? this.props.x : this.Document.x || 0; } + @computed get Y() { return this.props.y !== undefined ? this.props.y : this.Document.y || 0; } + @computed get width(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.props.width !== undefined ? this.props.width : this.Document.width || 0; } + @computed get height(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.props.height !== undefined ? this.props.height : this.Document.height || 0; } @computed get zoom(): number { return 1 / FieldValue(this.Document.zoomBasis, 1); } @computed get nativeWidth(): number { return FieldValue(this.Document.nativeWidth, 0); } @computed get nativeHeight(): number { return FieldValue(this.Document.nativeHeight, 0); } - @computed get width(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : FieldValue(this.Document.width, 0); } - @computed get height(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : FieldValue(this.Document.height, 0); } set width(w: number) { this.Document.width = w; -- cgit v1.2.3-70-g09d2 From d059c64a7b3ce424b8c41c485c7c58c0d4bfbae8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 2 Jul 2019 21:42:08 -0400 Subject: fixed doc decorations border for documents laid out with arrangeScripts --- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 8556817cc..5171f7a04 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -52,7 +52,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.props.PanelHeight(); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.zoom) + .scale(1 / this.contentScaling()).scale(1 / this.zoom * NumCast(this.props.Document.width, this.width) / this.width) animateBetweenIcon = (icon: number[], stime: number, maximizing: boolean) => { this.props.bringToFront(this.props.Document); -- cgit v1.2.3-70-g09d2 From 5e35e1895bb54568bbf8cc3991480e20edd1de83 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 2 Jul 2019 23:28:57 -0400 Subject: fixed issue with editing applied template text boxes. --- src/client/views/MainOverlayTextBox.tsx | 7 +++++-- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 3 ++- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index d31319429..7d15702a2 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -30,6 +30,7 @@ export class MainOverlayTextBox extends React.Component private _textBox: FormattedTextBox | undefined; private _tooltip?: HTMLElement; @observable public TextDoc?: Doc; + @observable public TextDataDoc?: Doc; updateTooltip = () => { this._outerdiv && this._tooltip && !this._outerdiv.contains(this._tooltip) && this._outerdiv.appendChild(this._tooltip); @@ -43,13 +44,15 @@ export class MainOverlayTextBox extends React.Component (box?: FormattedTextBox) => { this._textBox = box; if (box) { - this.TextDoc = box.props.DataDoc; + this.TextDoc = box.props.Document; + this.TextDataDoc = box.props.DataDoc; let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined); let xf = () => { box.props.ScreenToLocalTransform(); return new Transform(-sxf.translateX, -sxf.translateY, 1 / sxf.scale); }; this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf, BoolCast(box.props.Document.autoHeight, false) || box.props.height === "min-content"); } else { this.TextDoc = undefined; + this.TextDataDoc = undefined; this.setTextDoc(); } }); @@ -114,7 +117,7 @@ export class MainOverlayTextBox extends React.Component } } render() { - this.TextDoc; + this.TextDoc; this.TextDataDoc; if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) { let textRect = this._textTargetDiv.getBoundingClientRect(); let s = this._textXf().Scale; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 5171f7a04..3f9270597 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -47,12 +47,13 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; panelWidth = () => this.props.PanelWidth(); panelHeight = () => this.props.PanelHeight(); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.zoom * NumCast(this.props.Document.width, this.width) / this.width) + .scale(1 / this.contentScaling()).scale(1 / this.zoom / this.scaleToOverridingWidth) animateBetweenIcon = (icon: number[], stime: number, maximizing: boolean) => { this.props.bringToFront(this.props.Document); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 07cd43ce3..1eeb04755 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -211,7 +211,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe const field = this.dataDoc ? Cast(this.dataDoc[this.props.fieldKey], RichTextField) : undefined; return field ? field.Data : `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`; }, - field => this._editorView && !this._applyingChange && this.props.Document[this.props.fieldKey] instanceof RichTextField && + field => this._editorView && !this._applyingChange && this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field))) ); this.setupEditor(config, this.dataDoc, this.props.fieldKey); -- cgit v1.2.3-70-g09d2 From c77dfd3fcb2df644fcf2c177db7e6e376ca4c3a9 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 3 Jul 2019 14:29:53 -0400 Subject: quick and dirty arrange transition animations --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 5 ++++- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index cb7be3f28..6b0cb5728 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,6 +1,6 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCastAsync, HeightSym, WidthSym } from "../../../../new_fields/Doc"; +import { Doc, DocListCastAsync, HeightSym, WidthSym, DocListCast } from "../../../../new_fields/Doc"; import { Id } from "../../../../new_fields/FieldSymbols"; import { InkField, StrokeData } from "../../../../new_fields/InkField"; import { createSchema, makeInterface } from "../../../../new_fields/Schema"; @@ -458,6 +458,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { ContextMenu.Instance.addItem({ description: "Add freeform arrangement", event: () => { + const docs = DocListCast(this.Document[this.props.fieldKey]); + docs.map(d => d.transition = "transform 1s"); let overlayDisposer: () => void; let scriptingBox = overlayDisposer()} onSave={(text, onError) => { const script = CompileScript(text, { @@ -473,6 +475,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } this.props.Document.arrangeScript = new ScriptField(script); overlayDisposer(); + setTimeout(() => docs.map(d => d.transition = undefined), 1200); }} />; overlayDisposer = OverlayView.Instance.addElement(scriptingBox, { x: 100, y: 100, width: 200, height: 200 }); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3f9270597..30cf74f3e 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,7 +1,7 @@ import { computed } from "mobx"; import { observer } from "mobx-react"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; -import { BoolCast, FieldValue, NumCast } from "../../../new_fields/Types"; +import { BoolCast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types"; import { Transform } from "../../util/Transform"; import { DocComponent } from "../DocComponent"; import { DocumentView, DocumentViewProps, positionSchema } from "./DocumentView"; @@ -86,6 +86,7 @@ export class CollectionFreeFormDocumentView extends DocComponent Date: Thu, 4 Jul 2019 14:08:00 -0400 Subject: added text font color setting. adding interactive border radius. moved main toolbar. --- src/client/documents/Documents.ts | 4 +-- src/client/util/DragManager.ts | 1 + src/client/util/RichTextSchema.tsx | 11 ++++++++ src/client/util/TooltipTextMenu.tsx | 3 +- src/client/views/DocumentDecorations.scss | 22 +++++++++++++++ src/client/views/DocumentDecorations.tsx | 32 ++++++++++++++++++++++ src/client/views/InkingControl.tsx | 3 ++ src/client/views/Main.scss | 2 +- src/client/views/MainOverlayTextBox.tsx | 5 ++++ src/client/views/MainView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 16 ++++------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 15 ++++++---- src/client/views/nodes/DocumentView.tsx | 4 +-- src/client/views/nodes/FormattedTextBox.tsx | 11 +++++++- 14 files changed, 106 insertions(+), 25 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 7a976e7d7..2bddf053a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -77,7 +77,7 @@ export interface DocumentOptions { backgroundLayout?: string; curPage?: number; documentText?: string; - borderRounding?: number; + borderRounding?: string; schemaColumns?: List; dockingConfig?: string; dbDoc?: Doc; @@ -93,7 +93,7 @@ export namespace DocUtils { if (target === CurrentUserUtils.UserDocument) return; UndoManager.RunInBatch(() => { - let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 }); + let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: "100%" }); linkDoc.type = DocTypes.LINK; let linkDocProto = Doc.GetProto(linkDoc); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 7dc48fb78..d4b1bc8f4 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -315,6 +315,7 @@ export namespace DragManager { scaleYs.push(scaleY); let dragElement = ele.cloneNode(true) as HTMLElement; dragElement.style.opacity = "0.7"; + dragElement.style.borderRadius = getComputedStyle(ele).borderRadius; dragElement.style.position = "absolute"; dragElement.style.margin = "0"; dragElement.style.top = "0"; diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 63c879d67..2a57180d3 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -348,6 +348,17 @@ export const marks: { [index: string]: MarkSpec } = { }] }, + pFontColor: { + attrs: { + color: { default: "yellow" } + }, + parseDOM: [{ style: 'background: #d9dbdd' }], + toDOM: (node) => { + return ['span', { + style: `color: ${node.attrs.color}` + }]; + } + }, /** FONT SIZES */ pFontSize: { diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 9f8d0b2f6..e3e26d1f4 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -111,7 +111,8 @@ export class TooltipTextMenu { this.fontSizeToNum.set(schema.marks.p32, 32); this.fontSizeToNum.set(schema.marks.p48, 48); this.fontSizeToNum.set(schema.marks.p72, 72); - //this.fontSizeToNum.set(schema.marks.pFontSize,schema.marks.pFontSize.) + this.fontSizeToNum.set(schema.marks.pFontSize, 10); + this.fontSizeToNum.set(schema.marks.pFontSize, 10); this.fontSizes = Array.from(this.fontSizeToNum.keys()); //list types diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index ba9f32d7d..2d430512b 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -26,6 +26,14 @@ $linkGap : 3px; opacity: 0.8; } + .documentDecorations-radius { + pointer-events: auto; + background: black; + opacity: 0.8; + transform: translate(10px, 10px); + grid-row: 4; + } + #documentDecorations-topLeftResizer, #documentDecorations-leftResizer, #documentDecorations-bottomLeftResizer { @@ -44,11 +52,25 @@ $linkGap : 3px; grid-column-start: 5; grid-column-end: 7; } + + #documentDecorations-borderRadius{ + grid-column-start: 5; + grid-column-end: 7; + border-radius: 100%; + .borderRadiusTooltip{ + width:10px; + height:10px; + position:absolute; + } + } #documentDecorations-topLeftResizer, #documentDecorations-bottomRightResizer { cursor: nwse-resize; } + #documentDecorations-bottomRightResizer { + grid-row:4; + } #documentDecorations-topRightResizer, #documentDecorations-bottomLeftResizer { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3df520428..c7990647a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -341,6 +341,37 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> iconDoc.y = where[1] + NumCast(selView.props.Document.y); } + _radiusDown = [0, 0]; + @action + onRadiusDown = (e: React.PointerEvent): void => { + e.stopPropagation(); + if (e.button === 0) { + this._radiusDown = [e.clientX, e.clientY]; + this._isPointerDown = true; + this._resizeUndo = UndoManager.StartBatch("DocDecs set radius"); + document.removeEventListener("pointermove", this.onRadiusMove); + document.removeEventListener("pointerup", this.onRadiusUp); + document.addEventListener("pointermove", this.onRadiusMove); + document.addEventListener("pointerup", this.onRadiusUp); + } + } + + onRadiusMove = (e: PointerEvent): void => { + let dist = Math.sqrt((e.clientX - this._radiusDown[0]) * (e.clientX - this._radiusDown[0]) + (e.clientY - this._radiusDown[1]) * (e.clientY - this._radiusDown[1])); + SelectionManager.SelectedDocuments().map(dv => Doc.GetProto(dv.props.Document).borderRounding = `${Math.min(100, dist)}%`); + e.stopPropagation(); + e.preventDefault(); + } + + onRadiusUp = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isPointerDown = false; + this._resizeUndo && this._resizeUndo.end(); + document.removeEventListener("pointermove", this.onRadiusMove); + document.removeEventListener("pointerup", this.onRadiusUp); + } + @action onPointerDown = (e: React.PointerEvent): void => { e.stopPropagation(); @@ -705,6 +736,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
e.preventDefault()}>
e.preventDefault()}>
e.preventDefault()}>
+
e.preventDefault()}>
{linkButton}
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index 0461d7299..c7f7bdb66 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -10,6 +10,8 @@ import { InkTool } from "../../new_fields/InkField"; import { Doc } from "../../new_fields/Doc"; import { undoBatch, UndoManager } from "../util/UndoManager"; import { StrCast } from "../../new_fields/Types"; +import { FormattedTextBox } from "./nodes/FormattedTextBox"; +import { MainOverlayTextBox } from "./MainOverlayTextBox"; library.add(faPen, faHighlighter, faEraser, faBan); @@ -42,6 +44,7 @@ export class InkingControl extends React.Component { switchColor = action((color: ColorResult): void => { this._selectedColor = color.hex + (color.rgb.a !== undefined ? this.decimalToHexString(Math.round(color.rgb.a * 255)) : "ff"); if (InkingControl.Instance.selectedTool === InkTool.None) { + if (MainOverlayTextBox.Instance.SetColor(color.hex)) return; let selected = SelectionManager.SelectedDocuments(); let oldColors = selected.map(view => { let targetDoc = view.props.Document.isTemplate ? view.props.Document : Doc.GetProto(view.props.Document); diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 44c1cb9fc..b85a8040a 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -144,7 +144,7 @@ button:hover { #add-nodes-menu { position: absolute; bottom: 22px; - left: 24px; + left: 250px; > label { background: $dark-color; diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 7d15702a2..d8aaea259 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -36,6 +36,11 @@ export class MainOverlayTextBox extends React.Component this._outerdiv && this._tooltip && !this._outerdiv.contains(this._tooltip) && this._outerdiv.appendChild(this._tooltip); } + public SetColor(color: string) { + return this._textBox && this._textBox.setFontColor(color); + } + + constructor(props: MainOverlayTextBoxProps) { super(props); this._textProxyDiv = React.createRef(); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 1542fedef..61ccf4c1d 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -354,7 +354,7 @@ export class MainView extends React.Component { [React.createRef(), "tree", "Add Tree", addTreeNode], ]; - return < div id="add-nodes-menu" > + return < div id="add-nodes-menu" style={{ left: this.flyoutWidth + 5 }} > diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 31c0fe499..4850c6218 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -44,14 +44,12 @@ export class MarqueeView extends React.Component _commandExecuted = false; @action - cleanupInteractions = (all: boolean = false, rem_keydown: boolean = true) => { + cleanupInteractions = (all: boolean = false) => { if (all) { document.removeEventListener("pointerup", this.onPointerUp, true); document.removeEventListener("pointermove", this.onPointerMove, true); } - if (rem_keydown) { - document.removeEventListener("keydown", this.marqueeCommand, true); - } + document.removeEventListener("keydown", this.marqueeCommand, true); this._visible = false; } @@ -191,12 +189,9 @@ export class MarqueeView extends React.Component SelectionManager.DeselectAll(mselect.length ? undefined : this.props.container.props.Document); } this.props.selectDocuments(mselect.length ? mselect : [this.props.container.props.Document]); - mselect.length ? this.cleanupInteractions(true, false) : this.cleanupInteractions(true); - } - else { - //console.log("invisible"); - this.cleanupInteractions(true); } + //console.log("invisible"); + this.cleanupInteractions(true); if (e.altKey) { e.preventDefault(); @@ -266,13 +261,12 @@ export class MarqueeView extends React.Component } let ink = Cast(this.props.container.props.Document.ink, InkField); let inkData = ink ? ink.inkData : undefined; - let zoomBasis = NumCast(this.props.container.props.Document.scale, 1); let newCollection = Docs.FreeformDocument(selected, { x: bounds.left, y: bounds.top, panX: 0, panY: 0, - borderRounding: e.key === "e" ? -1 : undefined, + borderRounding: e.key === "e" ? "100%" : undefined, backgroundColor: this.props.container.isAnnotationOverlay ? undefined : "white", width: bounds.width, height: bounds.height, diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 30cf74f3e..1c00687ed 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -70,11 +70,14 @@ export class CollectionFreeFormDocumentView extends DocComponent { - let br = NumCast(this.props.Document.borderRounding); - return br >= 0 ? br : - NumCast(this.props.Document.nativeWidth) === 0 ? - Math.min(this.props.PanelWidth(), this.props.PanelHeight()) - : Math.min(this.Document.nativeWidth || 0, this.Document.nativeHeight || 0); + let br = StrCast(this.props.Document.borderRounding); + if (br.endsWith("%")) { + let percent = Number(br.substr(0, br.length - 1)) / 100; + let nativeDim = Math.min(NumCast(this.props.Document.nativeWidth), NumCast(this.props.Document.nativeHeight)); + let minDim = percent * (nativeDim ? nativeDim : Math.min(this.props.PanelWidth(), this.props.PanelHeight())); + return minDim; + } + return undefined; } render() { @@ -84,7 +87,7 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu style={{ outlineColor: "maroon", outlineStyle: "dashed", - outlineWidth: BoolCast(this.props.Document.libraryBrush) && !NumCast(this.props.Document.borderRounding) ? + outlineWidth: BoolCast(this.props.Document.libraryBrush) && !StrCast(this.props.Document.borderRounding) ? `${this.props.ScreenToLocalTransform().Scale}px` : "0px", - border: BoolCast(this.props.Document.libraryBrush) && NumCast(this.props.Document.borderRounding) ? + border: BoolCast(this.props.Document.libraryBrush) && StrCast(this.props.Document.borderRounding) ? `dashed maroon ${this.props.ScreenToLocalTransform().Scale}px` : undefined, borderRadius: "inherit", background: backgroundColor, diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 1eeb04755..bf6f4c764 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -97,6 +97,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe return ""; } + @undoBatch + public setFontColor(color: string) { + if (this._editorView!.state.selection.from === this._editorView!.state.selection.to) return false; + let colorMark = this._editorView!.state.schema.mark(this._editorView!.state.schema.marks.pFontColor, { color: color }); + this._editorView!.dispatch(this._editorView!.state.tr.addMark(this._editorView!.state.selection.from, + this._editorView!.state.selection.to, colorMark)); + return true; + } + constructor(props: FieldViewProps) { super(props); if (this.props.outer_div) { @@ -418,7 +427,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } render() { let style = this.props.isOverlay ? "scroll" : "hidden"; - let rounded = NumCast(this.props.Document.borderRounding) < 0 ? "-rounded" : ""; + let rounded = StrCast(this.props.Document.borderRounding) === "100%" ? "-rounded" : ""; let interactive = InkingControl.Instance.selectedTool ? "" : "interactive"; return (