diff options
-rw-r--r-- | src/client/util/DragManager.ts | 20 | ||||
-rw-r--r-- | src/client/views/collections/CollectionFreeFormView.tsx | 23 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 114 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 8 | ||||
-rw-r--r-- | src/client/views/collections/CollectionViewBase.tsx | 14 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 |
6 files changed, 127 insertions, 54 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index eb4b3aeaa..fd026992b 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -61,7 +61,7 @@ export namespace DragManager { }; } - export function StartDrag(ele: HTMLElement, dragData: { [id: string]: any }, options: DragOptions) { + export function StartDrag(ele: HTMLElement, dragData: { [id: string]: any }, options?: DragOptions) { DocumentDecorations.Instance.Hidden = true; if (!dragDiv) { dragDiv = document.createElement("div"); @@ -87,10 +87,12 @@ export namespace DragManager { dragDiv.appendChild(dragElement); let hideSource = false; - if (typeof options.hideSource === "boolean") { - hideSource = options.hideSource; - } else { - hideSource = options.hideSource(); + if (options) { + if (typeof options.hideSource === "boolean") { + hideSource = options.hideSource; + } else { + hideSource = options.hideSource(); + } } const wasHidden = ele.hidden; if (hideSource) { @@ -107,7 +109,7 @@ export namespace DragManager { const upHandler = (e: PointerEvent) => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); - FinishDrag(dragElement, e, options, dragData); + FinishDrag(dragElement, e, dragData, options); if (hideSource && !wasHidden) { ele.hidden = false; } @@ -116,7 +118,7 @@ export namespace DragManager { document.addEventListener("pointerup", upHandler); } - function FinishDrag(dragEle: HTMLElement, e: PointerEvent, options: DragOptions, dragData: { [index: string]: any }) { + function FinishDrag(dragEle: HTMLElement, e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions) { dragDiv.removeChild(dragEle); const target = document.elementFromPoint(e.x, e.y); if (!target) { @@ -130,7 +132,9 @@ export namespace DragManager { data: dragData } })); - options.handlers.dragComplete({}); + if (options) { + options.handlers.dragComplete({}); + } DocumentDecorations.Instance.Hidden = false; } }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 90eb8a44e..b54d9e0cf 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -44,16 +44,13 @@ export class CollectionFreeFormView extends CollectionViewBase { @action drop = (e: Event, de: DragManager.DropEvent) => { super.drop(e, de); - const doc: DocumentView = de.data["document"]; - const xOffset = de.data["xOffset"] as number || 0; - const yOffset = de.data["yOffset"] as number || 0; - //this should be able to use translate and scale methods on an Identity transform, no? - const transform = this.getTransform(); - const screenX = de.x - xOffset; - const screenY = de.y - yOffset; - const [x, y] = transform.transformPoint(screenX, screenY); - doc.props.Document.SetNumber(KeyStore.X, x); - doc.props.Document.SetNumber(KeyStore.Y, y); + const docView: DocumentView = de.data["documentView"]; + let doc: Document = docView ? docView.props.Document : de.data["document"]; + let screenX = de.x - (de.data["xOffset"] as number || 0); + let screenY = de.y - (de.data["yOffset"] as number || 0); + const [x, y] = this.getTransform().transformPoint(screenX, screenY); + doc.SetNumber(KeyStore.X, x); + doc.SetNumber(KeyStore.Y, y); this.bringToFront(doc); } @@ -148,15 +145,15 @@ export class CollectionFreeFormView extends CollectionViewBase { } @action - bringToFront(doc: DocumentView) { + bringToFront(doc: Document) { const { fieldKey: fieldKey, Document: Document } = this.props; const value: Document[] = Document.GetList<Document>(fieldKey, []).slice(); value.sort((doc1, doc2) => { - if (doc1 === doc.props.Document) { + if (doc1 === doc) { return 1; } - if (doc2 === doc.props.Document) { + if (doc2 === doc) { return -1; } return doc1.GetNumber(KeyStore.ZIndex, 0) - doc2.GetNumber(KeyStore.ZIndex, 0); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index dc952ef82..d5b82cbb6 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -15,6 +15,8 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { CollectionViewBase } from "./CollectionViewBase"; +import { DragManager } from "../../util/DragManager"; +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 @@ -30,6 +32,9 @@ export class CollectionSchemaView extends CollectionViewBase { @observable _selectedIndex = 0; @observable _splitPercentage: number = 50; + + + renderCell = (rowProps: CellInfo) => { let props: FieldViewProps = { doc: rowProps.value[0], @@ -42,31 +47,55 @@ export class CollectionSchemaView extends CollectionViewBase { let contents = ( <FieldView {...props} /> ) + let reference = React.createRef<HTMLDivElement>(); + let onRowMove = action((e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + DragManager.StartDrag(reference.current!, { document: props.doc }); + }); + let onRowUp = action((e: PointerEvent): void => { + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + }); + let onRowDown = (e: React.PointerEvent) => { + if (e.shiftKey) { + CollectionDockingView.Instance.StartOtherDrag(reference.current!, props.doc); + e.stopPropagation(); + } else { + document.addEventListener("pointermove", onRowMove); + document.addEventListener('pointerup', onRowUp); + } + } return ( - <EditableView contents={contents} height={36} GetValue={() => { - let field = props.doc.Get(props.fieldKey); - if (field && field instanceof Field) { - return field.ToScriptString(); - } - return field || ""; - }} SetValue={(value: string) => { - let script = CompileScript(value); - if (!script.compiled) { - return false; - } - let field = script(); - if (field instanceof Field) { - props.doc.Set(props.fieldKey, field); - return true; - } else { - let dataField = ToField(field); - if (dataField) { - props.doc.Set(props.fieldKey, dataField); - return true; - } - } - return false; - }}></EditableView> + <div onPointerDown={onRowDown} ref={reference}> + <EditableView contents={contents} + height={36} GetValue={() => { + let field = props.doc.Get(props.fieldKey); + if (field && field instanceof Field) { + return field.ToScriptString(); + } + return field || ""; + }} SetValue={(value: string) => { + let script = CompileScript(value); + if (!script.compiled) { + return false; + } + let field = script(); + if (field instanceof Field) { + props.doc.Set(props.fieldKey, field); + return true; + } else { + let dataField = ToField(field); + if (dataField) { + props.doc.Set(props.fieldKey, dataField); + return true; + } + } + return false; + }}></EditableView></div> ) } @@ -91,21 +120,49 @@ export class CollectionSchemaView extends CollectionViewBase { }; } + _startSplitPercent = 0; @action onDividerMove = (e: PointerEvent): void => { let nativeWidth = this._mainCont.current!.getBoundingClientRect(); this._splitPercentage = Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100); } + @action onDividerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onDividerMove); document.removeEventListener('pointerup', this.onDividerUp); + if (this._startSplitPercent == this._splitPercentage) { + this._splitPercentage = this._splitPercentage == 1 ? 66 : 100; + } } onDividerDown = (e: React.PointerEvent) => { + this._startSplitPercent = this._splitPercentage; e.stopPropagation(); e.preventDefault(); document.addEventListener("pointermove", this.onDividerMove); document.addEventListener('pointerup', this.onDividerUp); } + @action + onExpanderMove = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + } + @action + onExpanderUp = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + document.removeEventListener("pointermove", this.onExpanderMove); + document.removeEventListener('pointerup', this.onExpanderUp); + if (this._startSplitPercent == this._splitPercentage) { + this._splitPercentage = this._splitPercentage == 100 ? 66 : 100; + } + } + onExpanderDown = (e: React.PointerEvent) => { + this._startSplitPercent = this._splitPercentage; + e.stopPropagation(); + e.preventDefault(); + document.addEventListener("pointermove", this.onExpanderMove); + document.addEventListener('pointerup', this.onExpanderUp); + } onPointerDown = (e: React.PointerEvent) => { // if (e.button === 2 && this.active) { @@ -113,8 +170,10 @@ export class CollectionSchemaView extends CollectionViewBase { // e.preventDefault(); // } else { - if (e.buttons === 1 && this.props.active()) { - e.stopPropagation(); + if (e.buttons === 1) { + if (this.props.isSelected()) { + e.stopPropagation(); + } } } } @@ -155,6 +214,8 @@ export class CollectionSchemaView extends CollectionViewBase { } </Measure> ) + let handle = !this.props.active() ? (null) : ( + <div style={{ position: "absolute", height: "37px", width: "20px", zIndex: 20, right: 0, top: 0, background: "Black" }} onPointerDown={this.onExpanderDown} />); return ( <div onPointerDown={this.onPointerDown} ref={this._mainCont} className="collectionSchemaView-container" style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} > <Measure onResize={action((r: any) => { @@ -190,6 +251,7 @@ export class CollectionSchemaView extends CollectionViewBase { style={{ position: "relative", float: "left", width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)`, height: "100%" }}> {content} </div> + {handle} </div > ) } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 6d30cf365..83886f933 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -53,7 +53,13 @@ export class CollectionView extends React.Component<CollectionViewProps> { removeDocument = (doc: Document): boolean => { //TODO This won't create the field if it doesn't already exist const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array<Document>()) - let index = value.indexOf(doc); + let index = -1; + for (let i = 0; i < value.length; i++) { + if (value[i].Id == doc.Id) { + index = i; + break; + } + } if (index !== -1) { value.splice(index, 1) diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index e53485183..217536e2b 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -44,12 +44,16 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps> @undoBatch @action protected drop(e: Event, de: DragManager.DropEvent) { - const doc: DocumentView = de.data["document"]; - if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this.props.CollectionView) { - if (doc.props.RemoveDocument) { - doc.props.RemoveDocument(doc.props.Document); + const docView: DocumentView = de.data["documentView"]; + const doc: Document = de.data["document"]; + if (docView && docView.props.ContainingCollectionView && docView.props.ContainingCollectionView !== this.props.CollectionView) { + if (docView.props.RemoveDocument) { + docView.props.RemoveDocument(docView.props.Document); } - this.props.addDocument(doc.props.Document); + this.props.addDocument(docView.props.Document); + } else if (doc) { + this.props.removeDocument(doc); + this.props.addDocument(doc); } e.stopPropagation(); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 212697442..6fe78daee 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -124,7 +124,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { this._contextMenuCanOpen = false; const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); let dragData: { [id: string]: any } = {}; - dragData["document"] = this; + dragData["documentView"] = this; dragData["xOffset"] = e.x - left; dragData["yOffset"] = e.y - top; DragManager.StartDrag(this._mainCont.current, dragData, { |