From 21b1e20106ff49c02657c88f503ef46bc7e4fb07 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 16 Apr 2019 23:09:03 -0400 Subject: various bug fixes --- src/client/views/collections/CollectionSchemaView.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 4f4068e7a..1defdba7e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -167,7 +167,7 @@ export class CollectionSchemaView extends CollectionSubView { @computed get columns() { - return this.props.Document.GetList(KeyStore.ColumnsKey, []); + return this.props.Document.GetList(KeyStore.ColumnsKey, [] as Key[]); } @action @@ -195,7 +195,7 @@ export class CollectionSchemaView extends CollectionSubView { @computed get findAllDocumentKeys(): { [id: string]: boolean } { - const docs = this.props.Document.GetList(this.props.fieldKey, []); + const docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); let keys: { [id: string]: boolean } = {}; if (this._optionsActivated > -1) { // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. @@ -237,7 +237,7 @@ export class CollectionSchemaView extends CollectionSubView { } @action setScaling = (r: any) => { - const children = this.props.Document.GetList(this.props.fieldKey, []); + const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; this._panelWidth = r.entry.width; this._panelHeight = r.entry.height ? r.entry.height : this._panelHeight; @@ -253,8 +253,10 @@ export class CollectionSchemaView extends CollectionSubView { getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX - this._tableWidth, - this.borderWidth).scale(1 / this._contentScaling); onPointerDown = (e: React.PointerEvent): void => { - if (e.button === 1 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { - e.stopPropagation(); + if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (this.props.isSelected()) + e.stopPropagation(); + else e.preventDefault(); } } @@ -293,7 +295,7 @@ export class CollectionSchemaView extends CollectionSubView { library.add(faCog); library.add(faPlus); const columns = this.columns; - const children = this.props.Document.GetList(this.props.fieldKey, []); + const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; //all the keys/columns that will be displayed in the schema const allKeys = this.findAllDocumentKeys; -- cgit v1.2.3-70-g09d2 From 1319573481868f2647259fce37cd15b35c3cafad Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 17 Apr 2019 12:07:55 -0400 Subject: fixed onactivechanged exception. restored preview region --- src/client/util/SelectionManager.ts | 4 ++-- src/client/views/Main.tsx | 2 +- src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/collections/CollectionBaseView.tsx | 8 ++++---- src/client/views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionSchemaView.tsx | 11 +++++------ .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FieldView.tsx | 4 ++-- src/client/views/nodes/KeyValuePair.tsx | 2 +- 10 files changed, 19 insertions(+), 20 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 320553952..b15a93d9f 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -18,13 +18,13 @@ export namespace SelectionManager { if (manager.SelectedDocuments.indexOf(doc) === -1) { manager.SelectedDocuments.push(doc); - doc.props.onActiveChanged(true); + doc.props.whenActiveChanged(true); } } @action DeselectAll(): void { - manager.SelectedDocuments.map(dv => dv.props.onActiveChanged(false)); + manager.SelectedDocuments.map(dv => dv.props.whenActiveChanged(false)); manager.SelectedDocuments = []; MainOverlayTextBox.Instance.SetTextDoc(); } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 0469211fa..84fdeab92 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -190,7 +190,7 @@ export class Main extends React.Component { selectOnLoad={false} focus={emptyDocFunction} parentActive={returnTrue} - onActiveChanged={emptyFunction} + whenActiveChanged={emptyFunction} ContainingCollectionView={undefined} />} } diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 141b3ad74..8cb01117c 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -101,7 +101,7 @@ export class MainOverlayTextBox extends React.Component return
this._textXf} focus={emptyDocFunction} /> + selectOnLoad={true} ContainingCollectionView={undefined} whenActiveChanged={emptyFunction} active={returnTrue} ScreenToLocalTransform={() => this._textXf} focus={emptyDocFunction} />
; } diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 4fda38a26..a8b061b04 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -22,7 +22,7 @@ export interface CollectionRenderProps { removeDocument: (document: Document) => boolean; moveDocument: (document: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean; active: () => boolean; - onActiveChanged: (isActive: boolean) => void; + whenActiveChanged: (isActive: boolean) => void; } export interface CollectionViewProps extends FieldViewProps { @@ -55,9 +55,9 @@ export class CollectionBaseView extends React.Component { //TODO should this be observable? private _isChildActive = false; - onActiveChanged = (isActive: boolean) => { + whenActiveChanged = (isActive: boolean) => { this._isChildActive = isActive; - this.props.onActiveChanged(isActive); + this.props.whenActiveChanged(isActive); } createsCycle(documentToAdd: Document, containerDocument: Document): boolean { @@ -184,7 +184,7 @@ export class CollectionBaseView extends React.Component { removeDocument: this.removeDocument, moveDocument: this.moveDocument, active: this.active, - onActiveChanged: this.onActiveChanged, + whenActiveChanged: this.whenActiveChanged, }; const viewtype = this.collectionViewType; return ( diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 2b886adb6..9ec0b3aeb 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -363,7 +363,7 @@ export class DockedFrameRenderer extends React.Component { isTopMost={true} selectOnLoad={false} parentActive={returnTrue} - onActiveChanged={emptyFunction} + whenActiveChanged={emptyFunction} focus={emptyDocFunction} ContainingCollectionView={undefined} />
; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 1defdba7e..15b7617ae 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -24,7 +24,7 @@ import { EditableView } from "../EditableView"; import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; -import { CollectionSubView } from "./CollectionSubView"; +import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 @@ -70,7 +70,6 @@ export class CollectionSchemaView extends CollectionSubView { @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); } - renderCell = (rowProps: CellInfo) => { let props: FieldViewProps = { Document: rowProps.value[0], @@ -83,7 +82,7 @@ export class CollectionSchemaView extends CollectionSubView { ScreenToLocalTransform: Transform.Identity, focus: emptyDocFunction, active: returnFalse, - onActiveChanged: emptyFunction, + whenActiveChanged: emptyFunction, }; let contents = ( @@ -285,7 +284,7 @@ export class CollectionSchemaView extends CollectionSubView { this._optionsActivated++; } - @observable previewScript: string = "this"; + @observable previewScript: string = ""; @action onPreviewScriptChange = (e: React.ChangeEvent) => { this.previewScript = e.currentTarget.value; @@ -299,7 +298,7 @@ export class CollectionSchemaView extends CollectionSubView { const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; //all the keys/columns that will be displayed in the schema const allKeys = this.findAllDocumentKeys; - let doc: any = selected ? selected.Get(new Key(this.previewScript)) : undefined; + let doc: any = selected ? (this.previewScript ? selected.Get(new Key(this.previewScript)) : selected) : undefined; // let doc = CompileScript(this.previewScript, { this: selected }, true)(); let content = this._selectedIndex === -1 || !selected ? (null) : ( @@ -318,7 +317,7 @@ export class CollectionSchemaView extends CollectionSubView { ContainingCollectionView={this.props.CollectionView} focus={emptyDocFunction} parentActive={this.props.active} - onActiveChanged={this.props.onActiveChanged} /> : null} + whenActiveChanged={this.props.whenActiveChanged} /> : null} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 97708ce19..80322c900 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -248,7 +248,7 @@ export class CollectionFreeFormView extends CollectionSubView { ContainingCollectionView: this.props.CollectionView, focus: this.focusDocument, parentActive: this.props.active, - onActiveChanged: this.props.active, + whenActiveChanged: this.props.active, }; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b99e449be..d74f9fc57 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -39,7 +39,7 @@ export interface DocumentViewProps { focus: (doc: Document) => void; selectOnLoad: boolean; parentActive: () => boolean; - onActiveChanged: (isActive: boolean) => void; + whenActiveChanged: (isActive: boolean) => void; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index ebd25f937..e9f6950ff 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -43,7 +43,7 @@ export interface FieldViewProps { moveDocument?: (document: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean; ScreenToLocalTransform: () => Transform; active: () => boolean; - onActiveChanged: (isActive: boolean) => void; + whenActiveChanged: (isActive: boolean) => void; focus: (doc: Document) => void; } @@ -95,7 +95,7 @@ export class FieldView extends React.Component { layoutKey={KeyStore.Layout} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} - onActiveChanged={this.props.onActiveChanged} /> + whenActiveChanged={this.props.whenActiveChanged} /> ); } else if (field instanceof ListField) { diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 5d69f23b2..d480eb5af 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -48,7 +48,7 @@ export class KeyValuePair extends React.Component { isTopMost: false, selectOnLoad: false, active: returnFalse, - onActiveChanged: emptyFunction, + whenActiveChanged: emptyFunction, ScreenToLocalTransform: Transform.Identity, focus: emptyDocFunction, }; -- cgit v1.2.3-70-g09d2 From 8d7d4d4bee15f250eb93f4fb850075e99bebedd3 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 17 Apr 2019 14:17:29 -0400 Subject: schemaviews --- .../views/collections/CollectionSchemaView.scss | 10 ++- .../views/collections/CollectionSchemaView.tsx | 89 +++++++++++++--------- 2 files changed, 60 insertions(+), 39 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index c8bfedff4..8c51ed752 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -71,7 +71,10 @@ ul { position: absolute; height: 100%; width: 100%; - overflow: auto; + .documentView-node:first-child { + position: relative; + background: $light-color; + } } .collectionSchemaView-previewRegion { position: relative; @@ -193,6 +196,11 @@ ul { border-bottom-style: solid; border-bottom-width: 1; } + .documentView-node-topmost { + text-align:left; + transform-origin: center top; + display: inline-block; + } .documentView-node:first-child { background: $light-color; .imageBox-cont img { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 15b7617ae..9e740eb00 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -12,7 +12,7 @@ import { Field, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { emptyDocFunction, emptyFunction, returnFalse, returnOne } from "../../../Utils"; +import { emptyDocFunction, emptyFunction, returnFalse, returnOne, Utils } from "../../../Utils"; import { Server } from "../../Server"; import { SetupDrag } from "../../util/DragManager"; import { CompileScript, ToField } from "../../util/Scripting"; @@ -25,6 +25,7 @@ import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView"; +import { CollectionDockingView } from "./CollectionDockingView"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 @@ -60,7 +61,6 @@ export class CollectionSchemaView extends CollectionSubView { private DIVIDER_WIDTH = 4; @observable _columns: Array = [KeyStore.Title, KeyStore.Data, KeyStore.Author]; - @observable _contentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ContentScaling prop of the DocumentView @observable _dividerX = 0; @observable _panelWidth = 0; @observable _panelHeight = 0; @@ -234,22 +234,9 @@ export class CollectionSchemaView extends CollectionSubView { setTableDimensions = (r: any) => { this._tableWidth = r.entry.width; } - @action - setScaling = (r: any) => { - const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); - const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; - this._panelWidth = r.entry.width; - this._panelHeight = r.entry.height ? r.entry.height : this._panelHeight; - this._contentScaling = r.entry.width / selected!.GetNumber(KeyStore.NativeWidth, r.entry.width); - } @computed get borderWidth() { return COLLECTION_BORDER_WIDTH; } - getContentScaling = (): number => this._contentScaling; - getPanelWidth = (): number => this._panelWidth; - getPanelHeight = (): number => this._panelHeight; - getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX, - this.borderWidth).scale(1 / this._contentScaling); - getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX - this._tableWidth, - this.borderWidth).scale(1 / this._contentScaling); onPointerDown = (e: React.PointerEvent): void => { if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { @@ -289,37 +276,63 @@ export class CollectionSchemaView extends CollectionSubView { onPreviewScriptChange = (e: React.ChangeEvent) => { this.previewScript = e.currentTarget.value; } + private get _document(): Document | undefined { + const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); + const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; + return selected ? (this.previewScript ? selected.Get(new Key(this.previewScript)) as Document : selected) : undefined; + } + private nativeWidth = () => this._document!.GetNumber(KeyStore.NativeWidth, this._panelWidth); + private nativeHeight = () => this._document!.GetNumber(KeyStore.NativeHeight, this._panelHeight); + private panelWidth = () => this.nativeWidth() * this._contentScaling(); + private panelHeight = () => this.nativeHeight() * this._contentScaling(); + private _contentScaling = () => { + let wscale = this._panelWidth / (this.nativeWidth() ? this.nativeWidth() : this._panelWidth); + if (wscale * this.nativeHeight() > this._panelHeight) + return this._panelHeight / (this.nativeHeight() ? this.nativeHeight() : this._panelHeight); + return wscale; + } + getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX - this._tableWidth - this.offset(), - this.borderWidth).scale(1 / this._contentScaling()); + getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX, - this.borderWidth).scale(1 / this._contentScaling()); + + offset = () => ((this.props as any).PanelWidth() * this.splitPercentage / 100 - this.nativeWidth() * this._contentScaling()) / 2; + @action + setScaling = (r: any) => { + this._panelWidth = r.entry.width; + this._panelHeight = r.entry.height ? r.entry.height : this._panelHeight; + } render() { library.add(faCog); library.add(faPlus); + if (!this._document) + return (null); const columns = this.columns; - const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); - const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; - //all the keys/columns that will be displayed in the schema + let doc = this._document; + const childs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); const allKeys = this.findAllDocumentKeys; - let doc: any = selected ? (this.previewScript ? selected.Get(new Key(this.previewScript)) : selected) : undefined; - // let doc = CompileScript(this.previewScript, { this: selected }, true)(); - let content = this._selectedIndex === -1 || !selected ? (null) : ( + let offset = this.offset(); + let content = !doc ? (null) : ( {({ measureRef }) =>
- {doc instanceof Document ? - : null} - +
+ {doc instanceof Document ? + : null} + +
}
@@ -355,8 +368,8 @@ export class CollectionSchemaView extends CollectionSubView { {({ measureRef }) =>
({ -- cgit v1.2.3-70-g09d2 From 3ec6343ad5f15cfe43c233f29453f02c435aecda Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 17 Apr 2019 19:12:38 -0400 Subject: fixed schema layout --- .../views/collections/CollectionSchemaView.scss | 11 ++ .../views/collections/CollectionSchemaView.tsx | 164 ++++++++++----------- 2 files changed, 86 insertions(+), 89 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 8c51ed752..580bce21b 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -71,6 +71,17 @@ ul { position: absolute; height: 100%; width: 100%; + .collectionSchemaView-previewDoc { + height: 100%; + width: 100%; + position: absolute; + } + .collectionSchemaView-input { + position: absolute; + max-width: 150px; + width: 100%; + bottom: 0px; + } .documentView-node:first-child { position: relative; background: $light-color; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 9e740eb00..f7d69aee1 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -61,9 +61,6 @@ export class CollectionSchemaView extends CollectionSubView { private DIVIDER_WIDTH = 4; @observable _columns: Array = [KeyStore.Title, KeyStore.Data, KeyStore.Author]; - @observable _dividerX = 0; - @observable _panelWidth = 0; - @observable _panelHeight = 0; @observable _selectedIndex = 0; @observable _columnsPercentage = 0; @observable _keys: Key[] = []; @@ -229,11 +226,6 @@ export class CollectionSchemaView extends CollectionSubView { document.addEventListener('pointerup', this.onDividerUp); } - @observable _tableWidth = 0; - @action - setTableDimensions = (r: any) => { - this._tableWidth = r.entry.width; - } @computed get borderWidth() { return COLLECTION_BORDER_WIDTH; } @@ -276,72 +268,65 @@ export class CollectionSchemaView extends CollectionSubView { onPreviewScriptChange = (e: React.ChangeEvent) => { this.previewScript = e.currentTarget.value; } - private get _document(): Document | undefined { + private get previewDocument(): Document | undefined { const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; return selected ? (this.previewScript ? selected.Get(new Key(this.previewScript)) as Document : selected) : undefined; } - private nativeWidth = () => this._document!.GetNumber(KeyStore.NativeWidth, this._panelWidth); - private nativeHeight = () => this._document!.GetNumber(KeyStore.NativeHeight, this._panelHeight); - private panelWidth = () => this.nativeWidth() * this._contentScaling(); - private panelHeight = () => this.nativeHeight() * this._contentScaling(); - private _contentScaling = () => { - let wscale = this._panelWidth / (this.nativeWidth() ? this.nativeWidth() : this._panelWidth); - if (wscale * this.nativeHeight() > this._panelHeight) - return this._panelHeight / (this.nativeHeight() ? this.nativeHeight() : this._panelHeight); + getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( + - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth - this.previewPanelCenteringOffset, + - this.borderWidth).scale(1 / this.previewContentScaling()); + getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH, - this.borderWidth).scale(1 / this.previewContentScaling()); + + get tableWidth() { return (this.props as any).PanelWidth() * (1 - this.splitPercentage / 100); } + get previewRegionHeight() { return (this.props as any).PanelHeight(); } + get previewRegionWidth() { return (this.props as any).PanelWidth() * this.splitPercentage / 100 - this.DIVIDER_WIDTH; } + + get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } + private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); + private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); + private previewContentScaling = () => { + let wscale = this.previewRegionWidth / (this.previewDocNativeWidth() ? this.previewDocNativeWidth() : this.previewRegionWidth); + if (wscale * this.previewDocNativeHeight() > this.previewRegionHeight) + return this.previewRegionHeight / (this.previewDocNativeHeight() ? this.previewDocNativeHeight() : this.previewRegionHeight); return wscale; } - getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX - this._tableWidth - this.offset(), - this.borderWidth).scale(1 / this._contentScaling()); - getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH - this._dividerX, - this.borderWidth).scale(1 / this._contentScaling()); + private previewDocNativeWidth = () => this.previewDocument!.GetNumber(KeyStore.NativeWidth, this.previewRegionWidth); + private previewDocNativeHeight = () => this.previewDocument!.GetNumber(KeyStore.NativeHeight, this.previewRegionHeight); - offset = () => ((this.props as any).PanelWidth() * this.splitPercentage / 100 - this.nativeWidth() * this._contentScaling()) / 2; - @action - setScaling = (r: any) => { - this._panelWidth = r.entry.width; - this._panelHeight = r.entry.height ? r.entry.height : this._panelHeight; - } - render() { - library.add(faCog); - library.add(faPlus); - if (!this._document) - return (null); - const columns = this.columns; - let doc = this._document; - const childs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); - const allKeys = this.findAllDocumentKeys; + @computed + get previewPanel() { + let doc = this.previewDocument; // let doc = CompileScript(this.previewScript, { this: selected }, true)(); - let offset = this.offset(); - let content = !doc ? (null) : ( - - {({ measureRef }) => -
-
- {doc instanceof Document ? - : null} - -
+ let inputPanelWidth = Math.min(75, this.previewPanelWidth() / 2); + return !doc ? (null) : ( +
+
+
+ {doc instanceof Document ? + : + null}
- } - + +
+
); - let dividerDragger = this.splitPercentage === 0 ? (null) : -
; - - //options button and menu - let optionsMenu = !this.props.active() ? (null) : (
Options
@@ -360,37 +345,38 @@ export class CollectionSchemaView extends CollectionSubView { }>
); + } + @computed + get dividerDragger() { + return this.splitPercentage === 0 ? (null) : +
; + } + + render() { + library.add(faCog); + library.add(faPlus); + if (!this.previewDocument) + return (null); + + const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); return (
this.onDrop(e, {})} ref={this.createDropTarget}> - - {({ measureRef }) => -
- ({ - Header: col.Name, - accessor: (doc: Document) => [doc, col], - id: col.Id - }))} - column={{ - ...ReactTableDefaults.column, - Cell: this.renderCell, - - }} - getTrProps={this.getTrProps} - /> -
} -
- {dividerDragger} -
- {content} +
+ ({ + Header: col.Name, + accessor: (doc: Document) => [doc, col], + id: col.Id + }))} + column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }} + getTrProps={this.getTrProps} + />
- {optionsMenu} + {this.dividerDragger} + {this.previewPanel} + {this.tableOptionsPanel}
); -- cgit v1.2.3-70-g09d2 From d998bdaa38677e4888393db01cf9b73bb49f2cc9 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 17 Apr 2019 19:55:12 -0400 Subject: some schema view simplifications --- .../views/collections/CollectionSchemaView.scss | 125 ++++++++++----------- .../views/collections/CollectionSchemaView.tsx | 98 ++++++++-------- src/client/views/collections/CollectionSubView.tsx | 6 +- 3 files changed, 112 insertions(+), 117 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 580bce21b..bced0d5d4 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -1,61 +1,5 @@ @import "../globalCssVariables"; -//options menu styling -#schemaOptionsMenuBtn { - position: absolute; - height: 20px; - width: 20px; - border-radius: 50%; - z-index: 21; - right: 4px; - top: 4px; - pointer-events: auto; - background-color:black; - display:inline-block; - padding: 0px; - font-size: 100%; -} - -ul { - list-style-type: disc; -} - -#schema-options-header { - text-align: center; - padding: 0px; - margin: 0px; -} -.schema-options-subHeader { - color: $intermediate-color; - margin-bottom: 5px; -} -#schemaOptionsMenuBtn:hover { - transform: scale(1.15); -} - -#preview-schema-checkbox-div { - margin-left: 20px; - font-size: 12px; -} - - #options-flyout-div { - text-align: left; - padding:0px; - z-index: 100; - font-family: $sans-serif; - padding-left: 5px; - } - - #schema-col-checklist { - overflow: scroll; - text-align: left; - //background-color: $light-color-secondary; - line-height: 25px; - max-height: 175px; - font-family: $sans-serif; - font-size: 12px; - } - .collectionSchemaView-container { border-width: $COLLECTION_BORDER_WIDTH; @@ -67,10 +11,11 @@ ul { width: 100%; height: 100%; - .collectionSchemaView-content { - position: absolute; + .collectionSchemaView-previewRegion { + position: relative; + background: $light-color; + float: left; height: 100%; - width: 100%; .collectionSchemaView-previewDoc { height: 100%; width: 100%; @@ -87,12 +32,6 @@ ul { background: $light-color; } } - .collectionSchemaView-previewRegion { - position: relative; - background: $light-color; - float: left; - height: 100%; - } .collectionSchemaView-previewHandle { position: absolute; height: 15px; @@ -219,6 +158,62 @@ ul { } } } +//options menu styling +#schemaOptionsMenuBtn { + position: absolute; + height: 20px; + width: 20px; + border-radius: 50%; + z-index: 21; + right: 4px; + top: 4px; + pointer-events: auto; + background-color:black; + display:inline-block; + padding: 0px; + font-size: 100%; +} + +ul { + list-style-type: disc; +} + +#schema-options-header { + text-align: center; + padding: 0px; + margin: 0px; +} +.schema-options-subHeader { + color: $intermediate-color; + margin-bottom: 5px; +} +#schemaOptionsMenuBtn:hover { + transform: scale(1.15); +} + +#preview-schema-checkbox-div { + margin-left: 20px; + font-size: 12px; +} + + #options-flyout-div { + text-align: left; + padding:0px; + z-index: 100; + font-family: $sans-serif; + padding-left: 5px; + } + + #schema-col-checklist { + overflow: scroll; + text-align: left; + //background-color: $light-color-secondary; + line-height: 25px; + max-height: 175px; + font-family: $sans-serif; + font-size: 12px; + } + .Resizer { box-sizing: border-box; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index f7d69aee1..4e3149fe4 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -4,7 +4,6 @@ import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, untracked } from "mobx"; import { observer } from "mobx-react"; -import Measure from "react-measure"; import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table"; import "react-table/react-table.css"; import { Document } from "../../../fields/Document"; @@ -12,7 +11,7 @@ import { Field, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { emptyDocFunction, emptyFunction, returnFalse, returnOne, Utils } from "../../../Utils"; +import { emptyDocFunction, emptyFunction, returnFalse } from "../../../Utils"; import { Server } from "../../Server"; import { SetupDrag } from "../../util/DragManager"; import { CompileScript, ToField } from "../../util/Scripting"; @@ -24,8 +23,7 @@ import { EditableView } from "../EditableView"; import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; -import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView"; -import { CollectionDockingView } from "./CollectionDockingView"; +import { CollectionSubView } from "./CollectionSubView"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 @@ -56,7 +54,7 @@ class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggl @observer export class CollectionSchemaView extends CollectionSubView { - private _mainCont = React.createRef(); + private _mainCont?: HTMLDivElement; private _startSplitPercent = 0; private DIVIDER_WIDTH = 4; @@ -207,7 +205,7 @@ export class CollectionSchemaView extends CollectionSubView { @action onDividerMove = (e: PointerEvent): void => { - let nativeWidth = this._mainCont.current!.getBoundingClientRect(); + let nativeWidth = this._mainCont!.getBoundingClientRect(); this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, Math.max(0, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100))); } @action @@ -279,47 +277,41 @@ export class CollectionSchemaView extends CollectionSubView { - this.borderWidth).scale(1 / this.previewContentScaling()); getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH, - this.borderWidth).scale(1 / this.previewContentScaling()); - get tableWidth() { return (this.props as any).PanelWidth() * (1 - this.splitPercentage / 100); } - get previewRegionHeight() { return (this.props as any).PanelHeight(); } - get previewRegionWidth() { return (this.props as any).PanelWidth() * this.splitPercentage / 100 - this.DIVIDER_WIDTH; } + get tableWidth() { return this.props.PanelWidth() * (1 - this.splitPercentage / 100); } + get previewRegionHeight() { return this.props.PanelHeight(); } + get previewRegionWidth() { return this.props.PanelWidth() * this.splitPercentage / 100 - this.DIVIDER_WIDTH; } - get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } - private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); - private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); + private previewDocNativeWidth = () => this.previewDocument!.GetNumber(KeyStore.NativeWidth, this.previewRegionWidth); + private previewDocNativeHeight = () => this.previewDocument!.GetNumber(KeyStore.NativeHeight, this.previewRegionHeight); private previewContentScaling = () => { let wscale = this.previewRegionWidth / (this.previewDocNativeWidth() ? this.previewDocNativeWidth() : this.previewRegionWidth); if (wscale * this.previewDocNativeHeight() > this.previewRegionHeight) return this.previewRegionHeight / (this.previewDocNativeHeight() ? this.previewDocNativeHeight() : this.previewRegionHeight); return wscale; } - private previewDocNativeWidth = () => this.previewDocument!.GetNumber(KeyStore.NativeWidth, this.previewRegionWidth); - private previewDocNativeHeight = () => this.previewDocument!.GetNumber(KeyStore.NativeHeight, this.previewRegionHeight); + private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); + private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); + get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } @computed get previewPanel() { - let doc = this.previewDocument; // let doc = CompileScript(this.previewScript, { this: selected }, true)(); - let inputPanelWidth = Math.min(75, this.previewPanelWidth() / 2); - return !doc ? (null) : ( + return !this.previewDocument ? (null) : (
-
-
- {doc instanceof Document ? - : - null} -
- +
+
+
); } @@ -353,6 +345,11 @@ export class CollectionSchemaView extends CollectionSubView {
; } + createTarget = (ele: HTMLDivElement) => { + this._mainCont = ele; + super.CreateDropTarget(ele); + } + render() { library.add(faCog); library.add(faPlus); @@ -361,24 +358,23 @@ export class CollectionSchemaView extends CollectionSubView { const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); return ( -
-
this.onDrop(e, {})} ref={this.createDropTarget}> -
- ({ - Header: col.Name, - accessor: (doc: Document) => [doc, col], - id: col.Id - }))} - column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }} - getTrProps={this.getTrProps} - /> -
- {this.dividerDragger} - {this.previewPanel} - {this.tableOptionsPanel} +
this.onDrop(e, {})} ref={this.createTarget}> +
+ ({ + Header: col.Name, + accessor: (doc: Document) => [doc, col], + id: col.Id + }))} + column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }} + getTrProps={this.getTrProps} + />
-
+ {this.dividerDragger} + {this.previewPanel} + {this.tableOptionsPanel} +
); } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index d3d69b1af..5c3b2e586 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -15,7 +15,6 @@ import { ServerUtils } from "../../../server/ServerUtil"; import { Server } from "../../Server"; import { FieldViewProps } from "../nodes/FieldView"; import * as rp from 'request-promise'; -import { emptyFunction } from "../../../Utils"; import { CollectionView } from "./CollectionView"; import { CollectionPDFView } from "./CollectionPDFView"; import { CollectionVideoView } from "./CollectionVideoView"; @@ -24,6 +23,8 @@ export interface CollectionViewProps extends FieldViewProps { addDocument: (document: Document, allowDuplicates?: boolean) => boolean; removeDocument: (document: Document) => boolean; moveDocument: (document: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean; + PanelWidth: () => number; + PanelHeight: () => number; } export interface SubCollectionViewProps extends CollectionViewProps { @@ -42,6 +43,9 @@ export class CollectionSubView extends React.Component { this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } }); } } + protected CreateDropTarget(ele: HTMLDivElement) { + this.createDropTarget(ele); + } @action protected setCursorPosition(position: [number, number]) { -- cgit v1.2.3-70-g09d2 From 6c56cbad38efbde578e2c2c90cbce4b7ff033059 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 17 Apr 2019 21:02:12 -0400 Subject: final cleanup of schema views --- .../views/collections/CollectionSchemaView.tsx | 144 +++++++++------------ 1 file changed, 59 insertions(+), 85 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 4e3149fe4..08c9740d0 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -33,22 +33,17 @@ import { CollectionSubView } from "./CollectionSubView"; class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggle: (key: Key) => void }> { @observable key: Key | undefined; - componentWillReceiveProps() { - Server.GetField(this.props.keyId, action((field: Opt) => { - if (field instanceof Key) { - this.key = field; - } - })); + constructor(props: any) { + super(props); + Server.GetField(this.props.keyId, action((field: Opt) => field instanceof Key && (this.key = field))); } render() { - if (this.key) { - return (
+ return !this.key ? (null) : + (
this.key && this.props.toggle(this.key)} /> {this.key.Name}
); - } - return (null); } } @@ -62,8 +57,11 @@ export class CollectionSchemaView extends CollectionSubView { @observable _selectedIndex = 0; @observable _columnsPercentage = 0; @observable _keys: Key[] = []; + @observable _newKeyName: string = ""; @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); } + @computed get columns() { return this.props.Document.GetList(KeyStore.ColumnsKey, [] as Key[]); } + @computed get borderWidth() { return COLLECTION_BORDER_WIDTH; } renderCell = (rowProps: CellInfo) => { let props: FieldViewProps = { @@ -159,9 +157,9 @@ export class CollectionSchemaView extends CollectionSubView { }; } - @computed - get columns() { - return this.props.Document.GetList(KeyStore.ColumnsKey, [] as Key[]); + private createTarget = (ele: HTMLDivElement) => { + this._mainCont = ele; + super.CreateDropTarget(ele); } @action @@ -181,26 +179,7 @@ export class CollectionSchemaView extends CollectionSubView { //toggles preview side-panel of schema @action toggleExpander = (event: React.ChangeEvent) => { - this._startSplitPercent = this.splitPercentage; - if (this._startSplitPercent === this.splitPercentage) { - this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage === 0 ? 33 : 0); - } - } - - @computed - get findAllDocumentKeys(): { [id: string]: boolean } { - const docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); - let keys: { [id: string]: boolean } = {}; - if (this._optionsActivated > -1) { - // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. - // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be - // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked. - // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu - // is displayed (unlikely) it won't show up until something else changes. - untracked(() => docs.map(doc => doc.GetAllPrototypes().map(proto => proto._proxies.forEach((val: any, key: string) => keys[key] = false)))); - } - this.columns.forEach(key => keys[key.Id] = true); - return keys; + this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage === 0 ? 33 : 0); } @action @@ -224,10 +203,6 @@ export class CollectionSchemaView extends CollectionSubView { document.addEventListener('pointerup', this.onDividerUp); } - - @computed - get borderWidth() { return COLLECTION_BORDER_WIDTH; } - onPointerDown = (e: React.PointerEvent): void => { if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { if (this.props.isSelected()) @@ -236,29 +211,21 @@ export class CollectionSchemaView extends CollectionSubView { } } - @action - addColumn = () => { - this.columns.push(new Key(this.newKeyName)); - this.newKeyName = ""; - } - - @observable - newKeyName: string = ""; - - @action - newKeyChange = (e: React.ChangeEvent) => { - this.newKeyName = e.currentTarget.value; - } onWheel = (e: React.WheelEvent): void => { if (this.props.active()) { e.stopPropagation(); } } - @observable _optionsActivated: number = 0; @action - OptionsMenuDown = (e: React.PointerEvent) => { - this._optionsActivated++; + addColumn = () => { + this.columns.push(new Key(this._newKeyName)); + this._newKeyName = ""; + } + + @action + newKeyChange = (e: React.ChangeEvent) => { + this._newKeyName = e.currentTarget.value; } @observable previewScript: string = ""; @@ -266,17 +233,12 @@ export class CollectionSchemaView extends CollectionSubView { onPreviewScriptChange = (e: React.ChangeEvent) => { this.previewScript = e.currentTarget.value; } - private get previewDocument(): Document | undefined { + + get previewDocument(): Document | undefined { const children = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; return selected ? (this.previewScript ? selected.Get(new Key(this.previewScript)) as Document : selected) : undefined; } - - getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( - - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth - this.previewPanelCenteringOffset, - - this.borderWidth).scale(1 / this.previewContentScaling()); - getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(- this.borderWidth - this.DIVIDER_WIDTH, - this.borderWidth).scale(1 / this.previewContentScaling()); - get tableWidth() { return this.props.PanelWidth() * (1 - this.splitPercentage / 100); } get previewRegionHeight() { return this.props.PanelHeight(); } get previewRegionWidth() { return this.props.PanelWidth() * this.splitPercentage / 100 - this.DIVIDER_WIDTH; } @@ -292,6 +254,9 @@ export class CollectionSchemaView extends CollectionSubView { private previewPanelWidth = () => this.previewDocNativeWidth() * this.previewContentScaling(); private previewPanelHeight = () => this.previewDocNativeHeight() * this.previewContentScaling(); get previewPanelCenteringOffset() { return (this.previewRegionWidth - this.previewDocNativeWidth() * this.previewContentScaling()) / 2; } + getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( + - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth - this.previewPanelCenteringOffset, + - this.borderWidth).scale(1 / this.previewContentScaling()); @computed get previewPanel() { @@ -315,28 +280,42 @@ export class CollectionSchemaView extends CollectionSubView {
); } - @computed + + get documentKeysCheckList() { + const docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); + let keys: { [id: string]: boolean } = {}; + // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. + // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be + // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked. + // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu + // is displayed (unlikely) it won't show up until something else changes. + untracked(() => docs.map(doc => doc.GetAllPrototypes().map(proto => proto._proxies.forEach((val: any, key: string) => keys[key] = false)))); + + this.columns.forEach(key => keys[key.Id] = true); + return Array.from(Object.keys(keys)).map(item => + ()); + } + get tableOptionsPanel() { - const allKeys = this.findAllDocumentKeys; - return !this.props.active() ? (null) : ( -
Options
-
-
Preview Window
-
Show Preview
-
Displayed Columns
-
    - {Array.from(Object.keys(allKeys)).map(item => - ())} -
- - + return !this.props.active() ? (null) : + ( +
Options
+
+
Preview Window
+
Show Preview
+
Displayed Columns
+
    + {this.documentKeysCheckList} +
+ + +
-
- }> - - ); + }> + + ); } @computed @@ -345,11 +324,6 @@ export class CollectionSchemaView extends CollectionSubView {
; } - createTarget = (ele: HTMLDivElement) => { - this._mainCont = ele; - super.CreateDropTarget(ele); - } - render() { library.add(faCog); library.add(faPlus); -- cgit v1.2.3-70-g09d2 From 23f4ce6107d64e4be8b05f528fc210ad6e85d174 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 18 Apr 2019 10:03:02 -0400 Subject: more minor schema view fixes. --- src/client/views/collections/CollectionSchemaView.scss | 3 --- src/client/views/collections/CollectionSchemaView.tsx | 13 +++++-------- src/client/views/globalCssVariables.scss.d.ts | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index bced0d5d4..6eabbe17c 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -153,9 +153,6 @@ } .documentView-node:first-child { background: $light-color; - .imageBox-cont img { - object-fit: contain; - } } } //options menu styling diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 08c9740d0..b61eb342d 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -239,9 +239,9 @@ export class CollectionSchemaView extends CollectionSubView { const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined; return selected ? (this.previewScript ? selected.Get(new Key(this.previewScript)) as Document : selected) : undefined; } - get tableWidth() { return this.props.PanelWidth() * (1 - this.splitPercentage / 100); } - get previewRegionHeight() { return this.props.PanelHeight(); } - get previewRegionWidth() { return this.props.PanelWidth() * this.splitPercentage / 100 - this.DIVIDER_WIDTH; } + get tableWidth() { return (this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH) * (1 - this.splitPercentage / 100); } + get previewRegionHeight() { return this.props.PanelHeight() - 2 * this.borderWidth; } + get previewRegionWidth() { return (this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH) * this.splitPercentage / 100; } private previewDocNativeWidth = () => this.previewDocument!.GetNumber(KeyStore.NativeWidth, this.previewRegionWidth); private previewDocNativeHeight = () => this.previewDocument!.GetNumber(KeyStore.NativeHeight, this.previewRegionHeight); @@ -262,7 +262,7 @@ export class CollectionSchemaView extends CollectionSubView { get previewPanel() { // let doc = CompileScript(this.previewScript, { this: selected }, true)(); return !this.previewDocument ? (null) : ( -
+
this.onDrop(e, {})} ref={this.createTarget}> -
+
({ Header: col.Name, diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/globalCssVariables.scss.d.ts index e874b815d..ed8573f41 100644 --- a/src/client/views/globalCssVariables.scss.d.ts +++ b/src/client/views/globalCssVariables.scss.d.ts @@ -1,7 +1,7 @@ interface IGlobalScss { contextMenuZindex: string; // context menu shows up over everything - COLLECTION_BORDER_WIDTH: number; + COLLECTION_BORDER_WIDTH: string; } declare const globalCssVariables: IGlobalScss; -- cgit v1.2.3-70-g09d2 From af6feb64510490da8d815f41ceb639d693b9eae3 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 19 Apr 2019 16:34:32 -0400 Subject: played with iconifying things in a different way. fixed some things with schemas. --- src/Utils.ts | 2 +- src/client/documents/Documents.ts | 16 ++++ src/client/northstar/dash-nodes/HistogramBox.scss | 6 +- src/client/northstar/dash-nodes/HistogramBox.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 42 ++++++---- src/client/views/Main.tsx | 8 +- .../views/collections/CollectionSchemaView.scss | 9 ++- .../views/collections/CollectionSchemaView.tsx | 5 +- .../CollectionFreeFormLinkView.tsx | 8 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 13 ++-- .../collections/collectionFreeForm/MarqueeView.tsx | 9 +-- src/client/views/globalCssVariables.scss | 2 + src/client/views/globalCssVariables.scss.d.ts | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 26 +++---- src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/DocumentView.scss | 16 +--- src/client/views/nodes/DocumentView.tsx | 71 ++++++++--------- src/client/views/nodes/FieldView.tsx | 5 ++ src/client/views/nodes/IconBox.scss | 12 +++ src/client/views/nodes/IconBox.tsx | 90 ++++++++++++++++++++++ src/fields/IconFIeld.ts | 25 ++++++ src/fields/KeyStore.ts | 10 +-- src/server/Message.ts | 2 +- src/server/ServerUtil.ts | 2 + 24 files changed, 264 insertions(+), 121 deletions(-) create mode 100644 src/client/views/nodes/IconBox.scss create mode 100644 src/client/views/nodes/IconBox.tsx create mode 100644 src/fields/IconFIeld.ts (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index dec6245ef..98f75d3b9 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1,7 +1,7 @@ import v4 = require('uuid/v4'); import v5 = require("uuid/v5"); import { Socket } from 'socket.io'; -import { Message, Types, Transferable } from './server/Message'; +import { Message } from './server/Message'; import { Document } from './fields/Document'; export class Utils { diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4febfa7eb..b0bb74d89 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -32,6 +32,9 @@ import { action } from "mobx"; import { ColumnAttributeModel } from "../northstar/core/attribute/AttributeModel"; import { AttributeTransformationModel } from "../northstar/core/attribute/AttributeTransformationModel"; import { AggregateFunction } from "../northstar/model/idea/idea"; +import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; +import { IconBox } from "../views/nodes/IconBox"; +import { IconField } from "../../fields/IconFIeld"; export interface DocumentOptions { x?: number; @@ -63,6 +66,7 @@ export namespace Documents { let videoProto: Document; let audioProto: Document; let pdfProto: Document; + let iconProto: Document; const textProtoId = "textProto"; const histoProtoId = "histoProto"; const pdfProtoId = "pdfProto"; @@ -72,6 +76,7 @@ export namespace Documents { const kvpProtoId = "kvpProto"; const videoProtoId = "videoProto"; const audioProtoId = "audioProto"; + const iconProtoId = "iconProto"; export function initProtos(): Promise { return Server.GetFields([textProtoId, histoProtoId, collProtoId, pdfProtoId, imageProtoId, videoProtoId, audioProtoId, webProtoId, kvpProtoId]).then(fields => { @@ -84,6 +89,7 @@ export namespace Documents { videoProto = fields[videoProtoId] as Document || CreateVideoPrototype(); audioProto = fields[audioProtoId] as Document || CreateAudioPrototype(); pdfProto = fields[pdfProtoId] as Document || CreatePdfPrototype(); + iconProto = fields[iconProtoId] as Document || CreateIconPrototype(); }); } function assignOptions(doc: Document, options: DocumentOptions): Document { @@ -92,6 +98,8 @@ export namespace Documents { if (options.title !== undefined) { doc.SetText(KeyStore.Title, options.title); } if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); } if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); } + if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); } + if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); } if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); } if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); } if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); } @@ -139,6 +147,11 @@ export namespace Documents { histoProto.SetText(KeyStore.BackgroundLayout, HistogramBox.LayoutString()); return histoProto; } + function CreateIconPrototype(): Document { + let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(), + { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data] }); + return iconProto; + } function CreateTextPrototype(): Document { let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); @@ -203,6 +216,9 @@ export namespace Documents { export function TextDocument(options: DocumentOptions = {}) { return assignToDelegate(SetInstanceOptions(textProto, options, ["", TextField]).MakeDelegate(), options); } + export function IconDocument(icon: string, options: DocumentOptions = {}) { + return assignToDelegate(SetInstanceOptions(iconProto, { width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data], layout: IconBox.LayoutString(), ...options }, [icon, IconField]), options); + } export function PdfDocument(url: string, options: DocumentOptions = {}) { return assignToDelegate(SetInstanceOptions(pdfProto, options, [new URL(url), PDFField]).MakeDelegate(), options); } diff --git a/src/client/northstar/dash-nodes/HistogramBox.scss b/src/client/northstar/dash-nodes/HistogramBox.scss index e899cf15e..06d781263 100644 --- a/src/client/northstar/dash-nodes/HistogramBox.scss +++ b/src/client/northstar/dash-nodes/HistogramBox.scss @@ -1,12 +1,12 @@ .histogrambox-container { padding: 0vw; position: absolute; - top: 0; - left:0; + top: -50%; + left:-50%; text-align: center; width: 100%; height: 100%; - background: black; + background: black; } .histogrambox-xaxislabel { position:absolute; diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx index 0e84ace50..e2ecc8c83 100644 --- a/src/client/northstar/dash-nodes/HistogramBox.tsx +++ b/src/client/northstar/dash-nodes/HistogramBox.tsx @@ -146,7 +146,7 @@ export class HistogramBox extends React.Component { return ( runInAction(() => { this.PanelWidth = r.entry.width; this.PanelHeight = r.entry.height; })}> {({ measureRef }) => -
+
{labelY} diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index cfb9befd5..da2c7a3be 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -5,17 +5,18 @@ import { KeyStore } from "../../fields/KeyStore"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { TextField } from "../../fields/TextField"; +import { Document } from "../../fields/Document"; import { emptyFunction } from "../../Utils"; import { DragLinksAsDocuments, DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; import './DocumentDecorations.scss'; import { MainOverlayTextBox } from "./MainOverlayTextBox"; -import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; import { DocumentView } from "./nodes/DocumentView"; import { LinkMenu } from "./nodes/LinkMenu"; import React = require("react"); import { CompileScript } from "../util/Scripting"; +import { IconBox } from "./nodes/IconBox"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -191,6 +192,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.addEventListener("pointerup", this.onMinimizeUp); } } + + @observable _minimizedX = 0; + @observable _minimizedY = 0; @action onMinimizeMove = (e: PointerEvent): void => { e.stopPropagation(); @@ -201,12 +205,20 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let xf = SelectionManager.SelectedDocuments()[0].props.ScreenToLocalTransform().inverse().transformPoint(0, 0); let dx = e.pageX - xf[0]; let dy = e.pageY - xf[1]; - if (Math.abs(dx) < 20 && Math.abs(dy) < 20) - dx = dy = 0; + this._minimizedX = e.clientX; + this._minimizedY = e.clientY; + if (Math.abs(dx) < 20 && Math.abs(dy) < 20) { + this._minimizedX = xf[0]; + this._minimizedY = xf[1]; + } SelectionManager.SelectedDocuments().map(dv => { - let where = (dv.props.ScreenToLocalTransform()).scale(dv.props.ContentScaling()).transformDirection(dx, dy); - dv.props.Document.SetNumber(KeyStore.MinimizedX, where[0]); - dv.props.Document.SetNumber(KeyStore.MinimizedY, where[1]); + let minDoc = dv.props.Document.Get(KeyStore.MinimizedDoc); + if (minDoc instanceof Document) { + let where = (dv.props.ScreenToLocalTransform()).scale(dv.props.ContentScaling()).transformPoint(this._minimizedX, this._minimizedY); + let minDocument = minDoc as Document; + minDocument.SetNumber(KeyStore.X, where[0] + dv.props.Document.GetNumber(KeyStore.X, 0)); + minDocument.SetNumber(KeyStore.Y, where[1] + dv.props.Document.GetNumber(KeyStore.Y, 0)); + } }); } } @@ -219,6 +231,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (Math.abs(dx) < 4 && Math.abs(dy) < 4 && !this._iconifying) { SelectionManager.SelectedDocuments().map(dv => dv.minimize()); SelectionManager.DeselectAll(); + } else { + this._minimizedX = this._minimizedY = 0; } document.removeEventListener("pointermove", this.onMinimizeMove); document.removeEventListener("pointerup", this.onMinimizeUp); @@ -404,24 +418,18 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (bounds.x === Number.MAX_VALUE || !seldoc) { return (null); } - let minvec = [seldoc.props.Document.GetNumber(KeyStore.MinimizedX, 0), seldoc.props.Document.GetNumber(KeyStore.MinimizedY, 0)]; - minvec = seldoc.props.ScreenToLocalTransform().scale(seldoc.props.ContentScaling()).inverse().transformDirection(minvec[0], minvec[1]); - let selpos = minvec[0] !== 0 || minvec[1] !== 0 ? - [minvec[0] - 12 + (!this._iconifying ? 8 : 0), minvec[1] - 12 + (!this._iconifying ? 28 : 0)] : + let selpos = this._minimizedX !== 0 || this._minimizedY !== 0 ? + [this._minimizedX - 12 + (!this._iconifying ? 8 : 0), this._minimizedY - 12 + (!this._iconifying ? 28 : 0)] : [0, this._iconifying ? -18 : 0]; let minimizeIcon = (
- {SelectionManager.SelectedDocuments().length == 1 ? SelectionManager.SelectedDocuments()[0].minimizedIcon : "..."} + {SelectionManager.SelectedDocuments().length == 1 ? IconBox.DocumentIcon(SelectionManager.SelectedDocuments()[0].props.Document.GetText(KeyStore.Layout, "...")) : "..."}
); if (this._iconifying) { - let xfpt = seldoc.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - return (
- {minimizeIcon} -
); + return (
{minimizeIcon}
); } - // console.log(this._documents.length) - // let test = this._documents[0].props.Document.Title; + if (this.Hidden) { return (null); } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 503a11b35..09ef30f6b 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -85,11 +85,11 @@ export class Main extends React.Component { this.initEventListeners(); this.initAuthenticationRouters(); - // try { - // this.initializeNorthstar(); - // } catch (e) { + try { + this.initializeNorthstar(); + } catch (e) { - // } + } } componentDidMount() { window.onpopstate = this.onHistory; } diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 6eabbe17c..cfdb3ab22 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -1,6 +1,7 @@ @import "../globalCssVariables"; + .collectionSchemaView-container { border-width: $COLLECTION_BORDER_WIDTH; border-color : $intermediate-color; @@ -10,6 +11,10 @@ position: absolute; width: 100%; height: 100%; + + .collectionSchemaView-cellContents { + height: $MAX_ROW_HEIGHT; + } .collectionSchemaView-previewRegion { position: relative; @@ -104,7 +109,7 @@ } .rt-tr-group { direction: ltr; - max-height: 44px; + max-height: $MAX_ROW_HEIGHT; } .rt-td { border-width: 1px; @@ -136,7 +141,7 @@ } .ReactTable .rt-th, .ReactTable .rt-td { - max-height: 44; + max-height: $MAX_ROW_HEIGHT; padding: 3px 7px; font-size: 13px; text-align: center; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index b61eb342d..90077b053 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -5,6 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, untracked } from "mobx"; import { observer } from "mobx-react"; import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table"; +import { MAX_ROW_HEIGHT } from '../../views/globalCssVariables.scss' import "react-table/react-table.css"; import { Document } from "../../../fields/Document"; import { Field, Opt } from "../../../fields/Field"; @@ -99,11 +100,11 @@ export class CollectionSchemaView extends CollectionSubView { return false; }; return ( -
+
{ let field = props.Document.Get(props.fieldKey); if (field && field instanceof Field) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 8868f7df0..20c5a84bf 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -23,10 +23,10 @@ export class CollectionFreeFormLinkView extends React.Component { if (super.drop(e, de) && de.data instanceof DragManager.DocumentDragData) { - console.log("DROP Aat " + de.x + " off " + de.data.xOffset); const [x, y] = this.getTransform().transformPoint(de.x - de.data.xOffset, de.y - de.data.yOffset); if (de.data.droppedDocuments.length) { let dragDoc = de.data.droppedDocuments[0]; let dropX = dragDoc.GetNumber(KeyStore.X, 0); let dropY = dragDoc.GetNumber(KeyStore.Y, 0); de.data.droppedDocuments.map(d => { - let minimized = d.GetBoolean(KeyStore.Minimized, false); - d.SetNumber(KeyStore.X, x + (d.GetNumber(KeyStore.X, 0) - (minimized ? d.GetNumber(KeyStore.MinimizedX, 0) : 0)) - dropX); - d.SetNumber(KeyStore.Y, y + (d.GetNumber(KeyStore.Y, 0) - (minimized ? d.GetNumber(KeyStore.MinimizedY, 0) : 0)) - dropY); - if (!minimized) { + d.SetNumber(KeyStore.X, x + (d.GetNumber(KeyStore.X, 0)) - dropX); + d.SetNumber(KeyStore.Y, y + (d.GetNumber(KeyStore.Y, 0)) - dropY); + if (!d.GetBoolean(KeyStore.IsMinimized, false)) { if (!d.GetNumber(KeyStore.Width, 0)) { d.SetNumber(KeyStore.Width, 300); } @@ -264,7 +263,9 @@ export class CollectionFreeFormView extends CollectionSubView { let docviews = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => { var page = doc.GetNumber(KeyStore.Page, -1); if (page === curPage || page === -1) { - prev.push(); + let minim = doc.GetT(KeyStore.IsMinimized, BooleanField); + if (minim === undefined || (minim && !minim.Data)) + prev.push(); } return prev; }, [] as JSX.Element[]); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 8b94374fa..bf918beba 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -208,12 +208,11 @@ export class MarqueeView extends React.Component let selRect = this.Bounds; let selection: Document[] = []; this.props.activeDocuments().map(doc => { - let minimized = doc.GetBoolean(KeyStore.Minimized, false); var z = doc.GetNumber(KeyStore.Zoom, 1); - var x = doc.GetNumber(KeyStore.X, 0) + (minimized ? doc.GetNumber(KeyStore.MinimizedX, 0) : 0); - var y = doc.GetNumber(KeyStore.Y, 0) + (minimized ? doc.GetNumber(KeyStore.MinimizedY, 0) : 0); - var w = minimized ? MINIMIZED_ICON_SIZE : doc.Width() / z; - var h = minimized ? MINIMIZED_ICON_SIZE : doc.Height() / z; + var x = doc.GetNumber(KeyStore.X, 0); + var y = doc.GetNumber(KeyStore.Y, 0); + var w = doc.Width() / z; + var h = doc.Height() / z; if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) { selection.push(doc); } diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index f154f8158..4f68b71b0 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -24,8 +24,10 @@ $docDecorations-zindex: 998; // then doc decorations appear over everything else $remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right? $COLLECTION_BORDER_WIDTH: 1; $MINIMIZED_ICON_SIZE:25; +$MAX_ROW_HEIGHT: 44px; :export { contextMenuZindex: $contextMenu-zindex; COLLECTION_BORDER_WIDTH: $COLLECTION_BORDER_WIDTH; MINIMIZED_ICON_SIZE: $MINIMIZED_ICON_SIZE; + MAX_ROW_HEIGHT: $MAX_ROW_HEIGHT; } \ No newline at end of file diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/globalCssVariables.scss.d.ts index cc77d987a..9788d31f7 100644 --- a/src/client/views/globalCssVariables.scss.d.ts +++ b/src/client/views/globalCssVariables.scss.d.ts @@ -3,6 +3,7 @@ interface IGlobalScss { contextMenuZindex: string; // context menu shows up over everything COLLECTION_BORDER_WIDTH: string; MINIMIZED_ICON_SIZE: string; + MAX_ROW_HEIGHT: string; } declare const globalCssVariables: IGlobalScss; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a3689414d..1d42b3899 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -46,10 +46,10 @@ export class CollectionFreeFormDocumentView extends React.Component this.props.ScreenToLocalTransform() @@ -57,8 +57,8 @@ export class CollectionFreeFormDocumentView extends React.Component this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; - panelWidth = () => this.isMinimized ? 10 : this.props.PanelWidth(); - panelHeight = () => this.isMinimized ? 10 : this.props.PanelHeight(); + panelWidth = () => this.props.PanelWidth(); + panelHeight = () => this.props.PanelHeight(); @computed get docView() { @@ -70,19 +70,17 @@ export class CollectionFreeFormDocumentView extends React.Component; } - get isMinimized() { return this.props.Document.GetBoolean(KeyStore.Minimized, false); } - render() { let zoomFade = 1; //var zoom = doc.GetNumber(KeyStore.Zoom, 1); - let transform = this.getTransform().scale(this.contentScaling()).inverse(); - var [sptX, sptY] = transform.transformPoint(0, 0); - let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); - let w = bptX - sptX; - //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; - let fadeUp = .75 * 1800; - let fadeDown = .075 * 1800; - zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; + // let transform = this.getTransform().scale(this.contentScaling()).inverse(); + // var [sptX, sptY] = transform.transformPoint(0, 0); + // let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); + // let w = bptX - sptX; + // //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; + // let fadeUp = .75 * 1800; + // let fadeDown = .075 * 1800; + // zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; return (
Error loading layout keys

; } return ; @@ -189,10 +179,10 @@ export class DocumentView extends React.Component { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); e.stopPropagation(); - if (!SelectionManager.IsSelected(this) && e.button !== 2 && - Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - SelectionManager.SelectDoc(this, e.ctrlKey); - } + if (!SelectionManager.IsSelected(this) && e.button !== 2) + if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { + SelectionManager.SelectDoc(this, e.ctrlKey); + } } stopPropagation = (e: React.SyntheticEvent) => { e.stopPropagation(); @@ -221,13 +211,33 @@ export class DocumentView extends React.Component { ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); } + @action createIcon = (layoutString: string): void => { + let iconDoc = Documents.IconDocument(layoutString); + iconDoc.SetBoolean(KeyStore.IsMinimized, false); + iconDoc.SetNumber(KeyStore.NativeWidth, 0); + iconDoc.SetNumber(KeyStore.NativeHeight, 0); + iconDoc.Set(KeyStore.Prototype, this.props.Document); + iconDoc.Set(KeyStore.MaximizedDoc, this.props.Document); + this.props.Document.Set(KeyStore.MinimizedDoc, iconDoc); + this.props.addDocument && this.props.addDocument(iconDoc, false); + } + @action - public minimize = (where: number[]): void => { - this.props.Document.SetBoolean(KeyStore.Minimized, true); - if (where[0] !== 0 || where[1] !== 0) - this.props.Document.SetNumber(KeyStore.MinimizedX, where[0]); - if (where[1] !== 0 || where[0] !== 0) - this.props.Document.SetNumber(KeyStore.MinimizedY, where[1]); + public minimize = (): void => { + this.props.Document.SetBoolean(KeyStore.IsMinimized, true); + this.props.Document.GetAsync(KeyStore.MinimizedDoc, mindoc => { + if (mindoc === undefined) { + this.props.Document.GetAsync(KeyStore.BackgroundLayout, field => { + if (field instanceof TextField) this.createIcon(field.Data); + else this.props.Document.GetAsync(KeyStore.Layout, field => { + if (field instanceof TextField) this.createIcon(field.Data); + }); + }); + } + else if (mindoc instanceof Document) { + this.props.addDocument && this.props.addDocument(mindoc, false); + } + }); } @undoBatch @@ -295,7 +305,6 @@ export class DocumentView extends React.Component { } e.preventDefault(); - !this.isMinimized() && ContextMenu.Instance.addItem({ description: "Minimize", event: () => this.minimize([0, 0]) }); ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }); ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked }); ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) }); @@ -309,9 +318,6 @@ export class DocumentView extends React.Component { SelectionManager.SelectDoc(this, false); } - @action - expand = (e: React.MouseEvent) => { this.props.Document.SetBoolean(KeyStore.Minimized, false); SelectionManager.SelectDoc(this, e.ctrlKey); } - isMinimized = () => this.props.Document.GetBoolean(KeyStore.Minimized, false); isSelected = () => SelectionManager.IsSelected(this); select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed); @@ -319,27 +325,12 @@ export class DocumentView extends React.Component { @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } @computed get contents() { return (); } - @computed get minimizedIcon() { - let button = this.layout.indexOf("PDFBox") !== -1 ? faFilePdf : - this.layout.indexOf("ImageBox") !== -1 ? faImage : - this.layout.indexOf("Formatted") !== -1 ? faStickyNote : - this.layout.indexOf("Video") !== -1 ? faFilm : - this.layout.indexOf("Collection") !== -1 ? faObjectGroup : - faCaretUp; - return - } render() { var scaling = this.props.ContentScaling(); var nativeHeight = this.nativeHeight > 0 ? this.nativeHeight.toString() + "px" : "100%"; var nativeWidth = this.nativeWidth > 0 ? this.nativeWidth.toString() + "px" : "100%"; - if (this.isMinimized()) { - return ( -
- {this.minimizedIcon} -
); - } return (
{ else if (field instanceof ImageField) { return ; } + else if (field instanceof IconField) { + return ; + } else if (field instanceof VideoField) { return ; } diff --git a/src/client/views/nodes/IconBox.scss b/src/client/views/nodes/IconBox.scss new file mode 100644 index 000000000..ce0ee2e09 --- /dev/null +++ b/src/client/views/nodes/IconBox.scss @@ -0,0 +1,12 @@ + +@import "../globalCssVariables"; +.iconBox-container { + position: absolute; + left:0; + top:0; + svg { + width: 100% !important; + height: 100%; + background: white; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx new file mode 100644 index 000000000..5ada2186d --- /dev/null +++ b/src/client/views/nodes/IconBox.tsx @@ -0,0 +1,90 @@ +import React = require("react"); +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed } from "mobx"; +import { observer } from "mobx-react"; +import { Document } from '../../../fields/Document'; +import { IconField } from "../../../fields/IconFIeld"; +import { KeyStore } from "../../../fields/KeyStore"; +import { SelectionManager } from "../../util/SelectionManager"; +import { FieldView, FieldViewProps } from './FieldView'; +import "./IconBox.scss"; + + +library.add(faCaretUp); +library.add(faObjectGroup); +library.add(faStickyNote); +library.add(faFilePdf); +library.add(faFilm); + +@observer +export class IconBox extends React.Component { + public static LayoutString() { return FieldView.LayoutString(IconBox); } + + @computed get maximized() { return this.props.Document.GetT(KeyStore.MaximizedDoc, Document); } + @computed get layout(): string { return this.props.Document.GetData(this.props.fieldKey, IconField, "

Error loading layout data

" as string); } + @computed get minimizedIcon() { return IconBox.DocumentIcon(this.layout); } + + public static DocumentIcon(layout: string) { + let button = layout.indexOf("PDFBox") !== -1 ? faFilePdf : + layout.indexOf("ImageBox") !== -1 ? faImage : + layout.indexOf("Formatted") !== -1 ? faStickyNote : + layout.indexOf("Video") !== -1 ? faFilm : + layout.indexOf("Collection") !== -1 ? faObjectGroup : + faCaretUp; + return + } + + animateTransition(icon: number[], targ: number[], width: number, height: number, stime: number, target: Document, maximizing: boolean) { + setTimeout(() => { + let now = Date.now(); + let progress = Math.min(1, (now - stime) / 200); + let pval = maximizing ? + [icon[0] + (targ[0] - icon[0]) * progress, icon[1] + (targ[1] - icon[1]) * progress] : + [targ[0] + (icon[0] - targ[0]) * progress, targ[1] + (icon[1] - targ[1]) * progress]; + target.SetNumber(KeyStore.Width, maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress); + target.SetNumber(KeyStore.Height, maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress); + target.SetNumber(KeyStore.X, pval[0]); + target.SetNumber(KeyStore.Y, pval[1]); + if (now < stime + 200) { + this.animateTransition(icon, targ, width, height, stime, target, maximizing); + } + else { + if (!maximizing) { + target.SetBoolean(KeyStore.IsMinimized, true); + target.SetNumber(KeyStore.X, targ[0]); + target.SetNumber(KeyStore.Y, targ[1]); + target.SetNumber(KeyStore.Width, width); + target.SetNumber(KeyStore.Height, height); + } + this._completed = true; + } + }, + 2); + } + + _completed = true; + + @action + public toggleMinimize = (): void => { + SelectionManager.DeselectAll(); + if (this.maximized instanceof Document && this._completed) { + this._completed = false; + let minimized = this.maximized.GetBoolean(KeyStore.IsMinimized, false); + this.maximized.SetBoolean(KeyStore.IsMinimized, false); + this.animateTransition( + [this.props.Document.GetNumber(KeyStore.X, 0), this.props.Document.GetNumber(KeyStore.Y, 0)], + [this.maximized.GetNumber(KeyStore.X, 0), this.maximized.GetNumber(KeyStore.Y, 0)], + this.maximized.GetNumber(KeyStore.Width, 0), this.maximized.GetNumber(KeyStore.Width, 0), + Date.now(), this.maximized, minimized); + } + } + + render() { + return ( +
+ {this.minimizedIcon} +
); + } +} \ No newline at end of file diff --git a/src/fields/IconFIeld.ts b/src/fields/IconFIeld.ts new file mode 100644 index 000000000..a6694cc49 --- /dev/null +++ b/src/fields/IconFIeld.ts @@ -0,0 +1,25 @@ +import { BasicField } from "./BasicField"; +import { FieldId } from "./Field"; +import { Types } from "../server/Message"; + +export class IconField extends BasicField { + constructor(data: string = "", id?: FieldId, save: boolean = true) { + super(data, save, id); + } + + ToScriptString(): string { + return `new IconField("${this.Data}")`; + } + + Copy() { + return new IconField(this.Data); + } + + ToJson() { + return { + type: Types.Icon, + data: this.Data, + id: this.Id + }; + } +} \ No newline at end of file diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index ff2f31003..a347f8bcf 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -4,8 +4,6 @@ export namespace KeyStore { export const Prototype = new Key("Prototype"); export const X = new Key("X"); export const Y = new Key("Y"); - export const MinimizedX = new Key("MinimizedX"); - export const MinimizedY = new Key("MinimizedY"); export const Page = new Key("Page"); export const Title = new Key("Title"); export const Author = new Key("Author"); @@ -47,14 +45,16 @@ export namespace KeyStore { export const OptionalRightCollection = new Key("OptionalRightCollection"); export const Archives = new Key("Archives"); export const Workspaces = new Key("Workspaces"); - export const Minimized = new Key("Minimized"); + export const IsMinimized = new Key("IsMinimized"); + export const MinimizedDoc = new Key("MinimizedDoc"); + export const MaximizedDoc = new Key("MaximizedDoc"); export const CopyDraggedItems = new Key("CopyDraggedItems"); - export const KeyList: Key[] = [Prototype, X, Y, MinimizedX, MinimizedY, Page, Title, Author, PanX, PanY, Scale, NativeWidth, NativeHeight, + export const KeyList: Key[] = [Prototype, X, Y, Page, Title, Author, PanX, PanY, Scale, NativeWidth, NativeHeight, Width, Height, ZIndex, Zoom, Data, Annotations, ViewType, Layout, BackgroundColor, BackgroundLayout, OverlayLayout, LayoutKeys, LayoutFields, ColumnsKey, SchemaSplitPercentage, Caption, ActiveWorkspace, DocumentText, BrushingDocs, LinkedToDocs, LinkedFromDocs, LinkDescription, LinkTags, Thumbnail, ThumbnailPage, CurPage, AnnotationOn, NumPages, Ink, Cursors, OptionalRightCollection, - Archives, Workspaces, Minimized, CopyDraggedItems + Archives, Workspaces, IsMinimized, MinimizedDoc, MaximizedDoc, CopyDraggedItems ]; export function KeyLookup(keyid: string) { for (const key of KeyList) { diff --git a/src/server/Message.ts b/src/server/Message.ts index bbe4ffcad..15916ef12 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -14,7 +14,7 @@ export class Message { } export enum Types { - Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, + Number, List, Key, Image, Web, Document, Text, Icon, RichText, DocumentReference, Html, Video, Audio, Ink, PDF, Tuple, HistogramOp, Boolean, Script, } diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index 818230c1a..79ca5e55d 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -18,6 +18,7 @@ import { NumberField } from "./../fields/NumberField"; import { RichTextField } from "./../fields/RichTextField"; import { TextField } from "./../fields/TextField"; import { Transferable, Types } from "./Message"; +import { IconField } from "../fields/IconFIeld"; export class ServerUtils { public static prepend(extension: string): string { @@ -37,6 +38,7 @@ export class ServerUtils { case Types.Boolean: return new BooleanField(json.data, json.id, false); case Types.Number: return new NumberField(json.data, json.id, false); case Types.Text: return new TextField(json.data, json.id, false); + case Types.Icon: return new IconField(json.data, json.id, false); case Types.Html: return new HtmlField(json.data, json.id, false); case Types.Web: return new WebField(new URL(json.data), json.id, false); case Types.RichText: return new RichTextField(json.data, json.id, false); -- cgit v1.2.3-70-g09d2 From 49131cc84b0f3e739edb5ffcd64f3acc9469f658 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 23 Apr 2019 12:17:12 -0400 Subject: fixes to zoom scaling, moved and fixed icon stuff into CollectionFreeFormDocumentView. several smaller bugs. --- src/client/views/DocumentDecorations.tsx | 41 ++++- src/client/views/Main.tsx | 1 + .../views/collections/CollectionBaseView.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 1 + .../views/collections/CollectionSchemaView.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 174 +++++++++++++++----- src/client/views/nodes/DocumentView.tsx | 180 +++++---------------- src/client/views/nodes/ImageBox.tsx | 5 +- 9 files changed, 215 insertions(+), 195 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d704b6c47..95910c7be 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -18,6 +18,7 @@ import React = require("react"); import { CompileScript } from "../util/Scripting"; import { IconBox } from "./nodes/IconBox"; import { FieldValue, Field } from "../../fields/Field"; +import { Documents } from "../documents/Documents"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -134,11 +135,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @action onBackgroundMove = (e: PointerEvent): void => { let dragDocView = SelectionManager.SelectedDocuments()[0]; - const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0); let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); + const [xoff, yoff] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top); + dragData.xOffset = xoff; + dragData.yOffset = yoff; dragData.aliasOnDrop = false; - dragData.xOffset = e.x - left; - dragData.yOffset = e.y - top; let move = SelectionManager.SelectedDocuments()[0].props.moveDocument; dragData.moveDocument = move; this.Interacting = this._dragging = true; @@ -213,12 +215,39 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this._minimizedX = snapped ? selDocPos[0] + 4 : e.clientX; this._minimizedY = snapped ? selDocPos[1] - 18 : e.clientY; let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); - Promise.all(selectedDocs.map(async selDoc => await selDoc.getIconDoc())).then(minDocSet => + Promise.all(selectedDocs.map(async selDoc => await this.getIconDoc(selDoc))).then(minDocSet => this.moveIconDocs(SelectionManager.SelectedDocuments()) ); this._iconifying = snapped; } } + + + @action createIcon = (docView: DocumentView, layoutString: string): Document => { + let doc = docView.props.Document; + let iconDoc = Documents.IconDocument(layoutString); + iconDoc.SetText(KeyStore.Title, "ICON" + doc.Title) + iconDoc.SetBoolean(KeyStore.IsMinimized, false); + iconDoc.SetNumber(KeyStore.NativeWidth, 0); + iconDoc.SetNumber(KeyStore.NativeHeight, 0); + iconDoc.SetNumber(KeyStore.X, doc.GetNumber(KeyStore.X, 0)); + iconDoc.SetNumber(KeyStore.Y, doc.GetNumber(KeyStore.Y, 0) - 24); + iconDoc.Set(KeyStore.Prototype, doc); + iconDoc.Set(KeyStore.MaximizedDoc, doc); + doc.Set(KeyStore.MinimizedDoc, iconDoc); + docView.props.addDocument && docView.props.addDocument(iconDoc, false); + return iconDoc; + } + @action + public getIconDoc = async (docView: DocumentView): Promise => { + let doc = docView.props.Document; + return await doc.GetTAsync(KeyStore.MinimizedDoc, Document).then(async mindoc => + mindoc ? mindoc : + await doc.GetTAsync(KeyStore.BackgroundLayout, TextField).then(async field => + (field instanceof TextField) ? this.createIcon(docView, field.Data) : + await doc.GetTAsync(KeyStore.Layout, TextField).then(field => + (field instanceof TextField) ? this.createIcon(docView, field.Data) : undefined))); + } @action onMinimizeUp = (e: PointerEvent): void => { e.stopPropagation(); @@ -226,7 +255,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.removeEventListener("pointermove", this.onMinimizeMove); document.removeEventListener("pointerup", this.onMinimizeUp); let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); - Promise.all(selectedDocs.map(async selDoc => await selDoc.getIconDoc())).then(minDocSet => { + Promise.all(selectedDocs.map(async selDoc => await this.getIconDoc(selDoc))).then(minDocSet => { let minDocs = minDocSet.filter(minDoc => minDoc instanceof Document).map(minDoc => minDoc as Document); minDocs.map(minDoc => { minDoc.SetNumber(KeyStore.X, minDocs[0].GetNumber(KeyStore.X, 0)); @@ -238,7 +267,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } }); runInAction(() => this._minimizedX = this._minimizedY = 0); - if (!this._iconifying) selectedDocs[0].toggleIcon(); + if (!this._iconifying) selectedDocs[0].props.toggleMinimized(); this._iconifying = false; }); } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 09ef30f6b..934616aca 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -187,6 +187,7 @@ export class Main extends React.Component {
{!mainCont ? (null) : { doc.SetOnPrototype(KeyStore.AnnotationOn, this.props.Document); } if (!this.createsCycle(doc, this.props.Document)) { - doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); let value = this.props.Document.Get(this.props.fieldKey) as ListField; if (value) { if (!value.Data.some(v => v.Id === doc.Id) || allowDuplicates) { @@ -103,6 +102,9 @@ export class CollectionBaseView extends React.Component { } else { this.props.Document.Set(this.props.fieldKey, new ListField([doc])); } + // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? + doc.GetTAsync(KeyStore.ZoomBasis, NumberField, field => !field && + doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1))); } return true; // bcz: What is this code trying to do? diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index e4c647635..1ea18ed42 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -350,6 +350,7 @@ export class DockedFrameRenderer extends React.Component {
{ let props: FieldViewProps = { @@ -266,6 +266,7 @@ export class CollectionSchemaView extends CollectionSubView {
{ private _mainCont = React.createRef(); + private _downX: number = 0; + private _downY: number = 0; - @computed - get transform(): string { + @computed get transform() { return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) scale(${this.zoom}, ${this.zoom}) `; } - - @computed get zoom(): number { return 1 / this.props.Document.GetNumber(KeyStore.ZoomBasis, 1); } - @computed get zIndex(): number { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } - @computed get width(): number { return this.props.Document.Width(); } - @computed get height(): number { return this.props.Document.Height(); } - @computed get nativeWidth(): number { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } - @computed get nativeHeight(): number { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } - + @computed get X() { return this.props.Document.GetNumber(KeyStore.X, 0); } + @computed get Y() { return this.props.Document.GetNumber(KeyStore.Y, 0); } + @computed get zoom() { return 1 / this.props.Document.GetNumber(KeyStore.ZoomBasis, 1); } + @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } + @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } + @computed get width() { return this.props.Document.Width(); } + @computed get height() { return this.props.Document.Height(); } + @computed get zIndex() { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } set width(w: number) { this.props.Document.SetData(KeyStore.Width, w, NumberField); if (this.nativeWidth && this.nativeHeight) { this.props.Document.SetNumber(KeyStore.Height, this.nativeHeight / this.nativeWidth * w); } } - set height(h: number) { this.props.Document.SetData(KeyStore.Height, h, NumberField); if (this.nativeWidth && this.nativeHeight) { this.props.Document.SetNumber(KeyStore.Width, this.nativeWidth / this.nativeHeight * h); } } - set zIndex(h: number) { this.props.Document.SetData(KeyStore.ZIndex, h, NumberField); } - get X() { - return this.props.Document.GetNumber(KeyStore.X, 0); - } - get Y() { - return this.props.Document.GetNumber(KeyStore.Y, 0); - } - getTransform = (): Transform => - this.props.ScreenToLocalTransform() - .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.zoom) - contentScaling = () => (this.nativeWidth > 0 ? this.width / this.nativeWidth : 1); panelWidth = () => this.props.PanelWidth(); panelHeight = () => this.props.PanelHeight(); + toggleMinimized = () => this.toggleIcon(); + getTransform = (): Transform => this.props.ScreenToLocalTransform() + .translate(-this.X, -this.Y) + .scale(1 / this.contentScaling()).scale(1 / this.zoom) @computed get docView() { return ; } + animateBetweenIcon(first: boolean, icon: number[], targ: number[], width: number, height: number, stime: number, target: Document, maximizing: boolean) { + setTimeout(() => { + let now = Date.now(); + let progress = Math.min(1, (now - stime) / 200); + let pval = maximizing ? + [icon[0] + (targ[0] - icon[0]) * progress, icon[1] + (targ[1] - icon[1]) * progress] : + [targ[0] + (icon[0] - targ[0]) * progress, targ[1] + (icon[1] - targ[1]) * progress]; + target.SetNumber(KeyStore.Width, maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress); + target.SetNumber(KeyStore.Height, maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress); + target.SetNumber(KeyStore.X, pval[0]); + target.SetNumber(KeyStore.Y, pval[1]); + if (first) { + target.SetBoolean(KeyStore.IsMinimized, false); + } + if (now < stime + 200) { + this.animateBetweenIcon(false, icon, targ, width, height, stime, target, maximizing); + } + else { + if (!maximizing) { + target.SetBoolean(KeyStore.IsMinimized, true); + target.SetNumber(KeyStore.X, targ[0]); + target.SetNumber(KeyStore.Y, targ[1]); + target.SetNumber(KeyStore.Width, width); + target.SetNumber(KeyStore.Height, height); + } + (target as any).isIconAnimating = false; + } + }, + 2); + } + @action + public toggleIcon = async (): Promise => { + SelectionManager.DeselectAll(); + let isMinimized: boolean | undefined; + let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document); + if (!minDoc) return; + let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField); + if (!minimizedDocSet) return; + minimizedDocSet.Data.map(async minimizedDoc => { + if (minimizedDoc instanceof Document) { + this.props.addDocument && this.props.addDocument(minimizedDoc, false); + let maximizedDoc = await minimizedDoc.GetTAsync(KeyStore.MaximizedDoc, Document); + if (maximizedDoc instanceof Document && !(maximizedDoc as any).isIconAnimating) { + (maximizedDoc as any).isIconAnimating = true; + if (isMinimized === undefined) { + let maximizedDocMinimizedState = await maximizedDoc.GetTAsync(KeyStore.IsMinimized, BooleanField); + isMinimized = (maximizedDocMinimizedState && maximizedDocMinimizedState.Data) ? true : false; + } + let minx = await minimizedDoc.GetTAsync(KeyStore.X, NumberField); + let miny = await minimizedDoc.GetTAsync(KeyStore.Y, NumberField); + let maxx = await maximizedDoc.GetTAsync(KeyStore.X, NumberField); + let maxy = await maximizedDoc.GetTAsync(KeyStore.Y, NumberField); + let maxw = await maximizedDoc.GetTAsync(KeyStore.Width, NumberField); + let maxh = await maximizedDoc.GetTAsync(KeyStore.Height, NumberField); + if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined && + maxw !== undefined && maxh !== undefined) + this.animateBetweenIcon( + true, + [minx.Data, miny.Data], [maxx.Data, maxy.Data], maxw.Data, maxh.Data, + Date.now(), maximizedDoc, isMinimized); + } + + } + }) + } + onPointerDown = (e: React.PointerEvent): void => { + e.stopPropagation(); + this._downX = e.clientX; + this._downY = e.clientY; + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + onPointerUp = (e: PointerEvent): void => { + document.removeEventListener("pointerup", this.onPointerUp); + e.stopPropagation(); + if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { + this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => { + if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents + SelectionManager.DeselectAll(); + this.props.addDocument && this.props.addDocument(maxdoc, false); + this.toggleIcon(); + } + }); + } + } + render() { + let maximizedDoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document); let zoomFade = 1; //var zoom = doc.GetNumber(KeyStore.ZoomBasis, 1); - // let transform = this.getTransform().scale(this.contentScaling()).inverse(); - // var [sptX, sptY] = transform.transformPoint(0, 0); - // let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); - // let w = bptX - sptX; - // //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; - // let fadeUp = .75 * 1800; - // let fadeDown = .075 * 1800; - // zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; + let transform = this.getTransform().scale(this.contentScaling()).inverse(); + var [sptX, sptY] = transform.transformPoint(0, 0); + let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); + let w = bptX - sptX; + //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; + const screenWidth = 1800; + let fadeUp = .75 * screenWidth; + let fadeDown = (maximizedDoc ? .0075 : .075) * screenWidth; + zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; return ( -
+
{this.docView}
); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 2f8ac9f20..8922e4b81 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -5,8 +5,6 @@ import { Field, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; -import { TextField } from "../../../fields/TextField"; import { ServerUtils } from "../../../server/ServerUtil"; import { emptyFunction, Utils } from "../../../Utils"; import { Documents } from "../../documents/Documents"; @@ -40,6 +38,7 @@ export interface DocumentViewProps { selectOnLoad: boolean; parentActive: () => boolean; whenActiveChanged: (isActive: boolean) => void; + toggleMinimized: () => void; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; @@ -83,7 +82,6 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { @observer export class DocumentView extends React.Component { - static _incompleteAnimations: Map = new Map(); private _downX: number = 0; private _downY: number = 0; private _mainCont = React.createRef(); @@ -96,42 +94,16 @@ export class DocumentView extends React.Component { @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array()); } @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array()); } - onPointerDown = (e: React.PointerEvent): void => { - this._downX = e.clientX; - this._downY = e.clientY; - if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) { - return; - } - if (e.shiftKey && e.buttons === 2) { - if (this.props.isTopMost) { - this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey); - } else { - CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e); - } - e.stopPropagation(); - } else { - let maxdoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document); - if (this.active || - maxdoc instanceof Document // bcz: need a better way of allowing a document to handle pointer events when its not active (ie. be a top-level widget) - ) { - e.stopPropagation(); - document.removeEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); - } - } - } - + @action componentDidMount() { if (this._mainCont.current) { this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }); } - runInAction(() => DocumentManager.Instance.DocumentViews.push(this)); + DocumentManager.Instance.DocumentViews.push(this); } - + @action componentDidUpdate() { if (this._dropDisposer) { this._dropDisposer(); @@ -142,12 +114,16 @@ export class DocumentView extends React.Component { }); } } - + @action componentWillUnmount() { if (this._dropDisposer) { this._dropDisposer(); } - runInAction(() => DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1)); + DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1); + } + + stopPropagation = (e: React.SyntheticEvent) => { + e.stopPropagation(); } startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) { @@ -168,43 +144,51 @@ export class DocumentView extends React.Component { } } - onPointerMove = (e: PointerEvent): void => { - if (e.cancelBubble) { + onPointerDown = (e: React.PointerEvent): void => { + this._downX = e.clientX; + this._downY = e.clientY; + if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) { return; } - if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { + if (e.shiftKey && e.buttons === 2) { + if (this.props.isTopMost) { + this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey); + } else { + CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e); + } + e.stopPropagation(); + } else if (this.active) { document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - if (!e.altKey && (!this.topMost || e.buttons === 2)) { - this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey); + document.addEventListener("pointerup", this.onPointerUp); + } + } + onPointerMove = (e: PointerEvent): void => { + if (!e.cancelBubble) { + if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + if (!e.altKey && (!this.topMost || e.buttons === 2)) { + this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey); + } } + e.stopPropagation(); + e.preventDefault(); } - e.stopPropagation(); - e.preventDefault(); } onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - e.stopPropagation(); if (!SelectionManager.IsSelected(this) && e.button !== 2 && Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => { - if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents - this.props.addDocument && this.props.addDocument(maxdoc, false); - this.toggleIcon(); - } else - SelectionManager.SelectDoc(this, e.ctrlKey); - }); + SelectionManager.SelectDoc(this, e.ctrlKey); } } - stopPropagation = (e: React.SyntheticEvent) => { - e.stopPropagation(); - } deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } - fieldsClicked = (e: React.MouseEvent): void => { let kvp = Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }); CollectionDockingView.Instance.AddRightSplit(kvp); @@ -215,7 +199,6 @@ export class DocumentView extends React.Component { ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked }); ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); } - closeFullScreenClicked = (e: React.MouseEvent): void => { CollectionDockingView.Instance.CloseFullScreen(); ContextMenu.Instance.clearItems(); @@ -223,92 +206,6 @@ export class DocumentView extends React.Component { ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); } - @action createIcon = (layoutString: string): Document => { - let iconDoc = Documents.IconDocument(layoutString); - iconDoc.SetText(KeyStore.Title, "ICON" + this.props.Document.Title) - iconDoc.SetBoolean(KeyStore.IsMinimized, false); - iconDoc.SetNumber(KeyStore.NativeWidth, 0); - iconDoc.SetNumber(KeyStore.NativeHeight, 0); - iconDoc.SetNumber(KeyStore.X, this.props.Document.GetNumber(KeyStore.X, 0)); - iconDoc.SetNumber(KeyStore.Y, this.props.Document.GetNumber(KeyStore.Y, 0) - 24); - iconDoc.Set(KeyStore.Prototype, this.props.Document); - iconDoc.Set(KeyStore.MaximizedDoc, this.props.Document); - this.props.Document.Set(KeyStore.MinimizedDoc, iconDoc); - this.props.addDocument && this.props.addDocument(iconDoc, false); - return iconDoc; - } - - animateBetweenIcon(icon: number[], targ: number[], width: number, height: number, stime: number, target: Document, maximizing: boolean) { - setTimeout(() => { - let now = Date.now(); - let progress = Math.min(1, (now - stime) / 200); - let pval = maximizing ? - [icon[0] + (targ[0] - icon[0]) * progress, icon[1] + (targ[1] - icon[1]) * progress] : - [targ[0] + (icon[0] - targ[0]) * progress, targ[1] + (icon[1] - targ[1]) * progress]; - target.SetNumber(KeyStore.Width, maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress); - target.SetNumber(KeyStore.Height, maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress); - target.SetNumber(KeyStore.X, pval[0]); - target.SetNumber(KeyStore.Y, pval[1]); - if (now < stime + 200) { - this.animateBetweenIcon(icon, targ, width, height, stime, target, maximizing); - } - else { - if (!maximizing) { - target.SetBoolean(KeyStore.IsMinimized, true); - target.SetNumber(KeyStore.X, targ[0]); - target.SetNumber(KeyStore.Y, targ[1]); - target.SetNumber(KeyStore.Width, width); - target.SetNumber(KeyStore.Height, height); - } - DocumentView._incompleteAnimations.set(target.Id, false); - } - }, - 2); - } - - @action - public toggleIcon = async (): Promise => { - SelectionManager.DeselectAll(); - let isMinimized: boolean | undefined; - let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document); - if (!minDoc) return; - let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField); - if (!minimizedDocSet) return; - minimizedDocSet.Data.map(async minimizedDoc => { - if (minimizedDoc instanceof Document) { - this.props.addDocument && this.props.addDocument(minimizedDoc, false); - let maximizedDoc = await minimizedDoc.GetTAsync(KeyStore.MaximizedDoc, Document); - if (maximizedDoc instanceof Document && !DocumentView._incompleteAnimations.get(maximizedDoc.Id)) { - DocumentView._incompleteAnimations.set(maximizedDoc.Id, true); - isMinimized = isMinimized === undefined ? maximizedDoc.GetBoolean(KeyStore.IsMinimized, false) : isMinimized; - maximizedDoc.SetBoolean(KeyStore.IsMinimized, false); - let minx = await minimizedDoc.GetTAsync(KeyStore.X, NumberField); - let miny = await minimizedDoc.GetTAsync(KeyStore.Y, NumberField); - let maxx = await maximizedDoc.GetTAsync(KeyStore.X, NumberField); - let maxy = await maximizedDoc.GetTAsync(KeyStore.Y, NumberField); - let maxw = await maximizedDoc.GetTAsync(KeyStore.Width, NumberField); - let maxh = await maximizedDoc.GetTAsync(KeyStore.Height, NumberField); - if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined && - maxw !== undefined && maxh !== undefined) - this.animateBetweenIcon( - [minx.Data, miny.Data], [maxx.Data, maxy.Data], maxw.Data, maxh.Data, - Date.now(), maximizedDoc, isMinimized); - } - - } - }) - } - - @action - public getIconDoc = async (): Promise => { - return await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document).then(async mindoc => - mindoc ? mindoc : - await this.props.Document.GetTAsync(KeyStore.BackgroundLayout, TextField).then(async field => - (field instanceof TextField) ? this.createIcon(field.Data) : - await this.props.Document.GetTAsync(KeyStore.Layout, TextField).then(field => - (field instanceof TextField) ? this.createIcon(field.Data) : undefined))); - } - @undoBatch @action drop = (e: Event, de: DragManager.DropEvent) => { @@ -353,6 +250,7 @@ export class DocumentView extends React.Component { } } + @action onDrop = (e: React.DragEvent) => { let text = e.dataTransfer.getData("text/plain"); if (!e.isDefaultPrevented() && text && text.startsWith(" { isSelected = () => SelectionManager.IsSelected(this); select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed); - @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } @computed get contents() { return (); } - render() { var scaling = this.props.ContentScaling(); var nativeHeight = this.nativeHeight > 0 ? this.nativeHeight.toString() + "px" : "100%"; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5d9aefd61..a16fd5007 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -16,7 +16,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); import { InkingControl } from '../InkingControl'; -import { InkTool } from '../../../fields/InkField'; +import { NumberField } from '../../../fields/NumberField'; @observer export class ImageBox extends React.Component { @@ -42,7 +42,8 @@ export class ImageBox extends React.Component { var w = this._imgRef.current!.naturalWidth; if (this._photoIndex === 0) { this.props.Document.SetNumber(KeyStore.NativeHeight, this.props.Document.GetNumber(KeyStore.NativeWidth, 0) * h / w); - this.props.Document.SetNumber(KeyStore.Height, this.props.Document.Width() * h / w); + this.props.Document.GetTAsync(KeyStore.Width, NumberField, field => + field && this.props.Document.SetNumber(KeyStore.Height, field.Data * h / w)); } } -- cgit v1.2.3-70-g09d2 From 575d8b339cdf74cdcb8d46dcd6e627aec2dda636 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 24 Apr 2019 23:17:44 -0400 Subject: added borderRadius and fixed a bunch of broken props along the way. --- src/client/documents/Documents.ts | 2 ++ src/client/views/Main.scss | 3 ++- src/client/views/Main.tsx | 3 ++- src/client/views/MainOverlayTextBox.tsx | 4 ++-- src/client/views/collections/CollectionBaseView.tsx | 7 ++++--- src/client/views/collections/CollectionDockingView.tsx | 3 ++- src/client/views/collections/CollectionSchemaView.tsx | 6 +++++- src/client/views/collections/CollectionSubView.tsx | 1 + src/client/views/collections/CollectionTreeView.tsx | 5 ++++- .../collectionFreeForm/CollectionFreeFormView.scss | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 14 +++++++++++--- .../views/collections/collectionFreeForm/MarqueeView.tsx | 7 ++++--- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 11 +++++++++++ src/client/views/nodes/DocumentView.tsx | 2 ++ src/client/views/nodes/FieldView.tsx | 7 ++++++- src/client/views/nodes/FormattedTextBox.scss | 3 +-- src/client/views/nodes/FormattedTextBox.tsx | 5 ++++- src/client/views/nodes/ImageBox.scss | 3 --- src/client/views/nodes/ImageBox.tsx | 2 +- src/fields/KeyStore.ts | 3 ++- 20 files changed, 67 insertions(+), 25 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0e6661819..879b114b6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -55,6 +55,7 @@ export interface DocumentOptions { backgroundColor?: string; copyDraggedItems?: boolean; documentText?: string; + borderRounding?: number; } export namespace Documents { @@ -108,6 +109,7 @@ export namespace Documents { if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); } if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); } if (options.copyDraggedItems !== undefined) { doc.SetBoolean(KeyStore.CopyDraggedItems, options.copyDraggedItems); } + if (options.borderRounding !== undefined) { doc.SetNumber(KeyStore.BorderRounding, options.borderRounding); } return doc; } diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 4373534b2..3edc79d39 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -42,7 +42,8 @@ h1 { } .jsx-parser { - width:100% + width:100%; + pointer-events: none; } p { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 934616aca..057f68ed9 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -17,7 +17,7 @@ import { CurrentUserUtils } from '../../server/authentication/models/current_use import { MessageStore } from '../../server/Message'; import { RouteStore } from '../../server/RouteStore'; import { ServerUtils } from '../../server/ServerUtil'; -import { emptyDocFunction, emptyFunction, returnTrue, Utils, returnOne } from '../../Utils'; +import { emptyDocFunction, emptyFunction, returnTrue, Utils, returnOne, returnZero } from '../../Utils'; import { Documents } from '../documents/Documents'; import { ColumnAttributeModel } from '../northstar/core/attribute/AttributeModel'; import { AttributeTransformationModel } from '../northstar/core/attribute/AttributeTransformationModel'; @@ -197,6 +197,7 @@ export class Main extends React.Component { isTopMost={true} selectOnLoad={false} focus={emptyDocFunction} + borderRounding={returnZero} parentActive={returnTrue} whenActiveChanged={emptyFunction} ContainingCollectionView={undefined} />} diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 9aaaad084..f98f6e8a5 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { Document } from '../../fields/Document'; import { Key } from '../../fields/Key'; import { KeyStore } from '../../fields/KeyStore'; -import { emptyDocFunction, emptyFunction, returnTrue } from '../../Utils'; +import { emptyDocFunction, emptyFunction, returnTrue, returnZero } from '../../Utils'; import '../northstar/model/ModelExtensions'; import '../northstar/utils/Extensions'; import { DragManager } from '../util/DragManager'; @@ -97,7 +97,7 @@ export class MainOverlayTextBox extends React.Component style={{ width: `${this.TextDoc.Width()}px`, height: `${this.TextDoc.Height()}px` }}> + ScreenToLocalTransform={this._textXf} borderRounding={returnZero} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyDocFunction} />
; } diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 097236c1d..e65770137 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -2,13 +2,12 @@ import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Document } from '../../../fields/Document'; -import { Field, FieldValue, FieldWaiting } from '../../../fields/Field'; +import { FieldValue, FieldWaiting } from '../../../fields/Field'; import { KeyStore } from '../../../fields/KeyStore'; import { ListField } from '../../../fields/ListField'; import { NumberField } from '../../../fields/NumberField'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; -import { TextField } from '../../../fields/TextField'; export enum CollectionViewType { Invalid, @@ -190,7 +189,9 @@ export class CollectionBaseView extends React.Component { }; const viewtype = this.collectionViewType; return ( -
+
{viewtype !== undefined ? this.props.children(viewtype, props) : (null)}
); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 84159635a..eb94a4e6d 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -8,7 +8,7 @@ import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/KeyStore"; import Measure from "react-measure"; import { FieldId, Opt, Field, FieldWaiting } from "../../../fields/Field"; -import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne } from "../../../Utils"; +import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne, returnZero } from "../../../Utils"; import { Server } from "../../Server"; import { undoBatch } from "../../util/UndoManager"; import { DocumentView } from "../nodes/DocumentView"; @@ -368,6 +368,7 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyDocFunction} + borderRounding={returnZero} ContainingCollectionView={undefined} />
); } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index cb7a67991..dc2910ede 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -12,7 +12,7 @@ import { Field, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { emptyDocFunction, emptyFunction, returnFalse } from "../../../Utils"; +import { emptyDocFunction, emptyFunction, returnFalse, returnZero } from "../../../Utils"; import { Server } from "../../Server"; import { SetupDrag } from "../../util/DragManager"; import { CompileScript, ToField } from "../../util/Scripting"; @@ -77,6 +77,9 @@ export class CollectionSchemaView extends CollectionSubView { focus: emptyDocFunction, active: returnFalse, whenActiveChanged: emptyFunction, + borderRounding: this.props.borderRounding, + PanelHeight: returnZero, + PanelWidth: returnZero, }; let contents = ( @@ -275,6 +278,7 @@ export class CollectionSchemaView extends CollectionSubView { focus={emptyDocFunction} parentActive={this.props.active} whenActiveChanged={this.props.whenActiveChanged} + borderRounding={this.props.borderRounding} />
boolean) => boolean; PanelWidth: () => number; PanelHeight: () => number; + borderRounding: () => number; } export interface SubCollectionViewProps extends CollectionViewProps { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index e0387f4b4..b9d1f0bd9 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -136,7 +136,10 @@ export class CollectionTreeView extends CollectionSubView { ); return ( -
e.stopPropagation()} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}> +
e.stopPropagation()} + onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
.jsx-parser { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7492d8744..9e2c9bf9a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -257,6 +257,7 @@ export class CollectionFreeFormView extends CollectionSubView { focus: this.focusDocument, parentActive: this.props.active, whenActiveChanged: this.props.active, + borderRounding: this.props.borderRounding, }; } @@ -288,11 +289,17 @@ export class CollectionFreeFormView extends CollectionSubView { const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`; return (
- + + {this.props.Document.Title} + + */} + - @@ -340,6 +347,7 @@ interface CollectionFreeFormViewPannableContentsProps { panX: () => number; panY: () => number; zoomScaling: () => number; + borderRadius: () => number; } @observer @@ -350,7 +358,7 @@ class CollectionFreeFormViewPannableContents extends React.Component otherwise, reactions won't fire - return
+ return
{this.props.children}
; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 898fff019..e724ab47e 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -14,7 +14,6 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); import { Utils } from "../../../../Utils"; -import { ListField } from "../../../../fields/ListField"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -25,6 +24,7 @@ interface MarqueeViewProps { selectDocuments: (docs: Document[]) => void; removeDocument: (doc: Document) => boolean; addLiveTextDocument: (doc: Document) => void; + borderRadius: () => number; } @observer @@ -138,7 +138,7 @@ export class MarqueeView extends React.Component this.cleanupInteractions(true); e.stopPropagation(); } - if (e.key === "c" || e.key === "r") { + if (e.key === "c" || e.key === "r" || e.key === "e") { e.stopPropagation(); let bounds = this.Bounds; let selected = this.marqueeSelect().map(d => { @@ -156,6 +156,7 @@ export class MarqueeView extends React.Component y: bounds.top, panx: 0, pany: 0, + borderRounding: e.key === "e" ? -1 : undefined, backgroundColor: selected.length ? "white" : "", scale: zoomBasis, width: bounds.width * zoomBasis, @@ -250,7 +251,7 @@ export class MarqueeView extends React.Component } render() { - return
+ return
{this.props.children} {!this._visible ? (null) : this.marqueeDiv}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 420324d40..8caf5ff31 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -65,6 +65,7 @@ export class CollectionFreeFormDocumentView extends React.Component; } @@ -148,6 +149,15 @@ export class CollectionFreeFormDocumentView extends React.Component { + let br = this.props.Document.GetNumber(KeyStore.BorderRounding, 0); + return br >= 0 ? br : + this.props.Document.GetNumber(KeyStore.NativeWidth, 0) === 0 ? + Math.min(this.props.PanelWidth(), this.props.PanelHeight()) + : + Math.min(this.props.Document.GetNumber(KeyStore.NativeWidth, 0), this.props.Document.GetNumber(KeyStore.NativeHeight, 0)); + } + render() { let maximizedDoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document); let zoomFade = 1; @@ -168,6 +178,7 @@ export class CollectionFreeFormDocumentView extends React.Component boolean; whenActiveChanged: (isActive: boolean) => void; toggleMinimized: () => void; + borderRounding: () => number; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; @@ -277,6 +278,7 @@ export class DocumentView extends React.Component {
boolean; whenActiveChanged: (isActive: boolean) => void; focus: (doc: Document) => void; + PanelWidth: () => number; + PanelHeight: () => number; + borderRounding: () => number; } @observer @@ -100,6 +103,8 @@ export class FieldView extends React.Component { layoutKey={KeyStore.Layout} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} + borderRounding={returnZero} + toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} /> ); } diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 5eb2bf7ce..59857bab3 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -22,11 +22,10 @@ overflow-x: hidden; color: initial; height: 100%; - pointer-events: all; + pointer-events: none; } .formattedTextBox-cont-hidden { overflow: hidden; - pointer-events: none; } .menuicon { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 9cd58c73a..4b2fdbaff 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -273,7 +273,10 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte let color = this.props.Document.GetText(KeyStore.BackgroundColor, ""); return (
{ let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 1); let interactive = InkingControl.Instance.selectedTool ? "" : "interactive" return ( -
+
Image not found {paths.length > 1 ? this.dots(paths) : (null)} {this.lightbox(paths)} diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 0a96beb50..aa18a9f33 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -49,12 +49,13 @@ export namespace KeyStore { export const MinimizedDoc = new Key("MinimizedDoc"); export const MaximizedDoc = new Key("MaximizedDoc"); export const CopyDraggedItems = new Key("CopyDraggedItems"); + export const BorderRounding = new Key("BorderRounding"); export const KeyList: Key[] = [Prototype, X, Y, Page, Title, Author, PanX, PanY, Scale, NativeWidth, NativeHeight, Width, Height, ZIndex, ZoomBasis, Data, Annotations, ViewType, Layout, BackgroundColor, BackgroundLayout, OverlayLayout, LayoutKeys, LayoutFields, ColumnsKey, SchemaSplitPercentage, Caption, ActiveWorkspace, DocumentText, BrushingDocs, LinkedToDocs, LinkedFromDocs, LinkDescription, LinkTags, Thumbnail, ThumbnailPage, CurPage, AnnotationOn, NumPages, Ink, Cursors, OptionalRightCollection, - Archives, Workspaces, IsMinimized, MinimizedDoc, MaximizedDoc, CopyDraggedItems + Archives, Workspaces, IsMinimized, MinimizedDoc, MaximizedDoc, CopyDraggedItems, BorderRounding ]; export function KeyLookup(keyid: string) { for (const key of KeyList) { -- cgit v1.2.3-70-g09d2 From 6a62e0a16abc3bbadfb179750463e3d361f1c759 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 25 Apr 2019 09:15:22 -0400 Subject: silly me - borderRadius can be inherited --- src/client/views/Main.scss | 1 + src/client/views/Main.tsx | 1 - src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/collections/CollectionBaseView.tsx | 2 +- src/client/views/collections/CollectionDockingView.tsx | 1 - src/client/views/collections/CollectionSchemaView.tsx | 2 -- src/client/views/collections/CollectionSubView.tsx | 1 - src/client/views/collections/CollectionTreeView.tsx | 2 +- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 10 ++++------ .../views/collections/collectionFreeForm/MarqueeView.tsx | 3 +-- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 3 +-- src/client/views/nodes/FieldView.tsx | 2 -- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 14 files changed, 11 insertions(+), 22 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.tsx') diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 3edc79d39..2f899ff28 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -44,6 +44,7 @@ h1 { .jsx-parser { width:100%; pointer-events: none; + border-radius: inherit; } p { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 057f68ed9..c6b3f06d8 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -197,7 +197,6 @@ export class Main extends React.Component { isTopMost={true} selectOnLoad={false} focus={emptyDocFunction} - borderRounding={returnZero} parentActive={returnTrue} whenActiveChanged={emptyFunction} ContainingCollectionView={undefined} />} diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index f98f6e8a5..be8d67925 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -97,7 +97,7 @@ export class MainOverlayTextBox extends React.Component style={{ width: `${this.TextDoc.Width()}px`, height: `${this.TextDoc.Height()}px` }}> + ScreenToLocalTransform={this._textXf} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyDocFunction} />
; } diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index e65770137..87b767c93 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -190,7 +190,7 @@ export class CollectionBaseView extends React.Component { const viewtype = this.collectionViewType; return (
{viewtype !== undefined ? this.props.children(viewtype, props) : (null)}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index eb94a4e6d..3267f2455 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -368,7 +368,6 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyDocFunction} - borderRounding={returnZero} ContainingCollectionView={undefined} />
); } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index dc2910ede..b6d5f1bfa 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -77,7 +77,6 @@ export class CollectionSchemaView extends CollectionSubView { focus: emptyDocFunction, active: returnFalse, whenActiveChanged: emptyFunction, - borderRounding: this.props.borderRounding, PanelHeight: returnZero, PanelWidth: returnZero, }; @@ -278,7 +277,6 @@ export class CollectionSchemaView extends CollectionSubView { focus={emptyDocFunction} parentActive={this.props.active} whenActiveChanged={this.props.whenActiveChanged} - borderRounding={this.props.borderRounding} />
boolean) => boolean; PanelWidth: () => number; PanelHeight: () => number; - borderRounding: () => number; } export interface SubCollectionViewProps extends CollectionViewProps { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index b9d1f0bd9..905b48db7 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -137,7 +137,7 @@ export class CollectionTreeView extends CollectionSubView { return (
e.stopPropagation()} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9e2c9bf9a..56342c84c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -257,7 +257,6 @@ export class CollectionFreeFormView extends CollectionSubView { focus: this.focusDocument, parentActive: this.props.active, whenActiveChanged: this.props.active, - borderRounding: this.props.borderRounding, }; } @@ -289,17 +288,17 @@ export class CollectionFreeFormView extends CollectionSubView { const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`; return (
{/* {this.props.Document.Title} */} - - @@ -347,7 +346,6 @@ interface CollectionFreeFormViewPannableContentsProps { panX: () => number; panY: () => number; zoomScaling: () => number; - borderRadius: () => number; } @observer @@ -358,7 +356,7 @@ class CollectionFreeFormViewPannableContents extends React.Component otherwise, reactions won't fire - return
+ return
{this.props.children}
; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index e724ab47e..b511a6e3d 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -24,7 +24,6 @@ interface MarqueeViewProps { selectDocuments: (docs: Document[]) => void; removeDocument: (doc: Document) => boolean; addLiveTextDocument: (doc: Document) => void; - borderRadius: () => number; } @observer @@ -251,7 +250,7 @@ export class MarqueeView extends React.Component } render() { - return
+ return
{this.props.children} {!this._visible ? (null) : this.marqueeDiv}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 8caf5ff31..4537ce3eb 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -65,7 +65,6 @@ export class CollectionFreeFormDocumentView extends React.Component; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ddf99c109..cec6e6468 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -41,7 +41,6 @@ export interface DocumentViewProps { parentActive: () => boolean; whenActiveChanged: (isActive: boolean) => void; toggleMinimized: () => void; - borderRounding: () => number; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; @@ -278,7 +277,7 @@ export class DocumentView extends React.Component {
void; PanelWidth: () => number; PanelHeight: () => number; - borderRounding: () => number; } @observer @@ -103,7 +102,6 @@ export class FieldView extends React.Component { layoutKey={KeyStore.Layout} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} - borderRounding={returnZero} toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} /> ); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 4b2fdbaff..5b17763e7 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -274,7 +274,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte return (