diff options
| author | aidahosa1 <aisosa_idahosa@brown.edu> | 2024-03-18 13:39:34 -0400 |
|---|---|---|
| committer | aidahosa1 <aisosa_idahosa@brown.edu> | 2024-04-04 04:24:18 -0400 |
| commit | e0641c3175bc7cf53dea924524e51f1eefa6a8b1 (patch) | |
| tree | 5fae28b6ad2627c7c0f50f7d3a1543fb66cd524e /src/client/views/collections/CollectionCardDeckView.tsx | |
| parent | b949608ff69fb66c30bbed439b1c37f8fffd2333 (diff) | |
the lack of pushing is astounding actually
Diffstat (limited to 'src/client/views/collections/CollectionCardDeckView.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionCardDeckView.tsx | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx new file mode 100644 index 000000000..feb9e61cc --- /dev/null +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -0,0 +1,164 @@ +import { action, computed, IReactionDisposer, makeObservable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Doc, DocListCast } from '../../../fields/Doc'; +import { ScriptField } from '../../../fields/ScriptField'; +import { NumCast, StrCast } from '../../../fields/Types'; +import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils'; +import { DocUtils } from '../../documents/Documents'; +import { SelectionManager } from '../../util/SelectionManager'; +import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { OpenWhere } from '../nodes/DocumentView'; +import { computePassLayout, computeStarburstLayout, computeCardDeckLayout } from './collectionFreeForm'; +import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; +import './CollectionPileView.scss'; +import { CollectionSubView } from './CollectionSubView'; +import { dropActionType } from '../../util/DragManager'; + +@observer +export class CollectionCardView extends CollectionSubView() { + _originalChrome: any = ''; + _disposers: { [name: string]: IReactionDisposer } = {}; + + constructor(props: any) { + super(props); + makeObservable(this); + } + + componentDidMount() { + if (this.layoutEngine() !== computePassLayout.name && this.layoutEngine() !== computeCardDeckLayout.name) { + this.Document._freeform_cardEngine = computePassLayout.name; + } + this._originalChrome = this.layoutDoc._chromeHidden; + this.layoutDoc._chromeHidden = true; + } + componentWillUnmount() { + this.layoutDoc._chromeHidden = this._originalChrome; + Object.values(this._disposers).forEach(disposer => disposer?.()); + } + + layoutEngine = () => StrCast(this.Document._freeform_cardEngine); + + @undoBatch + addCardDoc = (doc: Doc | Doc[]) => { + (doc instanceof Doc ? [doc] : doc).map(d => DocUtils.iconify(d)); + return this._props.addDocument?.(doc) || false; + }; + + @undoBatch + removeCardDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { + (doc instanceof Doc ? [doc] : doc).forEach(d => Doc.deiconifyView(d)); + const ret = this._props.moveDocument?.(doc, targetCollection, addDoc) || false; + if (ret && !DocListCast(this.dataDoc[this.fieldKey ?? 'data']).length) this.DocumentView?.()._props.removeDocument?.(this.Document); + return ret; + }; + + @computed get toggleIcon() { + return ScriptField.MakeScript('documentView.iconify()', { documentView: 'any' }); + } + @computed get contentEvents() { + const isCard = this.layoutEngine() === computeCardDeckLayout.name; + return this._props.isContentActive() && isCard ? undefined : 'none'; + } + + // returns the contents of the cardSpread in a CollectionFreeFormView + @computed get contents() { + return ( + <div className="collectionPileView-innards" style={{ pointerEvents: this.contentEvents }}> + <CollectionFreeFormView + {...this._props} // + layoutEngine={this.layoutEngine} + addDocument={this.addCardDoc} + moveDocument={this.removeCardDoc} + // pile children never have their contents active, but will be document active whenever the entire pile is. + childContentsActive={returnFalse} + childDocumentsActive={this._props.isDocumentActive} + childDragAction={dropActionType.move} + childClickScript={this.toggleIcon} + /> + </div> + ); + } + + // // toggles the pileup between starburst to compact + // toggleStarburst = action(() => { + // this.layoutDoc._freeform_scale = undefined; + // if (this.layoutEngine() === computeStarburstLayout.name) { + // if (NumCast(this.layoutDoc._width) !== NumCast(this.Document._starburstDiameter, 500)) { + // this.Document._starburstDiameter = NumCast(this.layoutDoc._width); + // } + // const defaultSize = 110; + // this.Document.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width) / 2 - NumCast(this.layoutDoc._freeform_pileWidth, defaultSize) / 2; + // this.Document.y = NumCast(this.Document.y) + NumCast(this.layoutDoc._height) / 2 - NumCast(this.layoutDoc._freeform_pileHeight, defaultSize) / 2; + // this.layoutDoc._width = NumCast(this.layoutDoc._freeform_pileWidth, defaultSize); + // this.layoutDoc._height = NumCast(this.layoutDoc._freeform_pileHeight, defaultSize); + // DocUtils.pileup(this.childDocs, undefined, undefined, NumCast(this.layoutDoc._width) / 2, false); + // this.layoutDoc._freeform_panX = 0; + // this.layoutDoc._freeform_panY = -10; + // this.Document._freeform_pileEngine = computePassLayout.name; + // } else { + // const defaultSize = NumCast(this.Document._starburstDiameter, 400); + // this.Document.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width) / 2 - defaultSize / 2; + // this.Document.y = NumCast(this.Document.y) + NumCast(this.layoutDoc._height) / 2 - defaultSize / 2; + // this.layoutDoc._freeform_pileWidth = NumCast(this.layoutDoc._width); + // this.layoutDoc._freeform_pileHeight = NumCast(this.layoutDoc._height); + // this.layoutDoc._freeform_panX = this.layoutDoc._freeform_panY = 0; + // this.layoutDoc._width = this.layoutDoc._height = defaultSize; + // this.layoutDoc.background; + // this.Document._freeform_pileEngine = computeStarburstLayout.name; + // } + // }); + + // for dragging documents out of the pileup view + _undoBatch: UndoManager.Batch | undefined; + pointerDown = (e: React.PointerEvent) => { + let dist = 0; + 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, OpenWhere.inParentFromScreen) && (this._props.removeDocument?.(doc) || false); + dist = 0; + } + } + return false; + }, + () => { + this._undoBatch?.end(); + this._undoBatch = undefined; + }, + emptyFunction, + e.shiftKey && this.layoutEngine() === computePassLayout.name, + this.layoutEngine() === computePassLayout.name && e.shiftKey + ); // this sets _doubleTap + }; + + // onClick for toggling the pileup view + // @undoBatch + // onClick = (e: React.MouseEvent) => { + // if (e.button === 0) { + // SelectionManager.DeselectAll(); + // this.toggleStarburst(); + // e.stopPropagation(); + // } + // }; + + render() { + return ( + <div className={`collectionPileView`} + // onClick={this.onClick} + onPointerDown={this.pointerDown} style={{ width: this._props.PanelWidth(), height: '100%' }}> + {this.contents} + </div> + ); + } +} |
