import { action, computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc, HeightSym, WidthSym } from "../../../fields/Doc"; import { NumCast, StrCast } from "../../../fields/Types"; import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView"; import "./CollectionPileView.scss"; import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); import { ScriptField } from "../../../fields/ScriptField"; @observer export class CollectionPileView extends CollectionSubView() { _originalChrome: any = ""; _disposers: { [name: string]: IReactionDisposer } = {}; componentDidMount() { if (this.layoutEngine() !== "pass" && this.layoutEngine() !== "starburst") { this.Document._pileLayoutEngine = "pass"; } this._originalChrome = this.layoutDoc._chromeHidden; this.layoutDoc._chromeHidden = true; // pileups are designed to go away when they are empty. this._disposers.selected = reaction(() => this.childDocs.length, (num) => !num && this.props.ContainingCollectionView?.removeDocument(this.props.Document)); } componentWillUnmount() { this.layoutDoc._chromeHidden = this._originalChrome; Object.values(this._disposers).forEach(disposer => disposer?.()); } layoutEngine = () => StrCast(this.Document._pileLayoutEngine); @undoBatch addPileDoc = (doc: Doc | Doc[]) => { (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); return this.props.addDocument?.(doc) || false; } @undoBatch removePileDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { (doc instanceof Doc ? [doc] : doc).map(undoBatch((d) => Doc.deiconifyView(d))); return this.props.moveDocument?.(doc, targetCollection, addDoc) || false; } toggleIcon = () => { return ScriptField.MakeScript("documentView.iconify()", { documentView: "any" }); } // returns the contents of the pileup in a CollectionFreeFormView @computed get contents() { const isStarburst = this.layoutEngine() === "starburst"; return
; } // toggles the pileup between starburst to compact toggleStarburst = action(() => { if (this.layoutEngine() === 'starburst') { const defaultSize = 110; this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - NumCast(this.layoutDoc._starburstPileWidth, defaultSize) / 2; this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - NumCast(this.layoutDoc._starburstPileHeight, defaultSize) / 2; this.layoutDoc._width = NumCast(this.layoutDoc._starburstPileWidth, defaultSize); this.layoutDoc._height = NumCast(this.layoutDoc._starburstPileHeight, defaultSize); DocUtils.pileup(this.childDocs, undefined, undefined, NumCast(this.layoutDoc._width) / 2, false); this.layoutDoc._panX = 0; this.layoutDoc._panY = -10; this.props.Document._pileLayoutEngine = 'pass'; } else { const defaultSize = 25; !this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 250); !this.layoutDoc._starburstDocScale && (this.layoutDoc._starburstDocScale = 2.5); if (this.layoutEngine() === 'pass') { this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - defaultSize / 2; this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - defaultSize / 2; this.layoutDoc._starburstPileWidth = this.layoutDoc[WidthSym](); this.layoutDoc._starburstPileHeight = this.layoutDoc[HeightSym](); } this.layoutDoc._panX = this.layoutDoc._panY = 0; this.layoutDoc._width = this.layoutDoc._height = defaultSize; this.props.Document._pileLayoutEngine = 'starburst'; } }); // for dragging documents out of the pileup view _undoBatch: UndoManager.Batch | undefined; pointerDown = (e: React.PointerEvent) => { let dist = 0; SnappingManager.SetIsDragging(true); setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { if (this.layoutEngine() === "pass" && this.childDocs.length && e.shiftKey) { dist += Math.sqrt(delta[0] * delta[0] + delta[1] * delta[1]); if (dist > 100) { if (!this._undoBatch) { this._undoBatch = UndoManager.StartBatch("layout pile"); } const doc = this.childDocs[0]; doc.x = e.clientX; doc.y = e.clientY; this.props.addDocTab(doc, "inParent") && (this.props.removeDocument?.(doc) || false); dist = 0; } } return false; }, () => { this._undoBatch?.end(); this._undoBatch = undefined; SnappingManager.SetIsDragging(false); }, emptyFunction, e.shiftKey && this.layoutEngine() === "pass", this.layoutEngine() === "pass" && e.shiftKey); // this sets _doubleTap } // onClick for toggling the pileup view @undoBatch @action onClick = (e: React.MouseEvent) => { if (e.button === 0) { SelectionManager.DeselectAll(); this.toggleStarburst(); e.stopPropagation(); } } render() { return
{this.contents}
; } }