aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionPileView.tsx
blob: e3bcf2a21c0d5fbc11beaaa4577734735f209ec7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import { HeightSym, Opt, WidthSym } from "../../../fields/Doc";
import { ScriptField } from "../../../fields/ScriptField";
import { BoolCast, NumCast, StrCast } from "../../../fields/Types";
import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionPileView.scss";
import React = require("react");
import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../../Utils";
import { SelectionManager } from "../../util/SelectionManager";
import { UndoManager } from "../../util/UndoManager";
import { SnappingManager } from "../../util/SnappingManager";

@observer
export class CollectionPileView extends CollectionSubView(doc => doc) {
    _lastTap = 0;
    _doubleTap: boolean | undefined = false;
    _originalChrome: string = "";
    @observable _contentsActive = true;
    @observable _layoutEngine = "pass";
    @observable _collapsed: boolean = false;
    @observable _childClickedScript: Opt<ScriptField>;
    componentDidMount() {
        this._originalChrome = StrCast(this.layoutDoc._chromeStatus);
        this.layoutDoc._chromeStatus = "disabled";
        this.layoutDoc.hideFilterView = true;
    }
    componentWillUnmount() {
        this.layoutDoc.hideFilterView = false;
        this.layoutDoc._chromeStatus = this._originalChrome;
    }

    layoutEngine = () => this._layoutEngine;

    @computed get contents() {
        return <div className="collectionPileView-innards" style={{
            width: "100%",
            pointerEvents: this.layoutEngine() !== "pass" && (this.props.active() || this.layoutEngine() === "starburst") ? undefined : "none"
        }} >
            <CollectionFreeFormView {...this.props} layoutEngine={this.layoutEngine} />
        </div>;
    }

    specificMenu = (e: React.MouseEvent) => {
        const layoutItems: ContextMenuProps[] = [];
        const doc = this.props.Document;

        ContextMenu.Instance.addItem({ description: "Options...", subitems: layoutItems, icon: "eye" });
    }

    toggleStarburst = action(() => {
        if (this._layoutEngine === 'starburst') {
            const defaultSize = 110;
            this.layoutDoc._overflow = undefined;
            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);
            this._layoutEngine = 'pass';
        } else {
            const defaultSize = 25;
            this.layoutDoc._overflow = 'visible';
            !this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 500);
            !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._width = this.layoutDoc._height = defaultSize;
            this._layoutEngine = 'starburst';
        }
    });

    _undoBatch: UndoManager.Batch | undefined;
    pointerDown = (e: React.PointerEvent) => {
        let dist = 0;
        SnappingManager.SetIsDragging(true);
        // this._lastTap should be set to 0, and this._doubleTap should be set to false in the class header
        setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => {
            if (this.layoutEngine() === "pass" && this.childDocs.length && this.props.isSelected(true)) {
                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);
                    dist = 0;
                }
            }
            return false;
        }, () => {
            this._undoBatch?.end();
            this._undoBatch = undefined;
            SnappingManager.SetIsDragging(false);
            if (!this.childDocs.length) {
                this.props.ContainingCollectionView?.removeDocument(this.props.Document);
            }
        }, emptyFunction, false, this.layoutEngine() === "pass" && this.props.isSelected(true)); // this sets _doubleTap
    }

    onClick = (e: React.MouseEvent) => {
        if (e.button === 0 && (this._doubleTap || this.layoutEngine() === "starburst")) {
            SelectionManager.DeselectAll();
            this.toggleStarburst();
            e.stopPropagation();
        }
        // else if (this.layoutEngine() === "pass") {
        //     runInAction(() => this._contentsActive = false);
        //     setTimeout(action(() => this._contentsActive = true), 300);
        // }
    }

    render() {

        return <div className={"collectionPileView"} onContextMenu={this.specificMenu} onClick={this.onClick} onPointerDown={this.pointerDown}
            style={{ width: this.props.PanelWidth(), height: `calc(100%  - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
            {this.contents}
        </div>;
    }
}