import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, DocCastAsync, WidthSym } from "../../../fields/Doc"; import { InkTool } from "../../../fields/InkField"; import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types"; import { returnFalse, returnOne, numberRange, returnTrue } from "../../../Utils"; import { documentSchema } from "../../../fields/documentSchemas"; import { DocumentManager } from "../../util/DocumentManager"; import { undoBatch } from "../../util/UndoManager"; import { CollectionDockingView, DockedFrameRenderer } from "../collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; import { FieldView, FieldViewProps } from './FieldView'; import { DocumentType } from "../../documents/DocumentTypes"; import "./PresBox.scss"; import { ViewBoxBaseComponent } from "../DocComponent"; import { makeInterface, listSpec } from "../../../fields/Schema"; import { Docs, DocUtils } from "../../documents/Documents"; import { PrefetchProxy } from "../../../fields/Proxy"; import { ScriptField } from "../../../fields/ScriptField"; import { Scripting } from "../../util/Scripting"; import { InkingStroke } from "../InkingStroke"; import { HighlightSpanKind } from "typescript"; import { SearchUtil } from "../../util/SearchUtil"; import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; import { child } from "serializr"; import { List } from "../../../fields/List"; import { Tooltip } from "@material-ui/core"; import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu"; import { conformsTo } from "lodash"; import { translate } from "googleapis/build/src/apis/translate"; import { DragManager, dropActionType } from "../../util/DragManager"; import { actionAsync } from "mobx-utils"; import { SelectionManager } from "../../util/SelectionManager"; type PresBoxSchema = makeInterface<[typeof documentSchema]>; const PresBoxDocument = makeInterface(documentSchema); @observer export class PresBox extends ViewBoxBaseComponent(PresBoxDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); } private treedropDisposer?: DragManager.DragDropDisposer; static Instance: PresBox; @observable _isChildActive = false; @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); } @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); } @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); } constructor(props: any) { super(props); PresBox.Instance = this; if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations. Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({ title: "pres element template", backgroundColor: "transparent", _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data" })); // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data // stored on each pres element. (this.presElement as Doc).lookupField = ScriptField.MakeFunction("lookupPresBoxField(container, field, data)", { field: "string", data: Doc.name, container: Doc.name }); } this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox } componentDidMount() { this.rootDoc.presBox = this.rootDoc; this.rootDoc._forceRenderEngine = "timeline"; this.rootDoc._replacedChrome = "replaced"; this.layoutDoc.presStatus = "edit"; this.layoutDoc._gridGap = 5; // document.addEventListener("keydown", this.keyEvents, false); } componentWillUnmount() { this.treedropDisposer?.(); } onPointerOver = () => { document.addEventListener("keydown", this.keyEvents, true); } onPointerLeave = () => { document.removeEventListener("keydown", this.keyEvents, true); } updateCurrentPresentation = () => { Doc.UserDoc().activePresentation = this.rootDoc; } @undoBatch @action next = () => { this.updateCurrentPresentation(); const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); const lastFrame = Cast(presTargetDoc.lastFrame, "number", null); const curFrame = NumCast(presTargetDoc.currentFrame); let internalFrames: boolean = false; if (presTargetDoc.presProgressivize || presTargetDoc.zoomProgressivize || presTargetDoc.scrollProgressivize) internalFrames = true; // Case 1: There are still other frames and should go through all frames before going to next slide if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) { presTargetDoc._viewTransition = "all 1s"; setTimeout(() => presTargetDoc._viewTransition = undefined, 1010); presTargetDoc.currentFrame = curFrame + 1; if (presTargetDoc.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc); // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide } else if (this.childDocs[this.itemIndex + 1] !== undefined) { const nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected, this.itemIndex); } } @undoBatch @action back = () => { this.updateCurrentPresentation(); const docAtCurrent = this.childDocs[this.itemIndex]; if (docAtCurrent) { //check if any of the group members had used zooming in including the current document //If so making sure to zoom out, which goes back to state before zooming action let prevSelected = this.itemIndex; let didZoom = docAtCurrent.zoomButton; // for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) { // didZoom = this.childDocs[prevSelected].zoomButton; // } prevSelected = Math.max(0, prevSelected - 1); this.gotoDocument(prevSelected, this.itemIndex); } } zoomProgressivizeNext = (presTargetDoc: Doc) => { const srcContext = Cast(presTargetDoc.context, Doc, null); const docView = DocumentManager.Instance.getDocumentView(presTargetDoc); const vfLeft: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]); const vfWidth: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]); const vfTop: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]); const vfHeight: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]); // Case 1: document that is not a Golden Layout tab if (srcContext) { console.log("CASE 1"); const srcDocView = DocumentManager.Instance.getDocumentView(srcContext); if (srcDocView) { const layoutdoc = Doc.Layout(presTargetDoc); const panelWidth: number = srcDocView.props.PanelWidth(); const panelHeight: number = srcDocView.props.PanelHeight(); console.log("srcDocView: " + srcDocView.props.PanelWidth()); // console.log("layoutdoc._width: " + layoutdoc._width); // console.log("srcContext._width: " + srcContext._width); const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2; const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2; // const newPanX = NumCast(presTargetDoc.x) + panelWidth / 2; // const newPanY = NumCast(presTargetDoc.y) + panelHeight / 2; let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2)); // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2)); srcContext._panX = newPanX + (vfLeft + (vfWidth / 2)); srcContext._panY = newPanY + (vfTop + (vfHeight / 2)); // srcContext._panX = newPanX // srcContext._panY = newPanY srcContext._viewScale = newScale; console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale); } } // Case 2: document is the containing collection if (docView && !srcContext) { console.log("CASE 2"); const panelWidth: number = docView.props.PanelWidth(); const panelHeight: number = docView.props.PanelHeight(); let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); presTargetDoc._panX = vfLeft + (vfWidth / 2); presTargetDoc._panY = vfTop + (vfWidth / 2); presTargetDoc._viewScale = newScale; } const resize = document.getElementById('resizable'); if (resize) { resize.style.width = vfWidth + 'px'; resize.style.height = vfHeight + 'px'; resize.style.top = vfTop + 'px'; resize.style.left = vfLeft + 'px'; } } @action onHideDocumentUntilPressClick = () => { this.childDocs.forEach((doc, index) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) { tagDoc.opacity = 1; } else { if (index <= this.itemIndex) { tagDoc.opacity = 1; } else { tagDoc.opacity = 0; } } }); } /** * This is the method that checks for the actions that need to be performed * before the document has been presented, which involves 3 button options: * Hide Until Presented, Hide After Presented, Fade After Presented */ @action hideDocumentInPres = () => { this.updateCurrentPresentation(); this.childDocs.forEach((doc, i) => { const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); console.log("HB: " + doc.presHideTillShownButton); console.log("HA: " + doc.presHideAfterButton); if (doc.presHideTillShownButton) { if (i < this.itemIndex) { console.log(i + 1 + "hide before"); tagDoc.opacity = 0; console.log(tagDoc.opacity); } else { tagDoc.opacity = 1; } } if (doc.presHideAfterButton) { if (i > this.itemIndex) { console.log(i + 1 + "hide after"); tagDoc.opacity = 0; console.log(tagDoc.opacity); } else { tagDoc.opacity = 1; } } }); } /** * This is the method that checks for the actions that need to be performed * after the document has been presented, which involves 3 button options: * Hide Until Presented, Hide After Presented, Fade After Presented */ showAfterPresented = (index: number) => { this.updateCurrentPresentation(); this.childDocs.forEach((doc, ind) => { const presTargetDoc = doc.presentationTargetDoc as Doc; //the order of cases is aligned based on priority if (doc.presHideTillShownButton && ind <= index) { presTargetDoc.opacity = 1; } if (doc.presHideAfterButton && ind < index) { presTargetDoc.opacity = 0; } }); } /** * This method makes sure that cursor navigates to the element that * has the option open and last in the group. If not in the group, and it has * the option open, navigates to that element. */ navigateToElement = async (curDoc: Doc) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); const srcContext = await DocCastAsync(targetDoc.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined; if (this.itemIndex >= 0) { if (targetDoc) { if (srcContext) this.layoutDoc.presCollection = srcContext; } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; } if (srcContext) console.log("NC: " + srcContext.title); if (presCollection) console.log("PC: " + presCollection.title); if (collectionDocView) { if (srcContext && srcContext !== presCollection) { console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection"); console.log(collectionDocView); collectionDocView.props.addDocTab(srcContext, "inPlace"); } } // else if (srcContext) { // console.log("Case 2: srcContext - not open and collection containing this document exists, so open collection that contains it and then await zooming in on document"); // this.props.addDocTab(srcContext, "onRight"); // } else if (!srcContext) { // console.log("Case 3: !srcContext - no collection containing this document, therefore open document itself on right"); // this.props.addDocTab(targetDoc, "onRight"); // } this.updateCurrentPresentation(); const docToJump = curDoc; const willZoom = false; //docToJump stayed same meaning, it was not in the group or was the last element in the group if (docToJump === curDoc) { //checking if curDoc has navigation open if (curDoc.presNavButton && targetDoc) { await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext); } else if (curDoc.presZoomButton && targetDoc) { //awaiting jump so that new scale can be found, since jumping is async await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext); } } else { //awaiting jump so that new scale can be found, since jumping is async targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext); } } //The function that is called when a document is clicked or reached through next or back. //it'll also execute the necessary actions if presentation is playing. public gotoDocument = action((index: number, fromDoc: number) => { this.updateCurrentPresentation(); Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); if (presTargetDoc?.lastFrame !== undefined) { presTargetDoc.currentFrame = 0; } this.navigateToElement(this.childDocs[index]); this._selectedArray = [this.childDocs[index]]; // this.hideIfNotPresented(index); // this.showAfterPresented(index); // this.hideDocumentInPres(); this.onHideDocumentUntilPressClick(); } }); @observable _presTimer!: NodeJS.Timeout; //The function that starts or resets presentaton functionally, depending on status flag. @action startOrResetPres = (startSlide: number) => { this.updateCurrentPresentation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (this.layoutDoc.presStatus === "auto") { if (this._presTimer) clearInterval(this._presTimer); this.layoutDoc.presStatus = "manual"; } else { this.layoutDoc.presStatus = "auto"; this.startPresentation(startSlide); this.gotoDocument(startSlide, this.itemIndex); this._presTimer = setInterval(() => { if (this.itemIndex + 1 < this.childDocs.length) this.next(); else { clearInterval(this._presTimer); this.layoutDoc.presStatus = "manual"; } }, targetDoc.presDuration ? NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition) : 2000); } } //The function that resets the presentation by removing every action done by it. It also //stops the presentaton. resetPresentation = () => { this.updateCurrentPresentation(); this.childDocs.forEach(doc => (doc.presentationTargetDoc as Doc).opacity = 1); this.rootDoc._itemIndex = 0; // this.layoutDoc.presStatus = false; } //The function that starts the presentation, also checking if actions should be applied //directly at start. startPresentation = (startIndex: number) => { this.updateCurrentPresentation(); this.childDocs.map(doc => { const presTargetDoc = doc.presentationTargetDoc as Doc; if (doc.presHideTillShownButton && this.childDocs.indexOf(doc) > startIndex) { presTargetDoc.opacity = 0; } if (doc.presHideAfterButton && this.childDocs.indexOf(doc) < startIndex) { presTargetDoc.opacity = 0; } if (doc.presFadeButton && this.childDocs.indexOf(doc) < startIndex) { presTargetDoc.opacity = 0.5; } }); } updateMinimize = () => { const srcContext = Cast(this.rootDoc.presCollection, Doc, null); if (srcContext) { if (srcContext.miniPres) { document.removeEventListener("keydown", this.keyEvents, false); srcContext.miniPres = false; // Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); CollectionDockingView.AddRightSplit(this.rootDoc); // this.layoutDoc.inOverlay = false; } else { document.addEventListener("keydown", this.keyEvents, false); srcContext.miniPres = true; this.props.addDocTab?.(this.rootDoc, "close"); // Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); } } // if (srcContext) { // Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); // CollectionDockingView.AddRightSplit(this.rootDoc); // this.layoutDoc.inOverlay = false; // } // else { // const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); // this.rootDoc.x = pt[0];// 500;//e.clientX + 25; // this.rootDoc.y = pt[1];////e.clientY - 25; // this.props.addDocTab?.(this.rootDoc, "close"); // Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); // } // } } @undoBatch viewChanged = action((e: React.ChangeEvent) => { //@ts-ignore const viewType = e.target.selectedOptions[0].value as CollectionViewType; viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here // this.updateMinimize(this.rootDoc._viewType = viewType); if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 5; }); @undoBatch movementChanged = action((movement: string) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (movement === 'zoom') { activeItem.presZoomButton = !activeItem.presZoomButton; if (activeItem.presZoomButton) activeItem.presMovement = 'Zoom'; else activeItem.presMovement = 'None'; activeItem.presNavButton = false; } else if (movement === 'nav') { activeItem.presZoomButton = false; activeItem.presNavButton = !activeItem.presNavButton; if (activeItem.presNavButton) activeItem.presMovement = 'Pan'; else activeItem.presMovement = 'None'; } else if (movement === 'switch') { targetDoc.presTransition = 0; activeItem.presSwitchButton = !activeItem.presSwitchButton; if (activeItem.presSwitchButton) activeItem.presMovement = 'Switch'; else activeItem.presMovement = 'None'; } else { activeItem.presMovement = 'None'; activeItem.presZoomButton = false; activeItem.presNavButton = false; activeItem.presSwitchButton = false; } }); whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); addDocumentFilter = (doc: Doc | Doc[]) => { const docs = doc instanceof Doc ? [doc] : doc; docs.forEach((doc, i) => { if (this.childDocs.includes(doc)) { console.log(docs.length); console.log(i + 1); if (docs.length === i + 1) return false; } else { doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf); !this.childDocs.includes(doc) && (doc.presZoomButton = true); } }); return true; } childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement; removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform();// listBox padding-left and pres-box-cont minHeight - .translate(-5, -65) panelHeight = () => this.props.PanelHeight() - 40; active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) && (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) // KEYS @observable _selectedArray: Doc[] = []; @observable _sortedSelectedArray: Doc[] = []; @observable _eleArray: HTMLElement[] = []; @observable _dragArray: HTMLElement[] = []; //TODO: Update to radix / quick sort @action sortArray = (): Doc[] => { const sort: Doc[] = this._selectedArray; this.childDocs.forEach((doc, i) => { if (this._selectedArray.includes(doc)) { sort.push(doc); } }); return sort; } @computed get listOfSelected() { const list = this._selectedArray.map((doc: Doc, index: any) => { const activeItem = Cast(doc, Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc!, Doc, null); return (
{index + 1}. {targetDoc.title}
); }); return list; } //Regular click @action selectElement = (doc: Doc) => { // this._selectedArray = []; this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex)); // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); // console.log(this._selectedArray); } //Command click @action multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => { this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); this._eleArray.push(ref); this._dragArray.push(drag); } //Shift click @action shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => { this._selectedArray = []; const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); if (activeItem) { for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) { this._selectedArray.push(this.childDocs[i]); this._eleArray.push(ref); this._dragArray.push(drag); } } } //Esc click @action keyEvents = (e: KeyboardEvent) => { e.stopPropagation(); e.preventDefault(); // switch(e.keyCode) { // case 27: console.log("escape"); // case 65 && (e.metaKey || e.altKey): // } // Escape key if (e.keyCode === 27) { if (this.layoutDoc.presStatus === "edit") this._selectedArray = []; else this.layoutDoc.presStatus = "edit"; // Ctrl-A to select all } if ((e.metaKey || e.altKey) && e.keyCode === 65) { if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs; // left(37) / a(65) / up(38) to go back } if (e.keyCode === 37) { if (this.layoutDoc.presStatus !== "edit") this.back(); // right (39) / d(68) / down(40) to go to next } if (e.keyCode === 39) { if (this.layoutDoc.presStatus !== "edit") this.next(); // spacebar to 'present' or go to next slide } if (e.keyCode === 32) { if (this.layoutDoc.presStatus !== "edit") this.next(); else this.layoutDoc.presStatus = "manual"; } } @observable private transitionTools: boolean = false; @observable private newDocumentTools: boolean = false; @observable private progressivizeTools: boolean = false; @observable private moreInfoTools: boolean = false; @observable private playTools: boolean = false; @observable private presentTools: boolean = false; @observable private pathBoolean: boolean = false; @observable private expandBoolean: boolean = false; // For toggling transition toolbar @action toggleTransitionTools = () => { this.transitionTools = !this.transitionTools; this.newDocumentTools = false; this.progressivizeTools = false; this.moreInfoTools = false; this.playTools = false; } // For toggling the add new document dropdown @action toggleNewDocument = () => { this.newDocumentTools = !this.newDocumentTools; this.transitionTools = false; this.progressivizeTools = false; this.moreInfoTools = false; this.playTools = false; } // For toggling the tools for progressivize @action toggleProgressivize = () => { this.progressivizeTools = !this.progressivizeTools; const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.editZoomProgressivize = false; targetDoc.editProgressivize = false; this.transitionTools = false; this.newDocumentTools = false; this.moreInfoTools = false; this.playTools = false; } // For toggling the tools for more info @action toggleMoreInfo = () => { this.moreInfoTools = !this.moreInfoTools; this.transitionTools = false; this.newDocumentTools = false; this.progressivizeTools = false; this.playTools = false; } // For toggling the options when the user wants to select play @action togglePlay = () => { this.playTools = !this.playTools; this.transitionTools = false; this.newDocumentTools = false; this.progressivizeTools = false; this.moreInfoTools = false; } // For toggling the options when the user wants to select play @action togglePresent = () => { this.presentTools = !this.presentTools; this.playTools = false; this.transitionTools = false; this.newDocumentTools = false; this.progressivizeTools = false; this.moreInfoTools = false; } @action toggleAllDropdowns() { this.transitionTools = false; this.newDocumentTools = false; this.progressivizeTools = false; this.moreInfoTools = false; this.playTools = false; } @undoBatch @action viewPaths = async () => { const srcContext = Cast(this.rootDoc.presCollection, Doc, null); if (this.pathBoolean) { console.log("true"); if (srcContext) { this.togglePath(); srcContext._fitToBox = false; srcContext._viewType = "freeform"; srcContext.presPathView = false; } } else { console.log("false"); if (srcContext) { this.togglePath(); srcContext._fitToBox = true; srcContext._viewType = "freeform"; srcContext.presPathView = true; } } console.log("view paths"); const viewType = srcContext?._viewType; const fit = srcContext?._fitToBox; // if (!DocumentManager.Instance.getDocumentView(curPres)) { // CollectionDockingView.AddRightSplit(curPres); // } } @computed get order() { const order: JSX.Element[] = []; this.childDocs.forEach((doc, index) => { const targetDoc = Cast(doc.presentationTargetDoc, Doc, null); const srcContext = Cast(targetDoc.context, Doc, null); if (this.rootDoc.presCollection === srcContext) { order.push(
{index + 1}
); } else { order.push(
{index + 1}
); } }); return order; } @computed get paths() { let pathPoints = ""; console.log(this.childDocs.length - 1); this.childDocs.forEach((doc, index) => { const targetDoc = Cast(doc.presentationTargetDoc, Doc, null); const srcContext = Cast(targetDoc.context, Doc, null); if (targetDoc && this.rootDoc.presCollection === srcContext) { const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2); const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2); if (index = 0) pathPoints = n1x + "," + n1y; else pathPoints = pathPoints + " " + n1x + "," + n1y; } else { if (index = 0) pathPoints = 0 + "," + 0; else pathPoints = pathPoints + " " + 0 + "," + 0; } }); console.log(pathPoints); return (); } @action togglePath = () => this.pathBoolean = !this.pathBoolean; @action toggleExpand = () => this.expandBoolean = !this.expandBoolean; /** * The function that is called on click to turn fading document after presented option on/off. * It also makes sure that the option swithches from hide-after to this one, since both * can't coexist. */ @action onFadeDocumentAfterPresentedClick = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); activeItem.presFadeButton = !activeItem.presFadeButton; if (!activeItem.presFadeButton) { if (targetDoc) { targetDoc.opacity = 1; } } else { activeItem.presHideAfterButton = false; if (this.rootDoc.presStatus !== "edit" && targetDoc) { targetDoc.opacity = 0.5; } } } @action dropdownToggle = (menu: string) => { console.log('presBox' + menu + 'Dropdown'); const dropMenu = document.getElementById('presBox' + menu + 'Dropdown'); console.log(dropMenu); console.log(dropMenu?.style.display); if (dropMenu) dropMenu.style.display === 'none' ? dropMenu.style.display = 'block' : dropMenu.style.display = 'none'; } setTransitionTime = (number: String) => { const timeInMS = Number(number) * 1000; const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (targetDoc) targetDoc.presTransition = timeInMS; } setDurationTime = (number: String) => { const timeInMS = Number(number) * 1000; const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (targetDoc) targetDoc.presDuration = timeInMS; } @computed get transitionDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); if (activeItem && targetDoc) { const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5; const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2; const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93); const durationThumbLocation = String(9.48 * Number(duration)); const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom'; return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
Movement
e.stopPropagation()} // onClick={() => this.dropdownToggle('Movement')} > {activeItem.presMovement}
e.stopPropagation()}>
e.stopPropagation()} onClick={() => this.movementChanged('none')}>None
e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom
e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan
e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Switch
Transition Speed
{transitionSpeed} s
) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
Fast
Medium
Slow
Visibility {"&"} Duration
{"Hide before presented"}
}>
activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton}>Hide before
{"Hide after presented"}
}>
activeItem.presHideAfterButton = !activeItem.presHideAfterButton}>Hide after
Slide Duration
{duration} s
) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
Short
Medium
Long
Effects
e.stopPropagation()} > {effect}
e.stopPropagation()}>
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'None'}>None
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Fade'}>Fade In
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Flip'}>Flip
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Rotate'}>Rotate
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Bounce'}>Bounce
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Roll'}>Roll
Effect direction
{"Enter from left"}
}>
targetDoc.presEffectDirection = 'left'}>
{"Enter from right"}
}>
targetDoc.presEffectDirection = 'right'}>
{"Enter from top"}
}>
targetDoc.presEffectDirection = 'top'}>
{"Enter from bottom"}
}>
targetDoc.presEffectDirection = 'bottom'}>
{"Enter from center"}
}>
targetDoc.presEffectDirection = false}>
{this.effectDirection}
this.applyTo(this._selectedArray)}> Apply to selected
this.applyTo(this.childDocs)}> Apply to all
); } } @computed get effectDirection(): string { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); let effect = ''; switch (targetDoc.presEffectDirection) { case 'left': effect = "Enter from left"; break; case 'right': effect = "Enter from right"; break; case 'top': effect = "Enter from top"; break; case 'bottom': effect = "Enter from bottom"; break; default: effect = "Enter from center"; break; } return effect; } applyTo = (array: Doc[]) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); array.forEach((doc, index) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); if (tagDoc && targetDoc) { tagDoc.presTransition = targetDoc.presTransition; tagDoc.presDuration = targetDoc.presDuration; tagDoc.presEffect = targetDoc.presEffect; } }); } public inputRef = React.createRef(); @computed get optionsDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); if (activeItem && targetDoc) { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
{this.stringType} options
Start automatically
Start manually
Open document
Open parent collection
Store original website
); } } @computed get newDocumentToolbarDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
runInAction(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
runInAction(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
Title
Subtitle
runInAction(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
Section header
runInAction(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
Title
Text goes here
runInAction(() => { this.layout = 'twoColumns'; this.createNewSlide(this.layout); })}>
Title
Column one text
Column two text
); } @observable openLayouts: boolean = false; @observable addFreeform: boolean = true; @observable layout: string = ""; @observable title: string = ""; @computed get newDocumentDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
Slide Title:

{/*
*/} { e.stopPropagation(); runInAction(() => { (this.title = e.target.value) }); }}> {/*
*/}
Choose type:
runInAction(() => { this.addFreeform = !this.addFreeform })}>Text
runInAction(() => { this.addFreeform = !this.addFreeform })}>Freeform
Preset layouts:
runInAction(() => { this.layout = 'blank' })} />
runInAction(() => { this.layout = 'title' })}>
Title
Subtitle
runInAction(() => { this.layout = 'header' })}>
Section header
runInAction(() => { this.layout = 'content' })}>
Title
Text goes here
runInAction(() => { this.layout = 'twoColumns' })}>
Title
Column one text
Column two text
runInAction(() => { this.openLayouts = !this.openLayouts })}>
this.createNewSlide(this.layout, this.title, this.addFreeform)}> Create New Slide
); } createNewSlide = (layout?: string, title?: string, freeform?: boolean) => { console.log("whats going on?"); let doc = undefined; if (freeform && layout) doc = this.createTemplate(layout, title); if (!freeform) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title }); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const data = Cast(presCollection.data, listSpec(Doc)); const presData = Cast(this.rootDoc.data, listSpec(Doc)); console.log(data); console.log(doc); if (data && doc && presData) { console.log("data and doc"); data.push(doc); DockedFrameRenderer.PinDoc(doc, false); } } createTemplate = (layout: string, input?: string) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); let x = 0; let y = 0; if (activeItem && targetDoc) { x = NumCast(targetDoc._x); y = NumCast(targetDoc._y) + NumCast(targetDoc._height) + 20; } let doc = undefined; const title = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", }); const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" }); const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" }); const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" }); const content = Docs.Create.TextDocument("Click to change texte", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" }); const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" }); const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" }); switch (layout) { case 'blank': doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'title': doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'header': doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'content': doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'twoColumns': doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; default: break; } return doc; } @computed get playDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
this.startOrResetPres(this.itemIndex)}> Present from current slide
this.startOrResetPres(0)}> Present from first slide
); } @computed get presentDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
Minimize
this.startOrResetPres(0)}> Sidebar view
); } // progressivizeOptions = (viewType: string) => { // const buttons = []; // buttons.push(
Child documents
); // buttons.push(
console.log("hide after")}>Internal zoom
); // buttons.push(
console.log("hide after")}>Bullet points
); // if (viewType === "rtf") { // buttons.push(
console.log("hide after")}>Bullet points
); // } // return buttons; // } @undoBatch @action nextKeyframe = (tagDoc: Doc): void => { const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); const currentFrame = Cast(tagDoc.currentFrame, "number", null); if (currentFrame === undefined) { tagDoc.currentFrame = 0; CollectionFreeFormDocumentView.setupScroll(tagDoc, 0); CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); } let lastFrame: number = 0; childDocs.forEach((doc) => { if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame); }); CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame); CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0); tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1); tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), lastFrame); if (tagDoc.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px'; resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px'; resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px'; resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px'; } } } @undoBatch @action prevKeyframe = (tagDoc: Doc): void => { const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); const currentFrame = Cast(tagDoc.currentFrame, "number", null); if (currentFrame === undefined) { tagDoc.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); } CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice()); tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1); if (tagDoc.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px'; resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px'; resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px'; resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px'; } } } @computed get stringType(): string { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); let type: string = ''; switch (targetDoc.type) { case DocumentType.PDF: type = "PDF"; break; case DocumentType.RTF: type = "Text node"; break; case DocumentType.COL: type = "Collection"; break; case DocumentType.AUDIO: type = "Audio"; break; case DocumentType.VID: type = "Video"; break; default: type = "Other node"; break; } return type; } @computed get progressivizeDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); if (activeItem && targetDoc) { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
{this.stringType} selected
Child documents
Edit
Internal zoom
Viewfinder
Snapshot
Text progressivize
Edit
Scroll progressivize
Edit
Frames
{ e.stopPropagation(); this.prevKeyframe(targetDoc); }}>
targetDoc.editing = !targetDoc.editing)} > {NumCast(targetDoc.currentFrame)}
{ e.stopPropagation(); this.nextKeyframe(targetDoc); }}>
{"Last frame"}
}>
{NumCast(targetDoc.lastFrame)}
console.log("play frames")}>Play
); } } //Toggle whether the user edits or not @action editSnapZoomProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (!targetDoc.editSnapZoomProgressivize) { targetDoc.editSnapZoomProgressivize = true; } else { targetDoc.editSnapZoomProgressivize = false; } } //Toggle whether the user edits or not @action editZoomProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (!targetDoc.editZoomProgressivize) { targetDoc.editZoomProgressivize = true; } else { targetDoc.editZoomProgressivize = false; } } //Toggle whether the user edits or not @action editScrollProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (!targetDoc.editScrollProgressivize) { targetDoc.editScrollProgressivize = true; } else { targetDoc.editScrollProgressivize = false; } } //Progressivize Zoom @action progressivizeScroll = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); activeItem.scrollProgressivize = !activeItem.scrollProgressivize; const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.scrollProgressivize = !targetDoc.zoomProgressivize; CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame), true); if (targetDoc.editScrollProgressivize) { targetDoc.editScrollProgressivize = false; targetDoc.currentFrame = 0; targetDoc.lastFrame = 0; } } //Progressivize Zoom @action progressivizeZoom = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); activeItem.zoomProgressivize = !activeItem.zoomProgressivize; const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize; CollectionFreeFormDocumentView.setupZoom(targetDoc, true); if (targetDoc.editZoomProgressivize) { targetDoc.editZoomProgressivize = false; targetDoc.currentFrame = 0; targetDoc.lastFrame = 0; } } //Progressivize Text nodes @action editTextProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.currentFrame = targetDoc.lastFrame; if (targetDoc?.editTextProgressivize) { targetDoc.editTextProgressivize = false; } else { targetDoc.editTextProgressivize = true; } } @action progressivizeText = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); activeItem.presProgressivize = !activeItem.presProgressivize; const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); targetDoc.presProgressivize = !targetDoc.presProgressivize; console.log(targetDoc.presProgressivize); if (activeItem.presProgressivize) { console.log("progressivize"); targetDoc.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); targetDoc.lastFrame = docs.length - 1; } } //Progressivize Child Docs @action editProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.currentFrame = targetDoc.lastFrame; if (targetDoc?.editProgressivize) { targetDoc.editProgressivize = false; } else { targetDoc.editProgressivize = true; } } @action progressivizeChild = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; targetDoc.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); targetDoc.lastFrame = docs.length - 1; } else { targetDoc.editProgressivize = false; activeItem.presProgressivize = false; targetDoc.presProgressivize = false; // docs.forEach((doc, index) => { // doc.appearFrame = 0; // }); targetDoc.currentFrame = 0; targetDoc.lastFrame = 0; } } @action checkMovementLists = (doc: Doc, xlist: any, ylist: any) => { const x: List = xlist; const y: List = ylist; const tags: JSX.Element[] = []; let pathPoints = ""; //List of all of the pathpoints that need to be added // console.log(x); // console.log(x.length); // console.log(x[0]); for (let i = 0; i < x.length - 1; i++) { if (y[i] || x[i]) { if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33); else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33); tags.push(
{i}
); } } tags.push(); return tags; } @observable toggleDisplayMovement = (doc: Doc) => { if (doc.displayMovement) doc.displayMovement = false; else doc.displayMovement = true; } private _isDraggingTL = false; private _isDraggingTR = false; private _isDraggingBR = false; private _isDraggingBL = false; private _isDragging = false; // private _drag = ""; // onPointerDown = (e: React.PointerEvent): void => { // e.stopPropagation(); // e.preventDefault(); // if (e.button === 0) { // this._drag = e.currentTarget.id; // console.log(this._drag); // } // document.removeEventListener("pointermove", this.onPointerMove); // document.addEventListener("pointermove", this.onPointerMove); // document.removeEventListener("pointerup", this.onPointerUp); // document.addEventListener("pointerup", this.onPointerUp); // } //Adds event listener so knows pointer is down and moving onPointerMid = (e: React.PointerEvent): void => { e.stopPropagation(); e.preventDefault(); this._isDragging = true; document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); } //Adds event listener so knows pointer is down and moving onPointerBR = (e: React.PointerEvent): void => { e.stopPropagation(); e.preventDefault(); this._isDraggingBR = true; document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); } //Adds event listener so knows pointer is down and moving onPointerBL = (e: React.PointerEvent): void => { e.stopPropagation(); e.preventDefault(); this._isDraggingBL = true; document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); } //Adds event listener so knows pointer is down and moving onPointerTR = (e: React.PointerEvent): void => { e.stopPropagation(); e.preventDefault(); this._isDraggingTR = true; document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); } //Adds event listener so knows pointer is down and moving onPointerTL = (e: React.PointerEvent): void => { e.stopPropagation(); e.preventDefault(); this._isDraggingTL = true; document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointerup", this.onPointerUp); } //Removes all event listeners onPointerUp = (e: PointerEvent): void => { e.stopPropagation(); e.preventDefault(); this._isDraggingTL = false; this._isDraggingTR = false; this._isDraggingBL = false; this._isDraggingBR = false; this._isDragging = false; document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); } //Adjusts the value in NodeStore onPointerMove = (e: PointerEvent): void => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const tagDocView = DocumentManager.Instance.getDocumentView(targetDoc); e.stopPropagation(); e.preventDefault(); const doc = document.getElementById('resizable'); if (doc && tagDocView) { const scale = tagDocView.childScaling(); console.log("childScaling: " + scale); const scale2 = tagDocView.props.ScreenToLocalTransform().Scale; console.log("ScreenToLocal...Scale: " + scale2); let height = doc.offsetHeight; let width = doc.offsetWidth; let top = doc.offsetTop; let left = doc.offsetLeft; // const newHeightB = height += (e.movementY * NumCast(targetDoc._viewScale)); // const newHeightT = height -= (e.movementY * NumCast(targetDoc._viewScale)); // const newWidthR = width += (e.movementX * NumCast(targetDoc._viewScale)); // const newWidthL = width -= (e.movementX * NumCast(targetDoc._viewScale)); // const newLeft = left += (e.movementX * NumCast(targetDoc._viewScale)); // const newTop = top += (e.movementY * NumCast(targetDoc._viewScale)); // switch (this._drag) { // case "": break; // case "resizer-br": // doc.style.height = newHeightB + 'px'; // doc.style.width = newWidthR + 'px'; // break; // case "resizer-bl": // doc.style.height = newHeightB + 'px'; // doc.style.width = newWidthL + 'px'; // doc.style.left = newLeft + 'px'; // break; // case "resizer-tr": // doc.style.width = newWidthR + 'px'; // doc.style.height = newHeightT + 'px'; // doc.style.top = newTop + 'px'; // case "resizer-tl": // doc.style.width = newWidthL + 'px'; // doc.style.height = newHeightT + 'px'; // doc.style.top = newTop + 'px'; // doc.style.left = newLeft + 'px'; // case "resizable": // doc.style.top = newTop + 'px'; // doc.style.left = newLeft + 'px'; // } //Bottom right if (this._isDraggingBR) { const newHeight = height += (e.movementY * scale2); doc.style.height = newHeight + 'px'; const newWidth = width += (e.movementX * scale2); doc.style.width = newWidth + 'px'; // Bottom left } else if (this._isDraggingBL) { const newHeight = height += (e.movementY * scale); doc.style.height = newHeight + 'px'; const newWidth = width -= (e.movementX * scale); doc.style.width = newWidth + 'px'; const newLeft = left += (e.movementX * scale); doc.style.left = newLeft + 'px'; // Top right } else if (this._isDraggingTR) { const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.width = newWidth + 'px'; const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.height = newHeight + 'px'; const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.top = newTop + 'px'; // Top left } else if (this._isDraggingTL) { const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.width = newWidth + 'px'; const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.height = newHeight + 'px'; const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.top = newTop + 'px'; const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.left = newLeft + 'px'; } else if (this._isDragging) { const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.top = newTop + 'px'; const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.left = newLeft + 'px'; } this.updateList(targetDoc, targetDoc["viewfinder-width-indexed"], width); this.updateList(targetDoc, targetDoc["viewfinder-height-indexed"], height); this.updateList(targetDoc, targetDoc["viewfinder-top-indexed"], top); this.updateList(targetDoc, targetDoc["viewfinder-left-indexed"], left); } } @action checkList = (doc: Doc, list: any): number => { const x: List = list; if (x && x.length >= NumCast(doc.currentFrame) + 1) { return x[NumCast(doc.currentFrame)]; } else { x.length = NumCast(doc.currentFrame) + 1; x[NumCast(doc.currentFrame)] = x[NumCast(doc.currentFrame) - 1]; return x[NumCast(doc.currentFrame)]; } } @action updateList = (doc: Doc, list: any, val: number) => { const x: List = list; if (x && x.length >= NumCast(doc.currentFrame) + 1) { x[NumCast(doc.currentFrame)] = val; list = x; } else { x.length = NumCast(doc.currentFrame) + 1; x[NumCast(doc.currentFrame)] = val; list = x; } } // scale: NumCast(targetDoc._viewScale), @computed get zoomProgressivizeContainer() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); if (targetDoc.editZoomProgressivize) { return ( <>
); } else return null; } @computed get progressivizeChildDocs() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); const tags: JSX.Element[] = []; docs.forEach((doc, index) => { if (doc["x-indexed"] && doc["y-indexed"]) { tags.push(
{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}
); } tags.push(
{ if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? "#aedff8" : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}>
{ e.stopPropagation(); this.prevAppearFrame(doc, index); }} />
{doc.appearFrame}
{ e.stopPropagation(); this.nextAppearFrame(doc, index); }} />
); }); return tags; } @undoBatch @action nextAppearFrame = (doc: Doc, i: number): void => { console.log("next"); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const appearFrame = Cast(doc.appearFrame, "number", null); if (appearFrame === undefined) { doc.appearFrame = 0; } doc.appearFrame = appearFrame + 1; const olist = new List(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); doc["opacity-indexed"] = olist; console.log(doc.appearFrame); } @undoBatch @action prevAppearFrame = (doc: Doc, i: number): void => { console.log("prev"); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const appearFrame = Cast(doc.appearFrame, "number", null); if (appearFrame === undefined) { doc.appearFrame = 0; } doc.appearFrame = Math.max(0, appearFrame - 1); const olist = new List(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); doc["opacity-indexed"] = olist; console.log(doc.appearFrame); } @computed get moreInfoDropdown() { return (
); } @computed get toolbarWidth(): number { const width = this.props.PanelWidth(); return width; } @computed get toolbar() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); if (activeItem) { return ( <>
{"Add new slide"}
}>
{"View paths"}
}>
{this.expandBoolean ? "Minimize all" : "Expand all"}
}>
{ this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
{/*
*/}
{/*
{"Transitions"}
}>
430 ? "block" : "none" }} className="toolbar-buttonText">  Transitions
{"Progressivize"}
}>
430 ? "block" : "none" }} className="toolbar-buttonText">  Progressivize
*/}
); } else { return ( <>
{"Add new slide"}
}>
); } } private _itemRef: React.RefObject = React.createRef(); // protected createPresDropTarget = (ele: HTMLDivElement) => { // console.log("created?"); // this.treedropDisposer?.(); // ele && (this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this))); // if (ele) { // console.log("ele: " + ele.className) // } // } // protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetAction: dropActionType) { // console.log("preDrop?") // if (de.complete.docDragData) { // // if targetDropAction is, say 'alias', but we're just dragging within a collection, we want to ignore the targetAction. // // otherwise, the targetAction should become the actual action (which can still be overridden by the userDropAction -eg, shift/ctrl keys) // if (targetAction && !de.complete.docDragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) { // de.complete.docDragData.dropAction = targetAction; // } // e.stopPropagation(); // } // } // @action // protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { // console.log("drop in pres") // const docDragData = de.complete.docDragData; // ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData }); // if (docDragData && this.props.addDocument) { // console.log("docDragData && this.props.addDocument"); // let added = false; // const dropaction = docDragData.dropAction || docDragData.userDropAction; // if (dropaction && dropaction !== "move") { // console.log("dropaction && dropaction !== move"); // added = this.props.addDocument(docDragData.droppedDocuments); // } else if (docDragData.moveDocument) { // console.log("docDragData.moveDocument"); // const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d); // const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d); // const res = addedDocs.length ? this.props.addDocument(addedDocs) : true; // if (movedDocs.length) { // const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey || // Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document); // added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.props.addDocument : returnFalse); // } else added = res; // } else { // console.log("else"); // added = this.props.addDocument(docDragData.droppedDocuments); // } // added && e.stopPropagation(); // return added; // } // return false; // } render() { this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; // const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => { // return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false); // }; return
this.startOrResetPres(0)}>  
{ e.stopPropagation; this.togglePlay(); }}> {this.playDropdown}
this.layoutDoc.presStatus = "manual"}>   Present
{ e.stopPropagation; this.togglePresent(); }}> {this.presentDropdown}
this.layoutDoc.presStatus = "edit"}>
{this.toolbar}
{this.newDocumentToolbarDropdown} {/* {this.newDocumentDropdown} {this.moreInfoDropdown} {this.transitionDropdown} {this.progressivizeDropdown} */}
{/* ref={this.createPresDropTarget}> */} {mode !== CollectionViewType.Invalid ? ScreenToLocalTransform={this.getTransform} /> : (null) }
; } } Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, data: Doc) { if (field === 'indexInPres') return DocListCast(container[StrCast(container.presentationFieldKey)]).indexOf(data); if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 30 : 26; if (field === 'presStatus') return container.presStatus; if (field === '_itemIndex') return container._itemIndex; if (field === 'presBox') return container; return undefined; }); // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus); // const presOrderedDocs = DocListCast(activeItem.presOrderedDocs); // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) { // this.rootDoc.presOrderedDocs = new List(this.childDocs.slice()); // }