diff options
Diffstat (limited to 'src/client/views/DocumentDecorations.tsx')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 209 |
1 files changed, 103 insertions, 106 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index cc5b754f0..693d6ec55 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,32 +1,34 @@ import { action, computed, observable, runInAction, untracked, reaction } from "mobx"; import { observer } from "mobx-react"; -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 { Document } from "../../fields/Document"; import { emptyFunction, Utils } 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 { DocumentView } from "./nodes/DocumentView"; +import { DocumentView, PositionDocument } from "./nodes/DocumentView"; import { LinkMenu } from "./nodes/LinkMenu"; import { TemplateMenu } from "./TemplateMenu"; import React = require("react"); import { Template, Templates } from "./Templates"; import { CompileScript } from "../util/Scripting"; import { IconBox } from "./nodes/IconBox"; -import { FieldValue, Field } from "../../fields/Field"; -import { Documents } from "../documents/Documents"; +import { Cast, FieldValue, NumCast, StrCast } from "../../new_fields/Types"; +import { Doc, FieldResult } from "../../new_fields/Doc"; +import { listSpec } from "../../new_fields/Schema"; +import { Docs } from "../documents/Documents"; +import { List } from "../../new_fields/List"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; import { faLink } from '@fortawesome/free-solid-svg-icons'; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; +import { CollectionFreeFormView } from "./collections/collectionFreeForm/CollectionFreeFormView"; +import { CollectionView } from "./collections/CollectionView"; +import { createCipher } from "crypto"; +import { FieldView } from "./nodes/FieldView"; library.add(faLink); @@ -43,44 +45,44 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> private _linkerButton = React.createRef<HTMLDivElement>(); private _downX = 0; private _downY = 0; + private _iconDoc?: Doc = undefined; @observable private _minimizedX = 0; @observable private _minimizedY = 0; @observable private _title: string = ""; @observable private _edtingTitle = false; - @observable private _fieldKey: Key = KeyStore.Title; + @observable private _fieldKey = "title"; @observable private _hidden = false; @observable private _opacity = 1; - @observable private _iconifying = false; + @observable private _removeIcon = false; @observable public Interacting = false; constructor(props: Readonly<{}>) { super(props); DocumentDecorations.Instance = this; this.keyinput = React.createRef(); - reaction(() => SelectionManager.SelectedDocuments().slice(), (docs) => docs.length === 0 && (this._edtingTitle = false)); + reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this._edtingTitle = false); } - @action titleChanged = (event: any) => { this._title = event.target.value; } - @action titleBlur = () => { this._edtingTitle = false; } + @action titleChanged = (event: any) => { this._title = event.target.value; }; + @action titleBlur = () => { this._edtingTitle = false; }; @action titleEntered = (e: any) => { var key = e.keyCode || e.which; // enter pressed if (key === 13) { var text = e.target.value; if (text[0] === '#') { - let command = text.slice(1, text.length); - this._fieldKey = new Key(command); + this._fieldKey = text.slice(1, text.length); this._title = this.selectionTitle; } else { if (SelectionManager.SelectedDocuments().length > 0) { - let field = SelectionManager.SelectedDocuments()[0].props.Document.Get(this._fieldKey); - if (field instanceof NumberField) { + let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey]; + if (typeof field === "number") { SelectionManager.SelectedDocuments().forEach(d => - d.props.Document.SetNumber(this._fieldKey, +this._title)); - } else if (field instanceof TextField || true) { + d.props.Document[this._fieldKey] = +this._title); + } else { SelectionManager.SelectedDocuments().forEach(d => - d.props.Document.SetText(this._fieldKey, this._title)); + d.props.Document[this._fieldKey] = this._title); } } } @@ -147,7 +149,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); dragData.xOffset = xoff; dragData.yOffset = yoff; - dragData.aliasOnDrop = false; dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument; this.Interacting = true; this._hidden = true; @@ -198,9 +199,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @action onMinimizeDown = (e: React.PointerEvent): void => { e.stopPropagation(); + this._iconDoc = undefined; if (e.button === 0) { this._downX = e.pageX; this._downY = e.pageY; + this._removeIcon = false; let selDoc = SelectionManager.SelectedDocuments()[0]; let selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); this._minimizedX = selDocPos[0] + 12; @@ -223,41 +226,15 @@ 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 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<Document | undefined> => { - let doc = docView.props.Document; - let iconDoc = 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))); - if (SelectionManager.SelectedDocuments()[0].props.addDocument !== undefined) - SelectionManager.SelectedDocuments()[0].props.addDocument!(iconDoc!); - return iconDoc; + if (selectedDocs.length > 1) { + this._iconDoc = this._iconDoc ? this._iconDoc : this.createIcon(SelectionManager.SelectedDocuments(), CollectionView.LayoutString()); + this.moveIconDoc(this._iconDoc); + } else { + this.getIconDoc(selectedDocs[0]).then(icon => icon && this.moveIconDoc(this._iconDoc = icon)); + } + this._removeIcon = snapped; + } } @action onMinimizeUp = (e: PointerEvent): void => { @@ -266,34 +243,52 @@ 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 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)); - minDoc.SetNumber(KeyStore.Y, minDocs[0].GetNumber(KeyStore.Y, 0)); - minDoc.SetData(KeyStore.LinkTags, minDocs, ListField); - if (this._iconifying && selectedDocs[0].props.removeDocument) { - selectedDocs[0].props.removeDocument(minDoc); - (minDoc.Get(KeyStore.MaximizedDoc, false) as Document)!.Set(KeyStore.MinimizedDoc, undefined); - } - }); - runInAction(() => this._minimizedX = this._minimizedY = 0); - if (!this._iconifying) selectedDocs[0].props.toggleMinimized(); - this._iconifying = false; - }); + if (this._iconDoc && selectedDocs.length === 1 && this._removeIcon) { + selectedDocs[0].props.removeDocument && selectedDocs[0].props.removeDocument(this._iconDoc); + } + !this._removeIcon && selectedDocs.length === 1 && this.getIconDoc(selectedDocs[0]).then(icon => selectedDocs[0].props.toggleMinimized()); + this._removeIcon = false; } + runInAction(() => this._minimizedX = this._minimizedY = 0); } - moveIconDocs(selViews: DocumentView[], minDocSet?: FieldValue<Field>[]) { - selViews.map(selDoc => { - let minDoc = selDoc.props.Document.Get(KeyStore.MinimizedDoc); - if (minDoc instanceof Document) { - let zoom = selDoc.props.Document.GetNumber(KeyStore.ZoomBasis, 1); - let where = (selDoc.props.ScreenToLocalTransform()).scale(selDoc.props.ContentScaling()).scale(1 / zoom). - transformPoint(this._minimizedX - 12, this._minimizedY - 12); - minDoc.SetNumber(KeyStore.X, where[0] + selDoc.props.Document.GetNumber(KeyStore.X, 0)); - minDoc.SetNumber(KeyStore.Y, where[1] + selDoc.props.Document.GetNumber(KeyStore.Y, 0)); - } - }); + + @action createIcon = (selected: DocumentView[], layoutString: string): Doc => { + let doc = selected[0].props.Document; + let iconDoc = Docs.IconDocument(layoutString); + iconDoc.isButton = true; + iconDoc.title = selected.length > 1 ? "ICONset" : "ICON" + StrCast(doc.title); + iconDoc.labelField = this._fieldKey; + iconDoc[this._fieldKey] = selected.length > 1 ? "collection" : undefined; + iconDoc.isMinimized = false; + iconDoc.width = Number(MINIMIZED_ICON_SIZE); + iconDoc.height = Number(MINIMIZED_ICON_SIZE); + iconDoc.x = NumCast(doc.x); + iconDoc.y = NumCast(doc.y) - 24; + iconDoc.maximizedDocs = new List<Doc>(selected.map(s => s.props.Document)); + doc.minimizedDoc = iconDoc; + selected[0].props.addDocument && selected[0].props.addDocument(iconDoc, false); + return iconDoc; + } + @action + public getIconDoc = async (docView: DocumentView): Promise<Doc | undefined> => { + let doc = docView.props.Document; + let iconDoc: Doc | undefined = await Cast(doc.minimizedDoc, Doc); + if (!iconDoc) { + const layout = StrCast(doc.backgroundLayout, StrCast(doc.layout, FieldView.LayoutString(DocumentView))); + iconDoc = this.createIcon([docView], layout); + } + if (SelectionManager.SelectedDocuments()[0].props.addDocument !== undefined) { + SelectionManager.SelectedDocuments()[0].props.addDocument!(iconDoc!); + } + return iconDoc; + } + moveIconDoc(iconDoc: Doc) { + let selView = SelectionManager.SelectedDocuments()[0]; + let zoom = NumCast(selView.props.Document.zoomBasis, 1); + let where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()).scale(1 / zoom). + transformPoint(this._minimizedX - 12, this._minimizedY - 12); + iconDoc.x = where[0] + NumCast(selView.props.Document.x); + iconDoc.y = where[1] + NumCast(selView.props.Document.y); } @action @@ -328,7 +323,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.removeEventListener("pointermove", this.onLinkerButtonMoved); document.removeEventListener("pointerup", this.onLinkerButtonUp); let selDoc = SelectionManager.SelectedDocuments()[0]; - let container = selDoc.props.ContainingCollectionView ? selDoc.props.ContainingCollectionView.props.Document.GetPrototype() : undefined; + let container = selDoc.props.ContainingCollectionView ? selDoc.props.ContainingCollectionView.props.Document.proto : undefined; let dragData = new DragManager.LinkDragData(selDoc.props.Document, container ? [container] : []); DragManager.StartLinkDrag(this._linkerButton.current, dragData, e.pageX, e.pageY, { handlers: { @@ -417,28 +412,30 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const rect = element.ContentDiv ? element.ContentDiv.getBoundingClientRect() : new DOMRect(); if (rect.width !== 0) { - let doc = element.props.Document; - let width = doc.GetNumber(KeyStore.Width, 0); - let nwidth = doc.GetNumber(KeyStore.NativeWidth, 0); - let nheight = doc.GetNumber(KeyStore.NativeHeight, 0); - let height = doc.GetNumber(KeyStore.Height, nwidth ? nheight / nwidth * width : 0); - let x = doc.GetOrCreate(KeyStore.X, NumberField); - let y = doc.GetOrCreate(KeyStore.Y, NumberField); + let doc = PositionDocument(element.props.Document); + let width = FieldValue(doc.width, 0); + let nwidth = FieldValue(doc.nativeWidth, 0); + let nheight = FieldValue(doc.nativeHeight, 0); + let height = FieldValue(doc.height, nwidth ? nheight / nwidth * width : 0); + let x = FieldValue(doc.x, 0); + let y = FieldValue(doc.y, 0); let scale = width / rect.width; let actualdW = Math.max(width + (dW * scale), 20); let actualdH = Math.max(height + (dH * scale), 20); - x.Data += dX * (actualdW - width); - y.Data += dY * (actualdH - height); - var nativeWidth = doc.GetNumber(KeyStore.NativeWidth, 0); - var nativeHeight = doc.GetNumber(KeyStore.NativeHeight, 0); + x += dX * (actualdW - width); + y += dY * (actualdH - height); + doc.x = x; + doc.y = y; + var nativeWidth = FieldValue(doc.nativeWidth, 0); + var nativeHeight = FieldValue(doc.nativeHeight, 0); if (nativeWidth > 0 && nativeHeight > 0) { if (Math.abs(dW) > Math.abs(dH)) { actualdH = nativeHeight / nativeWidth * actualdW; } else actualdW = nativeWidth / nativeHeight * actualdH; } - doc.SetNumber(KeyStore.Width, actualdW); - doc.SetNumber(KeyStore.Height, actualdH); + doc.width = actualdW; + doc.height = actualdH; } }); } @@ -460,12 +457,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @computed get selectionTitle(): string { if (SelectionManager.SelectedDocuments().length === 1) { - let field = SelectionManager.SelectedDocuments()[0].props.Document.Get(this._fieldKey); - if (field instanceof TextField) { - return (field).GetValue(); + let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey]; + if (typeof field === "string") { + return field; } - else if (field instanceof NumberField) { - return (field).GetValue().toString(); + else if (typeof field === "number") { + return field.toString(); } } else if (SelectionManager.SelectedDocuments().length > 1) { return "-multiple-"; @@ -488,21 +485,21 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } let minimizeIcon = ( <div className="documentDecorations-minimizeButton" onPointerDown={this.onMinimizeDown}> - {SelectionManager.SelectedDocuments().length == 1 ? IconBox.DocumentIcon(SelectionManager.SelectedDocuments()[0].props.Document.GetText(KeyStore.Layout, "...")) : "..."} + {SelectionManager.SelectedDocuments().length === 1 ? IconBox.DocumentIcon(StrCast(SelectionManager.SelectedDocuments()[0].props.Document.layout, "...")) : "..."} </div>); let linkButton = null; if (SelectionManager.SelectedDocuments().length > 0) { let selFirst = SelectionManager.SelectedDocuments()[0]; - let linkToSize = selFirst.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []).length; - let linkFromSize = selFirst.props.Document.GetData(KeyStore.LinkedFromDocs, ListField, []).length; + let linkToSize = Cast(selFirst.props.Document.linkedToDocs, listSpec(Doc), []).length; + let linkFromSize = Cast(selFirst.props.Document.linkedFromDocs, listSpec(Doc), []).length; let linkCount = linkToSize + linkFromSize; linkButton = (<Flyout anchorPoint={anchorPoints.RIGHT_TOP} content={<LinkMenu docView={selFirst} changeFlyout={this.changeFlyoutContent} />}> <div className={"linkButton-" + (linkCount ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} >{linkCount}</div> - </Flyout>); + </Flyout >); } let templates: Map<Template, boolean> = new Map(); @@ -511,7 +508,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let docTemps = doc.templates; let checked = false; docTemps.forEach(temp => { - if (template.Name === temp.Name) { + if (template.Layout === temp) { checked = true; } }); |