import { ObservableMap, action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; 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'; 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'; @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 * this.fitContentScale; } 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); 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); } }; 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)); 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) / 2))); } else if (amCards %2 == 0 && index > (amCards+1)/2){ // console.log("sup" + stepMag); return possRotate + stepMag; } return possRotate; }; 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)) { 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={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 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)} /> ); }; 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); 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)}
); }); } 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()/2; } return 0; } render() { return (
this.setHoveredNodeIndex(-1)}> {this.renderRows()}
{/* {this.focusContent} */}
); } }