import { ObservableMap, action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Utils, returnZero } from '../../../Utils'; import { Doc, DocListCast, Field } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { NumCast, ScriptCast, StrCast, BoolCast } from '../../../fields/Types'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { StyleProp } from '../StyleProvider'; 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() { @observable selectedNodeIndex = -1; @observable hoveredNodeIndex = -1; @action setHoveredNodeIndex = (index: number) => { if (!this.isSelected(index)){ this.hoveredNodeIndex = index; } }; translateHover = (index: number): number => { if (this.hoveredNodeIndex == index && !this.isSelected(index)) { return -50; } return 0; }; @action setSelectedNodeIndex = (index: number) => { 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); } }; isSelected = (index: number): boolean => { const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]); return SelectionManager.IsSelected(docs[index]); }; inactiveDocs = () => { 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); // this.rotationDegree(7); } private _dropDisposer?: DragManager.DragDropDisposer; componentWillUnmount() { this._dropDisposer?.(); } protected createDashEventsTarget = (ele: HTMLDivElement | null) => { this._dropDisposer?.(); if (ele) { this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); } }; panelWidth = () => this._props.PanelWidth() / this.childLayoutPairs.length; panelHeight = () => this.panelWidth() * 1.5; 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)); 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)); // } // }; 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; }; @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() { // 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={undefined} 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} /> ); }; return this.childLayoutPairs.map((childPair, index) => { 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); 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, inactiveIndex) : 0); }; return (
this.setSelectedNodeIndex(index)} onMouseEnter={() => this.setHoveredNodeIndex(index)} > {/* {this.lol(childPair.data, index)} */} {displayDoc(childPair, childScreenToLocal)}
); }); } @computed get translateWrapperX() { if (this.inactiveDocs().length != this.childLayoutPairs.length){ return this.panelWidth()/2 } return 0; } render() { return (
this.setHoveredNodeIndex(-1)} > {this.content}
{/* {this.focusContent} */}
); } }