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}
;
}
}