From cec94dd9ced4f9af74189a4cffa0b113b5a0c4f1 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Wed, 21 Feb 2024 17:45:46 -0500 Subject: options icon changed --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index fb709818c..7bc630bb8 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -959,7 +959,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent }); - !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' }); + !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'sliders' }); this._downX = this._downY = Number.NaN; }; -- cgit v1.2.3-70-g09d2 From 2d4abcd15acec7d07be5ed608d15b39f32a8fb44 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Mon, 18 Mar 2024 13:39:34 -0400 Subject: the lack of pushing is astounding actually --- src/client/documents/DocumentTypes.ts | 4 +- src/client/documents/Documents.ts | 47 ++++++ .../views/collections/CollectionCardDeckView.tsx | 164 +++++++++++++++++++++ src/client/views/collections/CollectionView.tsx | 5 + .../CollectionFreeFormLayoutEngines.tsx | 34 +++++ .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- .../collections/collectionFreeForm/MarqueeView.tsx | 20 ++- 7 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 src/client/views/collections/CollectionCardDeckView.tsx (limited to 'src') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 1123bcac9..209b34f91 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -62,5 +62,7 @@ export enum CollectionViewType { Pile = 'pileup', StackedTimeline = 'stacked timeline', NoteTaking = 'notetaking', - Calendar = 'calendar' + Calendar = 'calendar', + Card = 'card' + } diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1d7c73306..be382afe3 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1218,6 +1218,15 @@ export namespace Docs { ); } + export function CardDeckDocument(documents: Array, options: DocumentOptions, id?: string) { + return InstanceFromProto( + Prototypes.get(DocumentType.COL), + new List(documents), + { backgroundColor: 'transparent', dropAction: dropActionType.move, _forceActive: true, _freeform_noZoom: true, _freeform_noAutoPan: true, ...options, _type_collection: CollectionViewType.Card }, + id + ); + } + export function LinearDocument(documents: Array, options: DocumentOptions, id?: string) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Linear }, id); } @@ -1864,6 +1873,44 @@ export namespace DocUtils { return newCollection; } } + + export function spreadCards(docList: Doc[], x: number = 0, y: number = 0, spreadAngle: number = 30, radius: number = 100, create: boolean = true) { + const totalCards = docList.length; + const halfSpreadAngle = spreadAngle * 0.5; + const angleStep = spreadAngle / (totalCards - 1); + + runInAction(() => { + docList.forEach((d, i) => { + DocUtils.iconify(d); + const angle = (-halfSpreadAngle + angleStep * i) * (Math.PI / 180); // Convert degrees to radians + d.x = x + Math.cos(angle) * radius; + d.y = y + Math.sin(angle) * radius; + d.rotation = angle; // Assuming 'd.rotation' sets the rotation, adjust accordingly + d._timecodeToShow = undefined; + }); + }); + + if (create) { + const newCollection = Docs.Create.CardDeckDocument(docList, { + title: 'card-spread', + _freeform_noZoom: true, + x: x - radius, + y: y - radius, + _width: radius * 2, + _height: radius * 2, + dragWhenActive: true, + _layout_fitWidth: false + }); + // Adjust position based on the collection's dimensions if needed + newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - radius; + newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - radius; + newCollection._width = newCollection._height = radius * 2; + return newCollection; + } + } + + + export function makeIntoPortal(doc: Doc, layoutDoc: Doc, allLinks: Doc[]) { const portalLink = allLinks.find(d => d.link_anchor_1 === doc && d.link_relationship === 'portal to:portal from'); if (!portalLink) { 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 ( +
+ +
+ ); + } + + // // 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 ( +
+ {this.contents} +
+ ); + } +} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 18eb4dd1f..b7805bf3f 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -33,6 +33,8 @@ import { CollectionLinearView } from './collectionLinear'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; +import { CollectionCardView } from './CollectionCardDeckView'; + export interface CollectionViewProps extends React.PropsWithChildren { isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) isAnnotationOverlayScrollable?: boolean; // whether the annotation overlay can be vertically scrolled (just for tree views, currently) @@ -134,6 +136,9 @@ export class CollectionView extends ViewBoxAnnotatableComponent; case CollectionViewType.Time: return ; case CollectionViewType.Grid: return ; + case CollectionViewType.Card: return ; + + } }; 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, pivotDoc return normalizeResults(burstDiam, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]); } +export function computeCardDeckLayout(poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { + const docMap = new Map(); + 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, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { const docMap = new Map(); 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 { + 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 { + if (this._commandExecuted || (e as any).propagationIsStopped) { return; } @@ -518,7 +531,8 @@ export class MarqueeView extends ObservableReactComponent Date: Wed, 21 Feb 2024 17:45:46 -0500 Subject: options icon changed --- src/.DS_Store | Bin 10244 -> 10244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'src') diff --git a/src/.DS_Store b/src/.DS_Store index f8d745dbf..b464c99c8 100644 Binary files a/src/.DS_Store and b/src/.DS_Store differ -- cgit v1.2.3-70-g09d2 From 66f904921ef519e1b54cb013ea7fafc640ae3dc7 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Tue, 19 Mar 2024 16:21:34 -0400 Subject: working on implementing card logic --- src/client/documents/Documents.ts | 16 +- src/client/util/CurrentUserUtils.ts | 2 +- .../views/collections/CollectionCardDeckView.scss | 0 .../views/collections/CollectionCardDeckView.tsx | 281 +++++++++++---------- src/client/views/collections/CollectionMenu.tsx | 4 + .../CollectionFreeFormLayoutEngines.tsx | 61 ++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 +- 7 files changed, 198 insertions(+), 172 deletions(-) create mode 100644 src/client/views/collections/CollectionCardDeckView.scss (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index be382afe3..00a7ecd23 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1218,14 +1218,7 @@ export namespace Docs { ); } - export function CardDeckDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto( - Prototypes.get(DocumentType.COL), - new List(documents), - { backgroundColor: 'transparent', dropAction: dropActionType.move, _forceActive: true, _freeform_noZoom: true, _freeform_noAutoPan: true, ...options, _type_collection: CollectionViewType.Card }, - id - ); - } + export function LinearDocument(documents: Array, options: DocumentOptions, id?: string) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Linear }, id); @@ -1243,6 +1236,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Carousel3D }); } + export function CardDeckDocument(documents: Array, options: DocumentOptions, id?: string) { + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Card}); + } + export function SchemaDocument(schemaHeaders: SchemaHeaderField[], documents: Array, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaHeaders: new List(schemaHeaders), ...options, _type_collection: CollectionViewType.Schema }); } @@ -1875,6 +1872,7 @@ export namespace DocUtils { } export function spreadCards(docList: Doc[], x: number = 0, y: number = 0, spreadAngle: number = 30, radius: number = 100, create: boolean = true) { + console.log('spread cards'); const totalCards = docList.length; const halfSpreadAngle = spreadAngle * 0.5; const angleStep = spreadAngle / (totalCards - 1); @@ -1885,7 +1883,7 @@ export namespace DocUtils { const angle = (-halfSpreadAngle + angleStep * i) * (Math.PI / 180); // Convert degrees to radians d.x = x + Math.cos(angle) * radius; d.y = y + Math.sin(angle) * radius; - d.rotation = angle; // Assuming 'd.rotation' sets the rotation, adjust accordingly + d.rotation = angle; d._timecodeToShow = undefined; }); }); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 84a33500d..bb24d8215 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -785,7 +785,7 @@ pie title Minerals in my tap water CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn, CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel, CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map, - CollectionViewType.Grid, CollectionViewType.NoteTaking]), + CollectionViewType.Grid, CollectionViewType.NoteTaking, CollectionViewType.Card]), title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}}, { title: "Header", icon: "heading", toolTip: "Doc Titlebar Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'} }, diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index feb9e61cc..e35f7b421 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -1,164 +1,185 @@ -import { action, computed, IReactionDisposer, makeObservable } from 'mobx'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { Utils, emptyFunction, returnFalse, returnZero } from '../../../Utils'; 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 { Id } from '../../../fields/FieldSymbols'; +import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; +import { DocumentType } from '../../documents/DocumentTypes'; +import { DragManager } from '../../util/DragManager'; 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 { StyleProp } from '../StyleProvider'; +import { DocumentView } from '../nodes/DocumentView'; +import { FocusViewOptions } from '../nodes/FieldView'; +import './CollectionCarousel3DView.scss'; import { CollectionSubView } from './CollectionSubView'; -import { dropActionType } from '../../util/DragManager'; - +const { default: { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } } = require('../global/globalCssVariables.module.scss'); // prettier-ignore @observer export class CollectionCardView extends CollectionSubView() { - _originalChrome: any = ''; - _disposers: { [name: string]: IReactionDisposer } = {}; - + @computed get scrollSpeed() { + return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed + } 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; - } + private _dropDisposer?: DragManager.DragDropDisposer; + componentWillUnmount() { - this.layoutDoc._chromeHidden = this._originalChrome; - Object.values(this._disposers).forEach(disposer => disposer?.()); + this._dropDisposer?.(); } - 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; + protected createDashEventsTarget = (ele: HTMLDivElement | null) => { + this._dropDisposer?.(); + if (ele) { + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); + } }; - @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; + centerScale = Number(CAROUSEL3D_CENTER_SCALE); + panelWidth = () => this._props.PanelWidth() / 3; + panelHeight = () => this._props.PanelHeight() * Number(CAROUSEL3D_SIDE_SCALE); + onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); + isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); + isChildContentActive = () => (this.isContentActive() ? true : false); + childScreenToLocal = () => + this._props // document's left is the panel shifted by the doc's index * panelWidth/#docs. But it scales by centerScale around its center, so it's left moves left by the distance of the left from the center (panelwidth/2) * the scale delta (centerScale-1) + .ScreenToLocalTransform() // the top behaves the same way ecept it's shifted by the 'top' amount specified for the panel in css and then by the scale factor. + .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, -((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) + .scale(1 / this.centerScale); + + focus = (anchor: Doc, options: FocusViewOptions) => { + const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; + options.didMove = true; + const target = DocCast(anchor.annotationOn) ?? anchor; + const index = docs.indexOf(target); + index !== -1 && (this.layoutDoc._carousel_index = index); //if index is not -1, then assign index to this.layoutDoc._carousel_index + return undefined; }; - @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'; + + @computed get content() { + const currentIndex = NumCast(this.layoutDoc._carousel_index); + const displayDoc = (childPair: { layout: Doc; data: Doc }) => { + return ( + + ); + }; + + return this.childLayoutPairs.map((childPair, index) => { + return ( +
+ {displayDoc(childPair)} +
+ ); + }); } - // returns the contents of the cardSpread in a CollectionFreeFormView - @computed get contents() { + changeSlide = (direction: number) => { + SelectionManager.DeselectAll(); + this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + direction + this.childLayoutPairs.length) % this.childLayoutPairs.length; + }; + + onArrowClick = (direction: number) => { + this.changeSlide(direction); + !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = direction === 1 ? 'fwd' : 'back'); // while autoscroll is on, keep the other autoscroll button hidden + !this.layoutDoc.autoScrollOn && this.fadeScrollButton(); // keep pause button visible while autoscroll is on + }; + + interval?: number; + startAutoScroll = (direction: number) => { + this.interval = window.setInterval(() => { + this.changeSlide(direction); + }, this.scrollSpeed); + }; + + stopAutoScroll = () => { + window.clearInterval(this.interval); + this.interval = undefined; + this.fadeScrollButton(); + }; + + toggleAutoScroll = (direction: number) => { + this.layoutDoc.autoScrollOn = this.layoutDoc.autoScrollOn ? false : true; + this.layoutDoc.autoScrollOn ? this.startAutoScroll(direction) : this.stopAutoScroll(); + }; + + fadeScrollButton = () => { + window.setTimeout(() => { + !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = 'none'); //fade away after 1.5s if it's not clicked. + }, 1500); + }; + + @computed get buttons() { return ( -
- +
+
this.onArrowClick(-1)} /> +
this.onArrowClick(1)} /> + {/* {this.autoScrollButton} */}
); } - // // 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 - }; + @computed get autoScrollButton() { + const whichButton = this.layoutDoc.showScrollButton; + return ( + <> +
this.toggleAutoScroll(-1)}> + {this.layoutDoc.autoScrollOn ? : } +
+
this.toggleAutoScroll(1)}> + {this.layoutDoc.autoScrollOn ? : } +
+ + ); + } - // onClick for toggling the pileup view - // @undoBatch - // onClick = (e: React.MouseEvent) => { - // if (e.button === 0) { - // SelectionManager.DeselectAll(); - // this.toggleStarburst(); - // e.stopPropagation(); - // } - // }; + @computed get dots() { + return this.childLayoutPairs.map((_child, index) =>
(this.layoutDoc._carousel_index = index)} />); + } + @computed get translateX() { + const index = NumCast(this.layoutDoc._carousel_index); + return this.panelWidth() * (1 - index); + } render() { return ( -
- {this.contents} +
+
+ {this.content} +
+ {this.buttons} +
{this.dots}
); } + + } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 8729ef549..9d135eb3b 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -319,6 +319,10 @@ export class CollectionViewBaseChrome extends React.Component(); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index e972f44f1..b3ae382e3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -126,39 +126,40 @@ export function computeStarburstLayout(poolData: Map, pivotDoc return normalizeResults(burstDiam, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]); } -export function computeCardDeckLayout(poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { - const docMap = new Map(); - 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 +// export function computeCardDeckLayout(poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { +// console.log('hi'); +// const docMap = new Map(); +// 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 +// 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', - }); - }); +// docMap.set(layout[Id], { +// x: posX, +// y: posY, +// width: docSize, +// height: docSize * aspect, +// zIndex: baseZIndex + i, +// rotation: rotation, +// 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]); -} +// // 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, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { const docMap = new Map(); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5fe61c1ab..1514af809 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -49,7 +49,9 @@ import { CollectionSubView } from '../CollectionSubView'; import { TreeViewType } from '../CollectionTreeView'; import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid'; import { CollectionFreeFormInfoUI } from './CollectionFreeFormInfoUI'; -import { computePassLayout, computePivotLayout, computeStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult, computeCardDeckLayout } 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,7 +1383,7 @@ export class CollectionFreeFormView extends CollectionSubView Date: Wed, 20 Mar 2024 03:27:55 -0400 Subject: me vs pointer events who will win --- src/client/views/DocComponent.tsx | 2 +- .../views/collections/CollectionCardDeckView.tsx | 168 ++++++++++++--------- 2 files changed, 94 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 18e7ab12a..a7a9763ec 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -35,7 +35,7 @@ export interface ViewBoxInterface { addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; // add a document (used only by collections) removeDocument?: (doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean) => boolean; // add a document (used only by collections) select?: (ctrlKey: boolean, shiftKey: boolean) => void; - focus?: (textAnchor: Doc, options: FocusViewOptions) => Opt; + focus?: (textAnchor: Doc, options: FocusViewOptions) => Opt; viewTransition?: () => Opt; // duration of a view transition animation isAnyChildContentActive?: () => boolean; // is any child content of the document active onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index e35f7b421..778280215 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { computed, makeObservable } from 'mobx'; -import { observer } from 'mobx-react'; +import { computed, makeObservable, observable, action } from 'mobx'; +import { observer, } from 'mobx-react'; import * as React from 'react'; import { Utils, emptyFunction, returnFalse, returnZero } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; @@ -14,12 +14,31 @@ import { DocumentView } from '../nodes/DocumentView'; import { FocusViewOptions } from '../nodes/FieldView'; import './CollectionCarousel3DView.scss'; import { CollectionSubView } from './CollectionSubView'; +import { ScriptField } from '../../../fields/ScriptField'; + const { default: { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } } = require('../global/globalCssVariables.module.scss'); // prettier-ignore @observer export class CollectionCardView extends CollectionSubView() { - @computed get scrollSpeed() { - return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed - } + // @computed get scrollSpeed() { + // return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed + // } + + selectedNodeIndex = observable.box(-1); // -1 indicates no selection + + @action + setSelectedNodeIndex = (index: number) => { + console.log('hi'); + SelectionManager.DeselectAll(); + this.selectedNodeIndex.set(index); + }; + + @computed + get rotationDegree() { + return this.isChildContentActive() ? 30 : 0; // Rotate by 30 degrees if selected, otherwise no rotation +} + + + constructor(props: any) { super(props); makeObservable(this); @@ -39,17 +58,23 @@ export class CollectionCardView extends CollectionSubView() { }; centerScale = Number(CAROUSEL3D_CENTER_SCALE); - panelWidth = () => this._props.PanelWidth() / 3; - panelHeight = () => this._props.PanelHeight() * Number(CAROUSEL3D_SIDE_SCALE); + panelWidth = () => (this._props.PanelWidth()) / this.childLayoutPairs.length; + panelHeight = () => this.panelWidth() * 1.5; onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); + onChildClick = () => ScriptCast(this.rotate(3, 3)); isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => (this.isContentActive() ? true : false); + + //thid needs to be fixed childScreenToLocal = () => this._props // document's left is the panel shifted by the doc's index * panelWidth/#docs. But it scales by centerScale around its center, so it's left moves left by the distance of the left from the center (panelwidth/2) * the scale delta (centerScale-1) .ScreenToLocalTransform() // the top behaves the same way ecept it's shifted by the 'top' amount specified for the panel in css and then by the scale factor. - .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, -((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) - .scale(1 / this.centerScale); + // .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2,-((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) + .rotate(this.rotate(this.childLayoutPairs.length, Number(this.layoutDoc._carousel_index))) + // .scale(1 / this.centerScale); + + //literally doesnot do anythin focus = (anchor: Doc, options: FocusViewOptions) => { const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; @@ -60,15 +85,41 @@ export class CollectionCardView extends CollectionSubView() { return undefined; }; + rotate = (amCards: number, index: number) => { + + const possRotate = -30 + (index * (30/((amCards - (amCards%2))/2))); + + if (amCards%2 == 0 && possRotate==0){ + console.log('whaddup') + return possRotate + Math.abs(-30 + ((index-1) * (30/((amCards - 1)/2)))) + } + + return possRotate; + } + + // translateY = (amCards: number, index: number) => { + // // Assuming you want a default value when index > amCards/2 + // // Adjust the logic as necessary for your use case + // if (index <= amCards / 2) { + // return -((50 / ((amCards - (amCards % 2)) / 2)) * index); + // } else { + // // Return a default or calculated value for indices greater than amCards/2 + // // This is just an example; adjust the logic as needed + // return -((50 / ((amCards - (amCards % 2)) / 2)) * (amCards - index - 1)); + // } + // }; + @computed get content() { - const currentIndex = NumCast(this.layoutDoc._carousel_index); + // const currentIndex = NumCast(this.layoutDoc._carousel_index); + const amCards = this.childLayoutPairs.length; const displayDoc = (childPair: { layout: Doc; data: Doc }) => { return ( { + + const isSelected = this.selectedNodeIndex.get() === index; + const rotationDegree = isSelected ? 30 : 0; // Rotate selected node by 5 degrees, for example + + return ( -
+
this.setSelectedNodeIndex(index)} + + + + > + {/* {this.lol(childPair.data, index)} */} + + {displayDoc(childPair)} -
+
); }); } - changeSlide = (direction: number) => { - SelectionManager.DeselectAll(); - this.layoutDoc._carousel_index = (NumCast(this.layoutDoc._carousel_index) + direction + this.childLayoutPairs.length) % this.childLayoutPairs.length; - }; - - onArrowClick = (direction: number) => { - this.changeSlide(direction); - !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = direction === 1 ? 'fwd' : 'back'); // while autoscroll is on, keep the other autoscroll button hidden - !this.layoutDoc.autoScrollOn && this.fadeScrollButton(); // keep pause button visible while autoscroll is on - }; - - interval?: number; - startAutoScroll = (direction: number) => { - this.interval = window.setInterval(() => { - this.changeSlide(direction); - }, this.scrollSpeed); - }; + // lol = (d : Doc, index: number) => { + // if (SelectionManager.IsSelected(d)){ + // this.setSelectedNodeIndex(index); - stopAutoScroll = () => { - window.clearInterval(this.interval); - this.interval = undefined; - this.fadeScrollButton(); - }; - - toggleAutoScroll = (direction: number) => { - this.layoutDoc.autoScrollOn = this.layoutDoc.autoScrollOn ? false : true; - this.layoutDoc.autoScrollOn ? this.startAutoScroll(direction) : this.stopAutoScroll(); - }; + // } + // } - fadeScrollButton = () => { - window.setTimeout(() => { - !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = 'none'); //fade away after 1.5s if it's not clicked. - }, 1500); - }; - - @computed get buttons() { - return ( -
-
this.onArrowClick(-1)} /> -
this.onArrowClick(1)} /> - {/* {this.autoScrollButton} */} -
- ); - } - - @computed get autoScrollButton() { - const whichButton = this.layoutDoc.showScrollButton; - return ( - <> -
this.toggleAutoScroll(-1)}> - {this.layoutDoc.autoScrollOn ? : } -
-
this.toggleAutoScroll(1)}> - {this.layoutDoc.autoScrollOn ? : } -
- - ); - } - - @computed get dots() { - return this.childLayoutPairs.map((_child, index) =>
(this.layoutDoc._carousel_index = index)} />); - } @computed get translateX() { const index = NumCast(this.layoutDoc._carousel_index); return this.panelWidth() * (1 - index); @@ -172,11 +188,13 @@ export class CollectionCardView extends CollectionSubView() { background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor), color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color), }}> -
+
{this.content}
- {this.buttons} -
{this.dots}
+ {/* {this.buttons} +
{this.dots}
*/}
); } -- cgit v1.2.3-70-g09d2 From 9651484f331c39cb42257977cd4e234c71e74549 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Wed, 20 Mar 2024 14:14:02 -0400 Subject: figuring out how to find the doc wrapper thing --- .../views/collections/CollectionCardDeckView.scss | 19 ++++ .../views/collections/CollectionCardDeckView.tsx | 114 ++++++++++++++------- 2 files changed, 96 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index e69de29bb..b6d9ca202 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -0,0 +1,19 @@ +@import '../global/globalCssVariables.module.scss'; + +.collectionCardView-outer { + height: 100%; + position: relative; + background-color: white; + overflow: hidden; +} + +.card-wrapper { + display: flex; + position: absolute; + top: $CAROUSEL3D_TOP * 1%; + height: ($CAROUSEL3D_SIDE_SCALE * 100) * 1%; + align-items: center; + transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); +} + + diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 778280215..3b3c4a764 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -12,36 +12,69 @@ import { SelectionManager } from '../../util/SelectionManager'; import { StyleProp } from '../StyleProvider'; import { DocumentView } from '../nodes/DocumentView'; import { FocusViewOptions } from '../nodes/FieldView'; -import './CollectionCarousel3DView.scss'; +import './CollectionCardDeckView.scss'; import { CollectionSubView } from './CollectionSubView'; import { ScriptField } from '../../../fields/ScriptField'; +import { lengthToDegrees } from '@turf/turf'; -const { default: { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } } = require('../global/globalCssVariables.module.scss'); // prettier-ignore @observer export class CollectionCardView extends CollectionSubView() { - // @computed get scrollSpeed() { - // return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed - // } + + @observable selectedNodeIndex = -1; + + @observable hoveredNodeIndex = -1; + + @action + setHoveredNodeIndex = (index : number) => { + this.hoveredNodeIndex = index; + } - selectedNodeIndex = observable.box(-1); // -1 indicates no selection + translateHover = (index : number) => { + if (this.hoveredNodeIndex == index){ + return -50; + } + return 0; + } + + @action setSelectedNodeIndex = (index: number) => { - console.log('hi'); - SelectionManager.DeselectAll(); - this.selectedNodeIndex.set(index); + + const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + console.log("goodnight") + + if (SelectionManager.IsSelected(docs[index])){ + console.log("good mornings") + this.setSelectedNodeIndex(index); + } }; - @computed - get rotationDegree() { - return this.isChildContentActive() ? 30 : 0; // Rotate by 30 degrees if selected, otherwise no rotation -} + + isSelected = (index : number) => { + const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + + return SelectionManager.IsSelected(docs[index]) + + } + + // @computed + // rotationDegree = (index : number) => { + // const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + + // if (SelectionManager.IsSelected(docs[index])){ + // return 30; + // } + + // return 0; + // } constructor(props: any) { super(props); makeObservable(this); + // this.rotationDegree(7); } private _dropDisposer?: DragManager.DragDropDisposer; @@ -57,11 +90,10 @@ export class CollectionCardView extends CollectionSubView() { } }; - centerScale = Number(CAROUSEL3D_CENTER_SCALE); panelWidth = () => (this._props.PanelWidth()) / this.childLayoutPairs.length; panelHeight = () => this.panelWidth() * 1.5; onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); - onChildClick = () => ScriptCast(this.rotate(3, 3)); + // onChildClick = () => ScriptCast(this.rotate(3, 3)); isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => (this.isContentActive() ? true : false); @@ -75,15 +107,15 @@ export class CollectionCardView extends CollectionSubView() { //literally doesnot do anythin - focus = (anchor: Doc, options: FocusViewOptions) => { - const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); - if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; - options.didMove = true; - const target = DocCast(anchor.annotationOn) ?? anchor; - const index = docs.indexOf(target); - index !== -1 && (this.layoutDoc._carousel_index = index); //if index is not -1, then assign index to this.layoutDoc._carousel_index - return undefined; - }; + // focus = (anchor: Doc, options: FocusViewOptions) => { + // const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); + // if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; + // options.didMove = true; + // const target = DocCast(anchor.annotationOn) ?? anchor; + // const index = docs.indexOf(target); + // index !== -1 && (this.layoutDoc._carousel_index = index); //if index is not -1, then assign index to this.layoutDoc._carousel_index + // return undefined; + // }; rotate = (amCards: number, index: number) => { @@ -128,7 +160,7 @@ export class CollectionCardView extends CollectionSubView() { renderDepth={this._props.renderDepth + 1} LayoutTemplate={this._props.childLayoutTemplate} LayoutTemplateString={this._props.childLayoutString} - focus={this.focus} + // focus={this.focus} ScreenToLocalTransform={this.childScreenToLocal} //makes sure the box wrapper thing is in the right spot isContentActive={this.isChildContentActive} isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} @@ -140,20 +172,29 @@ export class CollectionCardView extends CollectionSubView() { return this.childLayoutPairs.map((childPair, index) => { - const isSelected = this.selectedNodeIndex.get() === index; - const rotationDegree = isSelected ? 30 : 0; // Rotate selected node by 5 degrees, for example - + const isSelected = this.isSelected(index); + console.log(index + "is select?: " + isSelected); + const isHovered = this.hoveredNodeIndex === index; return (
this.setSelectedNodeIndex(index)} + + + // onClick={() => this.setSelectedNodeIndex(index)} + + onMouseEnter={() => this.setHoveredNodeIndex(index)} + onMouseLeave={() => this.setHoveredNodeIndex(-1)} @@ -182,19 +223,18 @@ export class CollectionCardView extends CollectionSubView() { render() { return (
-
{this.content}
- {/* {this.buttons} -
{this.dots}
*/}
); } -- cgit v1.2.3-70-g09d2 From 1afb2e781187c31b3b0932349dc05238796179e0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 20 Mar 2024 16:09:22 -0400 Subject: fix for document decorations --- .../views/collections/CollectionCardDeckView.tsx | 127 +++++++++------------ 1 file changed, 55 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 3b3c4a764..460f74a61 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -1,62 +1,52 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { computed, makeObservable, observable, action } from 'mobx'; -import { observer, } from 'mobx-react'; +import { ObservableMap, action, computed, makeObservable, observable } from 'mobx'; +import { observer } from 'mobx-react'; import * as React from 'react'; -import { Utils, emptyFunction, returnFalse, returnZero } from '../../../Utils'; +import { Utils, returnZero } from '../../../Utils'; import { Doc, DocListCast } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; -import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; -import { DocumentType } from '../../documents/DocumentTypes'; +import { NumCast, ScriptCast } from '../../../fields/Types'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { StyleProp } from '../StyleProvider'; import { DocumentView } from '../nodes/DocumentView'; -import { FocusViewOptions } from '../nodes/FieldView'; import './CollectionCardDeckView.scss'; import { CollectionSubView } from './CollectionSubView'; -import { ScriptField } from '../../../fields/ScriptField'; -import { lengthToDegrees } from '@turf/turf'; +import { Transform } from '../../util/Transform'; @observer export class CollectionCardView extends CollectionSubView() { - @observable selectedNodeIndex = -1; @observable hoveredNodeIndex = -1; @action - setHoveredNodeIndex = (index : number) => { + setHoveredNodeIndex = (index: number) => { this.hoveredNodeIndex = index; - } + }; - translateHover = (index : number) => { - if (this.hoveredNodeIndex == index){ + translateHover = (index: number) => { + if (this.hoveredNodeIndex == index) { return -50; } return 0; - } - - + }; @action setSelectedNodeIndex = (index: number) => { - const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); - console.log("goodnight") + console.log('goodnight'); - if (SelectionManager.IsSelected(docs[index])){ - console.log("good mornings") + if (SelectionManager.IsSelected(docs[index])) { + console.log('good mornings'); this.setSelectedNodeIndex(index); } }; - - isSelected = (index : number) => { + isSelected = (index: number) => { const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); - return SelectionManager.IsSelected(docs[index]) - - } + return SelectionManager.IsSelected(docs[index]); + }; // @computed // rotationDegree = (index : number) => { @@ -69,8 +59,6 @@ export class CollectionCardView extends CollectionSubView() { // return 0; // } - - constructor(props: any) { super(props); makeObservable(this); @@ -90,21 +78,20 @@ export class CollectionCardView extends CollectionSubView() { } }; - panelWidth = () => (this._props.PanelWidth()) / this.childLayoutPairs.length; + panelWidth = () => this._props.PanelWidth() / this.childLayoutPairs.length; panelHeight = () => this.panelWidth() * 1.5; onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); // onChildClick = () => ScriptCast(this.rotate(3, 3)); isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => (this.isContentActive() ? true : false); - + //thid needs to be fixed childScreenToLocal = () => this._props // document's left is the panel shifted by the doc's index * panelWidth/#docs. But it scales by centerScale around its center, so it's left moves left by the distance of the left from the center (panelwidth/2) * the scale delta (centerScale-1) .ScreenToLocalTransform() // the top behaves the same way ecept it's shifted by the 'top' amount specified for the panel in css and then by the scale factor. // .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2,-((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) - .rotate(this.rotate(this.childLayoutPairs.length, Number(this.layoutDoc._carousel_index))) - // .scale(1 / this.centerScale); - + .rotate(this.rotate(this.childLayoutPairs.length, Number(this.layoutDoc._carousel_index))); + // .scale(1 / this.centerScale); //literally doesnot do anythin // focus = (anchor: Doc, options: FocusViewOptions) => { @@ -118,16 +105,15 @@ export class CollectionCardView extends CollectionSubView() { // }; rotate = (amCards: number, index: number) => { + const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2)); - const possRotate = -30 + (index * (30/((amCards - (amCards%2))/2))); - - if (amCards%2 == 0 && possRotate==0){ - console.log('whaddup') - return possRotate + Math.abs(-30 + ((index-1) * (30/((amCards - 1)/2)))) + if (amCards % 2 == 0 && possRotate == 0) { + console.log('whaddup'); + return possRotate + Math.abs(-30 + (index - 1) * (30 / ((amCards - 1) / 2))); } - - return possRotate; - } + + return possRotate; + }; // translateY = (amCards: number, index: number) => { // // Assuming you want a default value when index > amCards/2 @@ -140,15 +126,16 @@ export class CollectionCardView extends CollectionSubView() { // return -((50 / ((amCards - (amCards % 2)) / 2)) * (amCards - index - 1)); // } // }; + @observable docRefs = new ObservableMap(); - @computed get content() { // const currentIndex = NumCast(this.layoutDoc._carousel_index); const amCards = this.childLayoutPairs.length; - const displayDoc = (childPair: { layout: Doc; data: Doc }) => { + const displayDoc = (childPair: { layout: Doc; data: Doc }, screenToLocalTransform: () => Transform) => { return ( r?.ContentDiv && this.docRefs.set(childPair.layout, r))} Document={childPair.layout} TemplateDataDocument={childPair.data} // onClickScript={this.toggleIcon} @@ -161,7 +148,7 @@ export class CollectionCardView extends CollectionSubView() { LayoutTemplate={this._props.childLayoutTemplate} LayoutTemplateString={this._props.childLayoutString} // focus={this.focus} - ScreenToLocalTransform={this.childScreenToLocal} //makes sure the box wrapper thing is in the right spot + ScreenToLocalTransform={screenToLocalTransform} //makes sure the box wrapper thing is in the right spot isContentActive={this.isChildContentActive} isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} PanelWidth={this.panelWidth} @@ -171,39 +158,37 @@ export class CollectionCardView extends CollectionSubView() { }; return this.childLayoutPairs.map((childPair, index) => { - const isSelected = this.isSelected(index); - console.log(index + "is select?: " + isSelected); + console.log(index + 'is select?: ' + isSelected); const isHovered = this.hoveredNodeIndex === index; + const childScreenToLocal = () => { + const dref = this.docRefs.get(childPair.layout); + const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv); + // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off + return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(1 / (isSelected ? 1.25 : 1)).rotate(!isSelected ? -this.rotate(amCards, index) : 0); + }; + return ( -
this.setSelectedNodeIndex(index)} - - - - }} - - - // onClick={() => this.setSelectedNodeIndex(index)} - - onMouseEnter={() => this.setHoveredNodeIndex(index)} - onMouseLeave={() => this.setHoveredNodeIndex(-1)} - - - - > + onMouseEnter={() => this.setHoveredNodeIndex(index)} + onMouseLeave={() => this.setHoveredNodeIndex(-1)}> {/* {this.lol(childPair.data, index)} */} - - {displayDoc(childPair)} -
+ {displayDoc(childPair, childScreenToLocal)} +
); }); } @@ -229,15 +214,13 @@ export class CollectionCardView extends CollectionSubView() { background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor), color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color), }}> -
{this.content}
); } - - } -- cgit v1.2.3-70-g09d2 From 09724c4a5649234d3ba857c0af196e74cb7ba0d2 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Thu, 21 Mar 2024 03:29:26 -0400 Subject: . --- .../views/collections/CollectionCardDeckView.scss | 10 ++ .../views/collections/CollectionCardDeckView.tsx | 110 ++++++++++++--------- 2 files changed, 71 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index b6d9ca202..95a9b658c 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -16,4 +16,14 @@ transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); } +.card-item-active, .card-item{ + transition: transform 0.3s ease-in-out; +} + + +.card-item-active{ + position: absolute; + z-index: 100; +} + diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 460f74a61..a4d0d1862 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -12,6 +12,7 @@ import { DocumentView } from '../nodes/DocumentView'; import './CollectionCardDeckView.scss'; import { CollectionSubView } from './CollectionSubView'; import { Transform } from '../../util/Transform'; +import { indexes } from 'd3'; @observer export class CollectionCardView extends CollectionSubView() { @@ -21,11 +22,13 @@ export class CollectionCardView extends CollectionSubView() { @action setHoveredNodeIndex = (index: number) => { + if (!this.isSelected(index)){ this.hoveredNodeIndex = index; + } }; - translateHover = (index: number) => { - if (this.hoveredNodeIndex == index) { + translateHover = (index: number): number => { + if (this.hoveredNodeIndex == index && !this.isSelected(index)) { return -50; } return 0; @@ -42,22 +45,17 @@ export class CollectionCardView extends CollectionSubView() { } }; - isSelected = (index: number) => { + isSelected = (index: number): boolean => { const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); return SelectionManager.IsSelected(docs[index]); }; - // @computed - // rotationDegree = (index : number) => { - // const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); - - // if (SelectionManager.IsSelected(docs[index])){ - // return 30; - // } + inactiveDocs = () => { + const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); - // return 0; - // } + return docs.filter(d => !SelectionManager.IsSelected(d)); + } constructor(props: any) { super(props); @@ -81,28 +79,9 @@ export class CollectionCardView extends CollectionSubView() { panelWidth = () => this._props.PanelWidth() / this.childLayoutPairs.length; panelHeight = () => this.panelWidth() * 1.5; onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); - // onChildClick = () => ScriptCast(this.rotate(3, 3)); isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => (this.isContentActive() ? true : false); - //thid needs to be fixed - childScreenToLocal = () => - this._props // document's left is the panel shifted by the doc's index * panelWidth/#docs. But it scales by centerScale around its center, so it's left moves left by the distance of the left from the center (panelwidth/2) * the scale delta (centerScale-1) - .ScreenToLocalTransform() // the top behaves the same way ecept it's shifted by the 'top' amount specified for the panel in css and then by the scale factor. - // .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2,-((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2) - .rotate(this.rotate(this.childLayoutPairs.length, Number(this.layoutDoc._carousel_index))); - // .scale(1 / this.centerScale); - - //literally doesnot do anythin - // focus = (anchor: Doc, options: FocusViewOptions) => { - // const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); - // if (anchor.type !== DocumentType.CONFIG && !docs.includes(anchor)) return; - // options.didMove = true; - // const target = DocCast(anchor.annotationOn) ?? anchor; - // const index = docs.indexOf(target); - // index !== -1 && (this.layoutDoc._carousel_index = index); //if index is not -1, then assign index to this.layoutDoc._carousel_index - // return undefined; - // }; rotate = (amCards: number, index: number) => { const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2)); @@ -126,11 +105,33 @@ export class CollectionCardView extends CollectionSubView() { // return -((50 / ((amCards - (amCards % 2)) / 2)) * (amCards - index - 1)); // } // }; + + + translateSelected = (index: number): number => { + if (this.isSelected(index)){ + const middleOfPanel = this._props.PanelWidth() / 2; + const scaledNodeWidth = this.panelWidth() * 1.25; + + // Calculate the position of the node's left edge before scaling + const nodeLeftEdge = index * this.panelWidth(); + // Find the center of the node after scaling + const scaledNodeCenter = nodeLeftEdge + (scaledNodeWidth / 2); + + // Calculate the translation needed to align the scaled node's center with the panel's center + const translation = middleOfPanel - scaledNodeCenter; + + return translation; + } + + return 0; + }; + @observable docRefs = new ObservableMap(); @computed get content() { // const currentIndex = NumCast(this.layoutDoc._carousel_index); - const amCards = this.childLayoutPairs.length; + const amCards = this.inactiveDocs().length; + // const myInactives = const displayDoc = (childPair: { layout: Doc; data: Doc }, screenToLocalTransform: () => Transform) => { return ( { const isSelected = this.isSelected(index); - console.log(index + 'is select?: ' + isSelected); const isHovered = this.hoveredNodeIndex === index; + const inactiveIndex = this.inactiveDocs().indexOf(childPair.layout); const childScreenToLocal = () => { const dref = this.docRefs.get(childPair.layout); const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv); // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off - return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(1 / (isSelected ? 1.25 : 1)).rotate(!isSelected ? -this.rotate(amCards, index) : 0); + return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(1 / (isSelected ? 1.25 : 1)).rotate(!isSelected ? -this.rotate(amCards, inactiveIndex) : 0); }; return (
this.setSelectedNodeIndex(index)} onMouseEnter={() => this.setHoveredNodeIndex(index)} - onMouseLeave={() => this.setHoveredNodeIndex(-1)}> + > {/* {this.lol(childPair.data, index)} */} {displayDoc(childPair, childScreenToLocal)} @@ -193,16 +201,13 @@ export class CollectionCardView extends CollectionSubView() { }); } - // lol = (d : Doc, index: number) => { - // if (SelectionManager.IsSelected(d)){ - // this.setSelectedNodeIndex(index); + @computed get translateWrapperX() { - // } - // } + if (this.inactiveDocs().length != this.childLayoutPairs.length){ + return this.panelWidth()/2 + } - @computed get translateX() { - const index = NumCast(this.layoutDoc._carousel_index); - return this.panelWidth() * (1 - index); + return 0; } render() { @@ -216,10 +221,17 @@ export class CollectionCardView extends CollectionSubView() { }}>
this.setHoveredNodeIndex(-1)} > {this.content}
+ + {/* {this.focusContent} */} + +
); } -- cgit v1.2.3-70-g09d2 From e7eb114fd32ac8bd9784a73e9125baa0a91c81d4 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Thu, 21 Mar 2024 04:54:19 -0400 Subject: figuring out sorting-- may just leave it to god --- .../views/collections/CollectionCardDeckView.tsx | 47 ++++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index a4d0d1862..66729d64b 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -2,9 +2,9 @@ import { ObservableMap, action, computed, makeObservable, observable } from 'mob import { observer } from 'mobx-react'; import * as React from 'react'; import { Utils, returnZero } from '../../../Utils'; -import { Doc, DocListCast } from '../../../fields/Doc'; +import { Doc, DocListCast, Field } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; -import { NumCast, ScriptCast } from '../../../fields/Types'; +import { NumCast, ScriptCast, StrCast, BoolCast } from '../../../fields/Types'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { StyleProp } from '../StyleProvider'; @@ -57,6 +57,19 @@ export class CollectionCardView extends CollectionSubView() { return docs.filter(d => !SelectionManager.IsSelected(d)); } + middleIndex = Math.floor(this.inactiveDocs().length / 2); + + + // verticalOffset = (index: number) => { + + // const distanceFromMiddle = Math.abs(index - this.middleIndex); + // // Adjust '4' to control the curvature; larger values create a flatter arc. + // return Math.pow(distanceFromMiddle, 2)* (Math.floor(64/this.inactiveDocs().length)); // Example quadratic function + // }; + + + + constructor(props: any) { super(props); makeObservable(this); @@ -126,6 +139,25 @@ export class CollectionCardView extends CollectionSubView() { return 0; }; + @computed get sortedDocs() { + const field = StrCast(this.layoutDoc.sortField); + const desc = BoolCast(this.layoutDoc.sortDesc); + const docs = !field + ? this.childDocs + : [...this.childDocs].sort((docA, docB) => { + const aStr = Field.toString(docA[field] as Field); + const bStr = Field.toString(docB[field] as Field); + var out = 0; + if (aStr < bStr) out = -1; + if (aStr > bStr) out = 1; + if (desc) out *= -1; + return out; + }); + return { docs }; + } + + + @observable docRefs = new ObservableMap(); @computed get content() { @@ -162,6 +194,8 @@ export class CollectionCardView extends CollectionSubView() { const isSelected = this.isSelected(index); const isHovered = this.hoveredNodeIndex === index; const inactiveIndex = this.inactiveDocs().indexOf(childPair.layout); + // const yOffset = this.verticalOffset(index); + const childScreenToLocal = () => { const dref = this.docRefs.get(childPair.layout); @@ -180,15 +214,20 @@ export class CollectionCardView extends CollectionSubView() { transform: ` rotate(${!isSelected ? this.rotate(amCards, inactiveIndex) : 0}deg) - translateX(${isSelected ? ((this._props.PanelWidth() / 2) - 210) : 0}px) translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 : 0}px) - scale(${isSelected ? 1.25 : 1})` //scale has to be applied last or selected offset gets messed up + translateX(${isSelected ? ((this._props.PanelWidth() / 2) - ((this.panelWidth())/2) - (this.panelWidth()/2)) : 0}px) + + scale(${isSelected ? 1.25 : 1}) + + ` //scale has to be applied last or selected offset gets messed up , }} + + // onClick={() => this.setSelectedNodeIndex(index)} onMouseEnter={() => this.setHoveredNodeIndex(index)} -- cgit v1.2.3-70-g09d2 From 3a9161f114b54df38b8114f922343ee288fd35d3 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Thu, 21 Mar 2024 06:08:34 -0400 Subject: hm --- .../collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx | 1 - src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index b3ae382e3..1f9cac608 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -156,7 +156,6 @@ export function computeStarburstLayout(poolData: Map, pivotDoc // }); // }); -// // 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]); // } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index d0ac5f6db..93d5363eb 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -541,7 +541,7 @@ export class MarqueeView extends ObservableReactComponent Date: Thu, 21 Mar 2024 11:10:16 -0400 Subject: transformation fixes for cardDeckView --- .../views/collections/CollectionCardDeckView.scss | 10 +-- .../views/collections/CollectionCardDeckView.tsx | 93 +++++++++------------- 2 files changed, 39 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index 95a9b658c..ebd7f9856 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -10,20 +10,16 @@ .card-wrapper { display: flex; position: absolute; - top: $CAROUSEL3D_TOP * 1%; - height: ($CAROUSEL3D_SIDE_SCALE * 100) * 1%; align-items: center; transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); } -.card-item-active, .card-item{ +.card-item-active, +.card-item { transition: transform 0.3s ease-in-out; } - -.card-item-active{ +.card-item-active { position: absolute; z-index: 100; } - - diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 66729d64b..e923f9a72 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -1,7 +1,7 @@ import { ObservableMap, action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Utils, returnZero } from '../../../Utils'; +import { Utils, returnFalse, returnTrue, returnZero } from '../../../Utils'; import { Doc, DocListCast, Field } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { NumCast, ScriptCast, StrCast, BoolCast } from '../../../fields/Types'; @@ -12,7 +12,6 @@ import { DocumentView } from '../nodes/DocumentView'; import './CollectionCardDeckView.scss'; import { CollectionSubView } from './CollectionSubView'; import { Transform } from '../../util/Transform'; -import { indexes } from 'd3'; @observer export class CollectionCardView extends CollectionSubView() { @@ -22,8 +21,8 @@ export class CollectionCardView extends CollectionSubView() { @action setHoveredNodeIndex = (index: number) => { - if (!this.isSelected(index)){ - this.hoveredNodeIndex = index; + if (!this.isSelected(index)) { + this.hoveredNodeIndex = index; } }; @@ -55,21 +54,10 @@ export class CollectionCardView extends CollectionSubView() { const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); return docs.filter(d => !SelectionManager.IsSelected(d)); - } + }; middleIndex = Math.floor(this.inactiveDocs().length / 2); - - // verticalOffset = (index: number) => { - - // const distanceFromMiddle = Math.abs(index - this.middleIndex); - // // Adjust '4' to control the curvature; larger values create a flatter arc. - // return Math.pow(distanceFromMiddle, 2)* (Math.floor(64/this.inactiveDocs().length)); // Example quadratic function - // }; - - - - constructor(props: any) { super(props); makeObservable(this); @@ -89,13 +77,19 @@ export class CollectionCardView extends CollectionSubView() { } }; - panelWidth = () => this._props.PanelWidth() / this.childLayoutPairs.length; - panelHeight = () => this.panelWidth() * 1.5; + childDocumentWidth = 600; // target width of a Doc... + /** + * how much to scale down the contents of the view so that everything will fit + */ + @computed get fitContentScale() { + return (this.childDocumentWidth * this.childLayoutPairs.length) / this._props.PanelWidth(); + } + panelWidth = () => this.childDocumentWidth; + panelHeight = (layout: Doc) => () => (2 * (this.panelWidth() * NumCast(layout._height))) / NumCast(layout._width); onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => (this.isContentActive() ? true : false); - rotate = (amCards: number, index: number) => { const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2)); @@ -119,23 +113,22 @@ export class CollectionCardView extends CollectionSubView() { // } // }; - translateSelected = (index: number): number => { - if (this.isSelected(index)){ + if (this.isSelected(index)) { const middleOfPanel = this._props.PanelWidth() / 2; const scaledNodeWidth = this.panelWidth() * 1.25; - + // Calculate the position of the node's left edge before scaling const nodeLeftEdge = index * this.panelWidth(); // Find the center of the node after scaling - const scaledNodeCenter = nodeLeftEdge + (scaledNodeWidth / 2); - + const scaledNodeCenter = nodeLeftEdge + scaledNodeWidth / 2; + // Calculate the translation needed to align the scaled node's center with the panel's center const translation = middleOfPanel - scaledNodeCenter; - + return translation; } - + return 0; }; @@ -156,14 +149,12 @@ export class CollectionCardView extends CollectionSubView() { return { docs }; } - - @observable docRefs = new ObservableMap(); @computed get content() { // const currentIndex = NumCast(this.layoutDoc._carousel_index); const amCards = this.inactiveDocs().length; - // const myInactives = + // const myInactives = const displayDoc = (childPair: { layout: Doc; data: Doc }, screenToLocalTransform: () => Transform) => { return ( ); }; @@ -196,12 +187,11 @@ export class CollectionCardView extends CollectionSubView() { const inactiveIndex = this.inactiveDocs().indexOf(childPair.layout); // const yOffset = this.verticalOffset(index); - const childScreenToLocal = () => { const dref = this.docRefs.get(childPair.layout); - const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv); + const { translateX, translateY, scale } = Utils.GetScreenTransform(dref?.ContentDiv); // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off - return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(1 / (isSelected ? 1.25 : 1)).rotate(!isSelected ? -this.rotate(amCards, inactiveIndex) : 0); + return new Transform(-translateX + (dref?.centeringX || 0) * scale, -translateY + (dref?.centeringY || 0) * scale, 1).scale(1 / scale).rotate(!isSelected ? -this.rotate(amCards, inactiveIndex) : 0); }; return ( @@ -210,28 +200,19 @@ export class CollectionCardView extends CollectionSubView() { className={`card-item${isSelected ? '-active' : ''}`} style={{ width: this.panelWidth(), - height: this.panelHeight(), - transform: - ` + height: this.panelHeight(childPair.layout)(), + transform: ` rotate(${!isSelected ? this.rotate(amCards, inactiveIndex) : 0}deg) translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 : 0}px) - translateX(${isSelected ? ((this._props.PanelWidth() / 2) - ((this.panelWidth())/2) - (this.panelWidth()/2)) : 0}px) + translateX(${isSelected ? (this._props.PanelWidth() / 2) * this.fitContentScale - this.childDocumentWidth / 2 : 0}px) scale(${isSelected ? 1.25 : 1}) - ` //scale has to be applied last or selected offset gets messed up - - , + `, //scale has to be applied last or selected offset gets messed up }} - - - - - // onClick={() => this.setSelectedNodeIndex(index)} - onMouseEnter={() => this.setHoveredNodeIndex(index)} - > + onMouseEnter={() => this.setHoveredNodeIndex(index)}> {/* {this.lol(childPair.data, index)} */} {displayDoc(childPair, childScreenToLocal)} @@ -241,9 +222,8 @@ export class CollectionCardView extends CollectionSubView() { } @computed get translateWrapperX() { - - if (this.inactiveDocs().length != this.childLayoutPairs.length){ - return this.panelWidth()/2 + if (this.inactiveDocs().length != this.childLayoutPairs.length) { + return this.panelWidth(); } return 0; @@ -260,17 +240,16 @@ export class CollectionCardView extends CollectionSubView() { }}>
this.setHoveredNodeIndex(-1)} - > + onMouseLeave={() => this.setHoveredNodeIndex(-1)}> {this.content}
{/* {this.focusContent} */} - -
); } -- cgit v1.2.3-70-g09d2 From 63385a6ba6411ec1ce745c7367bc2c5756c1dec9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 21 Mar 2024 14:43:08 -0400 Subject: from last --- src/client/views/collections/CollectionCardDeckView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index e923f9a72..b636b878e 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -28,7 +28,7 @@ export class CollectionCardView extends CollectionSubView() { translateHover = (index: number): number => { if (this.hoveredNodeIndex == index && !this.isSelected(index)) { - return -50; + return -50 * this.fitContentScale; } return 0; }; @@ -203,7 +203,7 @@ export class CollectionCardView extends CollectionSubView() { height: this.panelHeight(childPair.layout)(), transform: ` rotate(${!isSelected ? this.rotate(amCards, inactiveIndex) : 0}deg) - translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 : 0}px) + translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 * this.fitContentScale : 0}px) translateX(${isSelected ? (this._props.PanelWidth() / 2) * this.fitContentScale - this.childDocumentWidth / 2 : 0}px) scale(${isSelected ? 1.25 : 1}) -- cgit v1.2.3-70-g09d2 From 96240ee73cdd902f3550f817a660fb1b8c5bb6c1 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Thu, 4 Apr 2024 04:22:37 -0400 Subject: fixed weird centering, finally got the y positioning working, and am (unsuccesfully) working on creating rows --- .../views/collections/CollectionCardDeckView.scss | 9 ++ .../views/collections/CollectionCardDeckView.tsx | 174 ++++++++++++++++++--- 2 files changed, 162 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index ebd7f9856..ff9c0a569 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -14,6 +14,15 @@ transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); } +.card-row{ + display: flex; + position: absolute; + align-items: center; + transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); + + +} + .card-item-active, .card-item { transition: transform 0.3s ease-in-out; diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index b636b878e..98b4e8ec9 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -92,26 +92,55 @@ export class CollectionCardView extends CollectionSubView() { rotate = (amCards: number, index: number) => { const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2)); + const stepMag = Math.abs(-30 + ((amCards/2)- 1) * (30 / ((amCards - (amCards % 2)) / 2))); + + // console.log(possRotate + "poss") if (amCards % 2 == 0 && possRotate == 0) { - console.log('whaddup'); - return possRotate + Math.abs(-30 + (index - 1) * (30 / ((amCards - 1) / 2))); + // console.log('whaddup'); + return possRotate + Math.abs(-30 + (index - 1) * (30 / ((amCards) / 2))); + } + + else if (amCards %2 == 0 && index > (amCards+1)/2){ + // console.log("sup" + stepMag); + + return possRotate + stepMag; } return possRotate; }; - // translateY = (amCards: number, index: number) => { - // // Assuming you want a default value when index > amCards/2 - // // Adjust the logic as necessary for your use case - // if (index <= amCards / 2) { - // return -((50 / ((amCards - (amCards % 2)) / 2)) * index); - // } else { - // // Return a default or calculated value for indices greater than amCards/2 - // // This is just an example; adjust the logic as needed - // return -((50 / ((amCards - (amCards % 2)) / 2)) * (amCards - index - 1)); - // } - // }; + translateY = (amCards: number, index: number) => { + const evenOdd =amCards% 2 + const apex = (amCards-evenOdd)/2 + const stepMag = (200 / ((amCards - evenOdd)/2)) + + Math.abs(((apex-index) *25)) + + console.log("steo" + stepMag) + + if (evenOdd == 1 || index < apex -1){ + console.log('hi' + index) + return Math.abs(stepMag * (apex - index)) + } + + else{ + if (index == apex || index == apex -1){ + return 0 + } + + return Math.abs(stepMag * (apex - index -1)) + + } + + }; + + translateOverFlowY = (amCards: number, index: number) => { + if (amCards>8 && index > amCards/2){ + return 100 + + } + return 0 + } translateSelected = (index: number): number => { if (this.isSelected(index)) { @@ -151,9 +180,80 @@ export class CollectionCardView extends CollectionSubView() { @observable docRefs = new ObservableMap(); - @computed get content() { + // @computed get content() { + // // const currentIndex = NumCast(this.layoutDoc._carousel_index); + // const amCards = this.inactiveDocs().length; + // // const myInactives = + // const displayDoc = (childPair: { layout: Doc; data: Doc }, screenToLocalTransform: () => Transform) => { + // return ( + // r?.ContentDiv && this.docRefs.set(childPair.layout, r))} + // Document={childPair.layout} + // TemplateDataDocument={childPair.data} + // // onClickScript={this.toggleIcon} + // //suppressSetHeight={true} + // NativeWidth={returnZero} + // NativeHeight={returnZero} + // layout_fitWidth={returnFalse} + // onDoubleClickScript={this.onChildDoubleClick} + // renderDepth={this._props.renderDepth + 1} + // LayoutTemplate={this._props.childLayoutTemplate} + // LayoutTemplateString={this._props.childLayoutString} + // // focus={this.focus} + // ScreenToLocalTransform={screenToLocalTransform} //makes sure the box wrapper thing is in the right spot + // isContentActive={this.isChildContentActive} + // isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive} + // PanelWidth={this.panelWidth} + // PanelHeight={this.panelHeight(childPair.layout)} + // /> + // ); + // }; + + // return this.childLayoutPairs.map((childPair, index) => { + // const isSelected = this.isSelected(index); + // const isHovered = this.hoveredNodeIndex === index; + // const isOverflow = amCards > 8 && index > amCards/2 + // const inactiveIndex = this.inactiveDocs().indexOf(childPair.layout); + // // const yOffset = this.verticalOffset(index); + + // const childScreenToLocal = () => { + // const dref = this.docRefs.get(childPair.layout); + // const { translateX, translateY, scale } = Utils.GetScreenTransform(dref?.ContentDiv); + // // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off + // return new Transform(-translateX + (dref?.centeringX || 0) * scale, -translateY + (dref?.centeringY || 0) * scale, 1).scale(1 / scale).rotate(!isSelected ? -this.rotate(amCards, inactiveIndex) : 0); + // }; + + // return ( + //
this.setSelectedNodeIndex(index)} + + // onMouseEnter={() => this.setHoveredNodeIndex(index)}> + // {/* {this.lol(childPair.data, index)} */} + + // {displayDoc(childPair, childScreenToLocal)} + //
+ // ); + // }); + // } + + @action content(amCards: number, startIndex: number, stopIndex: number) { // const currentIndex = NumCast(this.layoutDoc._carousel_index); - const amCards = this.inactiveDocs().length; + // const amCards = this.inactiveDocs().length; // const myInactives = const displayDoc = (childPair: { layout: Doc; data: Doc }, screenToLocalTransform: () => Transform) => { return ( @@ -181,9 +281,13 @@ export class CollectionCardView extends CollectionSubView() { ); }; - return this.childLayoutPairs.map((childPair, index) => { + const inactiveDocs = this.inactiveDocs(); + return this.childLayoutPairs.filter((childPair, index) => { const inactiveIndex = inactiveDocs.indexOf(childPair.layout); return inactiveIndex >= startIndex && inactiveIndex <= stopIndex; + }).map((childPair, index) => { + const isSelected = this.isSelected(index); const isHovered = this.hoveredNodeIndex === index; + const isOverflow = amCards > 8 && index > amCards/2 const inactiveIndex = this.inactiveDocs().indexOf(childPair.layout); // const yOffset = this.verticalOffset(index); @@ -203,8 +307,10 @@ export class CollectionCardView extends CollectionSubView() { height: this.panelHeight(childPair.layout)(), transform: ` rotate(${!isSelected ? this.rotate(amCards, inactiveIndex) : 0}deg) - translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 * this.fitContentScale : 0}px) - translateX(${isSelected ? (this._props.PanelWidth() / 2) * this.fitContentScale - this.childDocumentWidth / 2 : 0}px) + translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 * this.fitContentScale : this.translateY(amCards, inactiveIndex) + // + this.translateOverFlowY(amCards, inactiveIndex) + }px) + translateX(${isSelected ? (this._props.PanelWidth() / 2) * this.fitContentScale - this.childDocumentWidth : 0}px) scale(${isSelected ? 1.25 : 1}) @@ -221,9 +327,35 @@ export class CollectionCardView extends CollectionSubView() { }); } + renderRows() { + const cards = this.inactiveDocs(); + const totalCards = cards.length; + const rowsNeeded = Math.ceil(totalCards / 8); + + let rows = []; + + for (let rowIndex = 0; rowIndex < rowsNeeded; rowIndex++) { + let rowStartIndex = rowIndex * 8; + let rowEndIndex = rowStartIndex + 8; + let rowCards = cards.slice(rowStartIndex, rowEndIndex); + + rows.push(this.renderRowCards(rowCards, rowIndex)); + } + + return rows; + } + + renderRowCards(rowCards: Doc[], rowIndex: number) { + return ( +
+ {this.content(rowCards.length, rowIndex*8, rowIndex*8+8)} +
+ ); + } + @computed get translateWrapperX() { if (this.inactiveDocs().length != this.childLayoutPairs.length) { - return this.panelWidth(); + return this.panelWidth()/2; } return 0; @@ -241,12 +373,12 @@ export class CollectionCardView extends CollectionSubView() {
this.setHoveredNodeIndex(-1)}> - {this.content} + {this.renderRows()}
{/* {this.focusContent} */} -- cgit v1.2.3-70-g09d2