aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
authoraidahosa1 <aisosa_idahosa@brown.edu>2024-03-18 13:39:34 -0400
committeraidahosa1 <aisosa_idahosa@brown.edu>2024-03-19 16:27:37 -0400
commit2d4abcd15acec7d07be5ed608d15b39f32a8fb44 (patch)
tree7719e68d87ad716ba7a27f457ef1cff77cf7aba2 /src/client/views/collections/collectionFreeForm
parentcec94dd9ced4f9af74189a4cffa0b113b5a0c4f1 (diff)
the lack of pushing is astounding actually
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx34
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx20
3 files changed, 55 insertions, 3 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index b8c0967c1..e972f44f1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -126,6 +126,40 @@ export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc
return normalizeResults(burstDiam, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]);
}
+export function computeCardDeckLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
+ const docMap = new Map<string, PoolData>();
+ const spreadWidth = Math.min(panelDim[0], childPairs.length * 50); // Total width of the spread
+ const startX = -(spreadWidth / 2); // Starting X position
+ const fanAngle = 5; // Angle in degrees for fanning out cards
+ const baseZIndex = 1000; // Base Z-index to ensure cards are stacked in order
+
+ childPairs.forEach(({ layout, data }, i) => {
+ const aspect = NumCast(layout._height) / NumCast(layout._width);
+ const docSize = Math.min(400, NumCast(layout._width)) * NumCast(pivotDoc._starburstDocScale, 1);
+ const posX = startX + (spreadWidth / childPairs.length) * i;
+ const posY = 0; // Adjust if you want to change the vertical alignment
+ const rotation = (i - (childPairs.length / 2)) * fanAngle; // Calculate rotation for fanning effect
+
+ docMap.set(layout[Id], {
+ x: posX,
+ y: posY,
+ width: docSize,
+ height: docSize * aspect,
+ zIndex: baseZIndex + i, // Increment Z-index for each card to stack them correctly
+ rotation: rotation, // Optional: Add this if you want to rotate elements for a fanned effect
+ pair: { layout, data },
+ replica: '',
+ color: 'white',
+ backgroundColor: 'white',
+ transition: 'all 0.3s',
+ });
+ });
+
+ // This is a placeholder for the divider object and may need to be adjusted based on actual usage
+ const divider = { type: 'div', color: 'transparent', x: -panelDim[0] / 2, y: -panelDim[1] / 2, width: 15, height: 15, payload: undefined };
+ return normalizeResults(panelDim, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]);
+}
+
export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
const docMap = new Map<string, PoolData>();
const fieldKey = 'data';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b2fb5848e..5fe61c1ab 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -49,7 +49,7 @@ import { CollectionSubView } from '../CollectionSubView';
import { TreeViewType } from '../CollectionTreeView';
import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid';
import { CollectionFreeFormInfoUI } from './CollectionFreeFormInfoUI';
-import { computePassLayout, computePivotLayout, computeStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from './CollectionFreeFormLayoutEngines';
+import { computePassLayout, computePivotLayout, computeStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult, computeCardDeckLayout } from './CollectionFreeFormLayoutEngines';
import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannableContents';
import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors';
import './CollectionFreeFormView.scss';
@@ -1381,6 +1381,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
case computeTimelineLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeTimelineLayout) };
case computePivotLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computePivotLayout) };
case computeStarburstLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeStarburstLayout) };
+ case computeCardDeckLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeCardDeckLayout) };
+
}
return { newPool, computedElementData: this.doFreeformLayout(newPool) };
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index b913e05ad..d0ac5f6db 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -383,6 +383,18 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
this.hideMarquee();
});
+ @undoBatch
+ spreadCards = action((e: KeyboardEvent | React.PointerEvent | undefined) => {
+ const selected = this.marqueeSelect(false);
+ SelectionManager.DeselectAll();
+ selected.forEach(d => this._props.removeDocument?.(d));
+ const newCollection = DocUtils.spreadCards(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2)!;
+ this._props.addDocument?.(newCollection);
+ this._props.selectDocuments([newCollection]);
+ MarqueeOptionsMenu.Instance.fadeOut(true);
+ this.hideMarquee();
+ });
+
/**
* This triggers the TabDocView.PinDoc method which is the universal method
* used to pin documents to the currently active presentation trail.
@@ -508,6 +520,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
@action
marqueeCommand = (e: KeyboardEvent) => {
+
if (this._commandExecuted || (e as any).propagationIsStopped) {
return;
}
@@ -518,7 +531,8 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
this.delete(e, e.key === 'h');
e.stopPropagation();
}
- if ('ctsSpg'.indexOf(e.key) !== -1) {
+ if ('ctsSpga'.indexOf(e.key) !== -1) {
+
this._commandExecuted = true;
e.stopPropagation();
e.preventDefault();
@@ -526,7 +540,9 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
if (e.key === 'g') this.collection(e, true);
if (e.key === 'c' || e.key === 't') this.collection(e);
if (e.key === 's' || e.key === 'S') this.summary(e);
- if (e.key === 'p') this.pileup(e);
+ if (e.key === 'p') this.pileup(e)
+ if (e.key === 'a') this.spreadCards(e);
+
this.cleanupInteractions(false);
}
if (e.key === 'r' || e.key === ' ') {