aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionCardDeckView.tsx
diff options
context:
space:
mode:
authoraidahosa1 <aisosa_idahosa@brown.edu>2024-03-18 13:39:34 -0400
committeraidahosa1 <aisosa_idahosa@brown.edu>2024-04-04 04:24:18 -0400
commite0641c3175bc7cf53dea924524e51f1eefa6a8b1 (patch)
tree5fae28b6ad2627c7c0f50f7d3a1543fb66cd524e /src/client/views/collections/CollectionCardDeckView.tsx
parentb949608ff69fb66c30bbed439b1c37f8fffd2333 (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.tsx164
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>
+ );
+ }
+}