diff options
author | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2020-08-06 05:11:18 +0800 |
---|---|---|
committer | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2020-08-06 05:11:18 +0800 |
commit | fa0b28c300416621dec25407484fc2606a736e2a (patch) | |
tree | 61baaa7197c80ed23da6c12b70a5202557598bfc | |
parent | 917deb0c0d73997f4ffa465e75ac05fdca7a8519 (diff) |
automatic text progressivize, ui changes, bug fixes
13 files changed, 386 insertions, 245 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 539341b62..57fcf3a00 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -129,6 +129,7 @@ export interface DocumentOptions { isLinkButton?: boolean; _columnWidth?: number; _fontSize?: string; + _fontWeight?: number; _fontFamily?: string; curPage?: number; currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds @@ -139,6 +140,7 @@ export interface DocumentOptions { appearFrame?: number; // the frame in which the document appears presTransition?: number; //the time taken for the transition TO a document presDuration?: number; //the duration of the slide in presentation view + presProgressivize?: boolean; // xArray?: number[]; // yArray?: number[]; borderRounding?: string; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index d46c03470..7d8a75dda 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -30,6 +30,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager'; import { DocumentType } from '../documents/DocumentTypes'; import { CollectionFreeFormView } from './collections/collectionFreeForm/CollectionFreeFormView'; import { InkField } from '../../fields/InkField'; +import { PresBox } from './nodes/PresBox'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -209,7 +210,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isPinned = targetDoc && Doc.isDocPinned(targetDoc); return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}> <div className="propertiesButtons-linker" - style={{ backgroundColor: isPinned ? "white" : "", color: isPinned ? "black" : "white" }} + style={{ backgroundColor: isPinned ? "" : "white", color: isPinned ? "white" : "black" }} onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}> <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" /> @@ -217,6 +218,37 @@ export class PropertiesButtons extends React.Component<{}, {}> { } @computed + get pinWithViewButton() { + const targetDoc = this.selectedDoc; + const isPinned = targetDoc && Doc.isDocPinned(targetDoc); + if (targetDoc) { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + } + return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with this view"}</div></>}> + <div className="propertiesButtons-linker" + style={{ backgroundColor: "white", color: "black" }} + onClick={e => { + if (targetDoc) { + DockedFrameRenderer.PinDoc(targetDoc, false); + const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1]; + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeDoc.presPinView = true; + activeDoc.presPinViewX = x; + activeDoc.presPinViewY = y; + activeDoc.presPinViewScale = scale; + } + }}> + <div style={{ position: 'absolute', fontSize: 25, fontWeight: 700, transform: 'translate(42%, -7px)', color: 'rgba(0,0,0,0.2)' }}>V</div> + <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" /> + </div></Tooltip>; + } + + + @computed get metadataButton() { //const view0 = this.view0; if (this.selectedDoc) { @@ -608,6 +640,9 @@ export class PropertiesButtons extends React.Component<{}, {}> { {this.pinButton} </div> <div className="propertiesButtons-button"> + {this.pinWithViewButton} + </div> + <div className="propertiesButtons-button"> {this.copyButton} </div> <div className="propertiesButtons-button"> diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 857f751d3..98babc3d2 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -45,7 +45,7 @@ .miniPres-button-text { display: flex; - height: 30; + height: 20; font-weight: 400; min-width: 100%; border-radius: 5px; @@ -55,15 +55,15 @@ } .miniPres-divider { - width: 1px; + width: 0.5px; height: 80%; border-right: solid 2px #5a5a5a; } .miniPres-button { display: flex; - height: 30; - min-width: 30; + height: 20; + min-width: 20; border-radius: 100%; align-items: center; justify-content: center; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 9c85bd0a2..bc88236dd 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -871,7 +871,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> { } renderMiniPres() { return <div className="miniPres" style={{ - width: 400, height: 50, background: '#323232' + width: 250, height: 30, background: '#323232' }}> <div className="miniPresOverlay" > <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div> diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index e00bdb065..fe3d57bdb 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -184,7 +184,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) if (found) { const top = found.getBoundingClientRect().top; const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top); - smoothScroll(doc.presTransition ? Number(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop); + smoothScroll(doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop); } afterFocus && setTimeout(() => { if (afterFocus?.()) { } @@ -291,20 +291,19 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) const docs = this.childDocList; if (docs) { newDocs.map((doc, i) => { + console.log(doc.title); if (i === 0) { if (targInd === -1) targInd = docs.length; else targInd = docs.indexOf(this.filteredChildren[targInd]); const srcInd = docs.indexOf(doc); docs.splice(srcInd, 1); docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc); - } else { + } else if (i < (newDocs.length / 2)) { //glr: for some reason dragged documents are duplicated if (targInd === -1) targInd = docs.length; - else targInd = docs.indexOf(this.filteredChildren[targInd]); + else targInd = docs.indexOf(newDocs[0]) + 1; const srcInd = docs.indexOf(doc); - const firstInd = docs.indexOf(newDocs[0]); docs.splice(srcInd, 1); - // docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc); - docs.splice(firstInd + 1, 0, doc); + docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc); } }); } @@ -312,6 +311,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) } return false; } + @undoBatch @action onExternalDrop = async (e: React.DragEvent): Promise<void> => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 109808956..65cd28742 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -911,8 +911,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P // !doc.z && NumCast(this.layoutDoc.scale) < 1 && this.scaleAtPt(DocumentView._focusHack, 1); // [NumCast(doc.x), NumCast(doc.y)], 1); // } else { if (DocListCast(this.dataDoc[this.props.fieldKey]).includes(doc)) { - // glr: freeform transform speed can be set through user by adjusting for presentation transform - if (!doc.z) this.setPan(newPanX, newPanY, doc.presTransition ? `transform ${doc.presTransition}ms` : "transform 500ms", true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow + // glr: freeform transform speed can be set by adjusting presTransition field - needs a way of knowing when presentation is not active... + if (!doc.z) this.setPan(newPanX, newPanY, doc.presTransition || doc.presTransition === 0 ? `transform ${doc.presTransition}ms` : "transform 500ms", true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow } Doc.BrushDoc(this.props.Document); this.props.focus(this.props.Document); diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 1f66d4144..035cd938e 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -865,7 +865,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { if (this.isPres) { return <div className="propertiesView" style={{ width: this.props.width }} > <div className="propertiesView-title" style={{ width: this.props.width }}> - Presentation Toolbar + Presentation <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}> <FontAwesomeIcon icon="times" color="black" size="sm" /> </div> @@ -922,7 +922,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div className="propertiesView-sharing-title" onPointerDown={() => runInAction(() => { this.openSlideOptions = !this.openSlideOptions; })} style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}> - <FontAwesomeIcon icon={"cog"} /> {PresBox.Instance.stringType} options + <FontAwesomeIcon icon={"cog"} /> {PresBox.Instance.stringType} options <div className="propertiesView-sharing-title-icon"> <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" /> </div> diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index c29547eac..35ed6c5a5 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -107,6 +107,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF d["w-indexed"] = new List<number>(windexed); d["opacity-indexed"] = new List<number>(oindexed); d["scroll-indexed"] = new List<number>(scrollIndexed); + if (d.appearFrame) { + if (d.appearFrame === timecode + 1) { + d["text-color"] = "red"; + } else if (d.appearFrame < timecode + 1) { + d["text-color"] = "grey"; + } else { d["text-color"] = "black"; } + } else if (d.appearFrame === 0) { + d["text-color"] = "black"; + } } public static updateScrollframe(doc: Doc, time: number) { @@ -139,6 +148,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number); yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number); opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number); + if (doc.appearFrame) { + if (doc.appearFrame === timecode + 1) { + doc["text-color"] = "red"; + } else if (doc.appearFrame < timecode + 1) { + doc["text-color"] = "grey"; + } else { doc["text-color"] = "black"; } + } else if (doc.appearFrame === 0) { + doc["text-color"] = "black"; + } doc.dataTransition = "all 1s"; }); setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010); @@ -166,7 +184,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) { docs.forEach((doc, i) => { - if (!doc.appearFrame) doc.appearFrame = i; + if (doc.appearFrame === undefined) doc.appearFrame = i; const curTimecode = progressivize ? i : timecode; const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]); diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index 089f69873..16821f5bc 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -754,8 +754,6 @@ } .presBox-button { - margin-right: 2.5px; - margin-left: 2.5px; height: 25px; border-radius: 5px; display: none; @@ -787,13 +785,65 @@ min-width: 100px; width: 100px; position: absolute; - right: 8px; + right: 10px; .present-icon { margin-right: 7px; } } + + .miniPresOverlay { + background-color: #323232; + color: white; + border-radius: 5px; + grid-template-rows: 100%; + height: 25; + width: 200; + justify-content: space-evenly; + align-items: center; + display: flex; + position: absolute; + right: 10px; + + .miniPres-button-text { + display: flex; + height: 20; + width: max-content; + font-family: Roboto; + font-weight: 400; + letter-spacing: normal; + border-radius: 5px; + align-items: center; + justify-content: center; + transition: all 0.3s; + } + + .miniPres-divider { + width: 0.5px; + height: 80%; + border-right: solid 1px #5a5a5a; + } + + .miniPres-button { + display: flex; + height: 20; + min-width: 20; + border-radius: 100%; + align-items: center; + justify-content: center; + transition: all 0.3s; + } + + .miniPres-button:hover { + background-color: #5a5a5a; + } + + .miniPres-button-text:hover { + background-color: #5a5a5a; + } + } + .collectionViewBaseChrome-viewPicker { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 2389d3875..1caefdc57 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -97,7 +97,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> @action next = () => { this.updateCurrentPresentation(); + const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null); const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); + const childDocs = DocListCast(presTargetDoc[Doc.LayoutFieldKey(presTargetDoc)]); + const currentFrame = Cast(presTargetDoc.currentFrame, "number", null); const lastFrame = Cast(presTargetDoc.lastFrame, "number", null); const curFrame = NumCast(presTargetDoc.currentFrame); let internalFrames: boolean = false; @@ -107,8 +110,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> presTargetDoc._viewTransition = "all 1s"; setTimeout(() => presTargetDoc._viewTransition = undefined, 1010); presTargetDoc.currentFrame = curFrame + 1; + if (presTargetDoc.scrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(presTargetDoc, currentFrame); + if (presTargetDoc.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0); if (presTargetDoc.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc); - // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide + // Case 2: Audio or video therefore wait to play the audio or video before moving on } else if ((presTargetDoc.type === DocumentType.VID || presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio) { if (presTargetDoc.type === DocumentType.AUDIO) { AudioBox.Instance.playFrom(0); @@ -117,7 +122,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> if (presTargetDoc.type === DocumentType.VID) { this._moveOnFromAudio = true; } - } else if (this.childDocs[this.itemIndex + 1] !== undefined) { + // Case 3: No more frames in current doc and next slide is defined, therefore move to next slide + } else if (activeNext !== undefined) { + if (!presTargetDoc.presProgressivize) { + const nextTagDoc = Cast(this.childDocs[this.itemIndex + 1].presentationTargetDoc, Doc, null); + const nextChildDocs = DocListCast(nextTagDoc[Doc.LayoutFieldKey(presTargetDoc)]); + nextChildDocs.forEach((doc, i) => { + doc.opacity = 1; + }) + } const nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected, this.itemIndex); this._moveOnFromAudio = false; @@ -130,15 +143,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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); } } @@ -159,19 +165,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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); } @@ -203,9 +201,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); if (tagDoc) tagDoc.opacity = 1; if (curDoc.presHideTillShownButton) { - console.log("-------------hide before---------------"); - console.log("this.itemIndex: " + this.itemIndex); - console.log("index: " + index) if (index > this.itemIndex) { tagDoc.opacity = 0; } else if (!curDoc.presHideAfterButton) { @@ -213,9 +208,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } } if (curDoc.presHideAfterButton) { - console.log("-------------hide after---------------"); - console.log("this.itemIndex: " + (this.itemIndex + 1)); - console.log("index: " + (index + 1)) if (index < this.itemIndex) { tagDoc.opacity = 0; } else if (!curDoc.presHideTillShownButton) { @@ -225,73 +217,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> }); } - @action - onHideAfterPresClick = () => { - this.childDocs.forEach((doc, index) => { - const curDoc = Cast(doc, Doc, null); - const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); - if (curDoc.presHideAfterButton) { - if (index < this.itemIndex) { - tagDoc.opacity = 0; - } else if (index = this.itemIndex) { - tagDoc.opacity = 1; - } - } - }); - } - - /** - * 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 @@ -310,24 +235,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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 (activeItem.openDocument) { - collectionDocView.props.addDocTab(activeItem, "inPlace"); - } else if (srcContext && srcContext !== presCollection) { - if (activeItem.openDocument) { - collectionDocView.props.addDocTab(activeItem, "inPlace"); - } else { - 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"); - } + if (srcContext && srcContext !== presCollection) { + // Case 1: new srcContext inside of current collection so add a new tab to the current pres collection + collectionDocView.props.addDocTab(srcContext, "inPlace"); } } - if (targetDoc.presWebsiteData) { - targetDoc.data = targetDoc.presWebsiteData; - } // 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"); @@ -354,6 +267,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> //awaiting jump so that new scale can be found, since jumping is async targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext); } + if (activeItem.presPinView) { + targetDoc._panX = activeItem.presPinViewX; + targetDoc._panY = activeItem.presPinViewY; + targetDoc._viewScale = activeItem.presPinViewScale; + } + if (collectionDocView && activeItem.openDocument) { + collectionDocView.props.addDocTab(activeItem, "inPlace"); + } + if (targetDoc.presWebsiteData) { + targetDoc.data = targetDoc.presWebsiteData; + } } //The function that is called when a document is clicked or reached through next or back. @@ -381,6 +305,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> @observable _presTimer!: NodeJS.Timeout; //The function that starts or resets presentaton functionally, depending on status flag. + @undoBatch @action startOrResetPres = (startSlide: number) => { this.updateCurrentPresentation(); @@ -432,31 +357,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> this.turnOffEdit(); if (srcContext) { if (srcContext.miniPres) { - document.removeEventListener("keydown", this.keyEvents, false); + document.removeEventListener("keydown", this.minimizeEvents, 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); + document.addEventListener("keydown", this.minimizeEvents, 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 @@ -464,7 +373,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> //@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); + this.rootDoc._viewType = viewType; if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 5; }); @@ -485,7 +394,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } else if (movement === 'switch') { targetDoc.presTransition = 0; activeItem.presSwitchButton = !activeItem.presSwitchButton; - if (activeItem.presSwitchButton) activeItem.presMovement = 'Switch'; + if (activeItem.presSwitchButton) activeItem.presMovement = 'Jump cut'; else activeItem.presMovement = 'None'; } else { activeItem.presMovement = 'None'; @@ -496,12 +405,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> }); whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); + // For dragging documents into the presentation trail 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); @@ -574,33 +482,45 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } } + @action + minimizeEvents = (e: KeyboardEvent) => { + e.stopPropagation(); + e.preventDefault(); + if (e.keyCode === 27) { // Escape key + this.layoutDoc.presStatus = "edit"; + } if (e.keyCode === 37) { // left(37) / a(65) / up(38) to go back + this.back(); + } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next + this.next(); + } + } + //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 (e.keyCode === 27) { // Escape key 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 ((e.metaKey || e.altKey) && e.keyCode === 65) { // Ctrl-A to select all if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs; - // left(37) / a(65) / up(38) to go back - } if (e.keyCode === 37) { + } if (e.keyCode === 37) { // left(37) / a(65) / up(38) to go back 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 (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next if (this.layoutDoc.presStatus !== "edit") this.next(); + } if (e.keyCode === 32) { // spacebar to 'present' or autoplay + if (this.layoutDoc.presStatus !== "edit") this.startOrResetPres(0); else this.layoutDoc.presStatus = "manual"; } + if (e.keyCode === 8) { // delete selected items + if (this.layoutDoc.presStatus === "edit") { + this._selectedArray.forEach((doc, i) => { + this.removeDocument(doc); + }); + } + } } @observable private transitionTools: boolean = false; @@ -617,7 +537,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> viewPaths = async () => { const srcContext = Cast(this.rootDoc.presCollection, Doc, null); if (this.pathBoolean) { - console.log("true"); if (srcContext) { this.togglePath(); srcContext._fitToBox = false; @@ -625,7 +544,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> srcContext.presPathView = false; } } else { - console.log("false"); if (srcContext) { this.togglePath(); srcContext._fitToBox = true; @@ -633,13 +551,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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() { @@ -664,7 +577,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> @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); @@ -678,7 +590,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> else pathPoints = pathPoints + " " + 0 + "," + 0; } }); - console.log(pathPoints); return (<polyline points={pathPoints} style={{ @@ -720,12 +631,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } } + // WHAT IS THIS? @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'; } @@ -749,8 +658,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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 ( @@ -767,7 +674,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> <div className={`presBox-dropdownOption ${activeItem.presMovement === 'None' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div> <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Zoom' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div> <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Pan' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div> - <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Switch' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Switch</div> + <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Jump cut' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Jump cut</div> </div> </div> <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "inline-flex" : "none" }}> @@ -985,7 +892,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } createNewSlide = (layout?: string, title?: string, freeform?: boolean) => { - console.log("whats going on?"); let doc = undefined; if (layout) doc = this.createTemplate(layout); if (freeform && layout) doc = this.createTemplate(layout, title); @@ -1019,7 +925,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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 }); + doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, 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 }); @@ -1084,14 +990,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> CollectionFreeFormDocumentView.setupScroll(tagDoc, 0); CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); } - let lastFrame: number = 0; - childDocs.forEach((doc) => { - if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame); - }); + // 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); + tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame)); if (tagDoc.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { @@ -1153,20 +1059,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> <div className="ribbon-box"> {this.stringType} selected - <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL ? "inline-flex" : "none" }}> + <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}> <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div> <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div> </div> - <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}> + <div className="ribbon-doubleButton" style={{ display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}> <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div> <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div> {/* <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div> */} </div> - <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}> + <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}> <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div> <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div> </div> - <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.PDF ? "inline-flex" : "none" }}> + <div className="ribbon-doubleButton" style={{ display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}> <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll progressivize</div> <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div> </div> @@ -1188,7 +1094,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> </div> <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip> </div> - <div className="ribbon-button" style={{ height: 20, backgroundColor: "#5a9edd" }} onClick={() => console.log("play frames")}>Play</div> + <div className="ribbon-button" style={{ height: 20, backgroundColor: "#5a9edd" }} onClick={() => console.log(" TODO: play frames")}>Play</div> </div> </div> </div> @@ -1298,9 +1204,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> 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; @@ -1350,9 +1254,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> const y: List<number> = 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); @@ -1630,7 +1531,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> @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); @@ -1638,9 +1538,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> doc.appearFrame = 0; } doc.appearFrame = appearFrame + 1; - const olist = new List<number>(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); - doc["opacity-indexed"] = olist; - console.log(doc.appearFrame); + this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame)); } @undoBatch @@ -1654,9 +1552,32 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> doc.appearFrame = 0; } doc.appearFrame = Math.max(0, appearFrame - 1); - const olist = new List<number>(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); - doc["opacity-indexed"] = olist; - console.log(doc.appearFrame); + this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame)); + } + + @action + updateOpacityList = (list: any, frame: number) => { + const x: List<number> = list; + if (x && x.length >= frame) { + for (let i = 0; i < x.length; i++) { + if (i < frame) { + x[i] = 0; + } else if (i >= frame) { + x[i] = 1; + } + } + list = x; + } else { + x.length = frame + 1; + for (let i = 0; i < x.length; i++) { + if (i < frame) { + x[i] = 0; + } else if (i >= frame) { + x[i] = 1; + } + } + list = x; + } } @computed get moreInfoDropdown() { @@ -1746,37 +1667,37 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}> - {/* <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Invalid}>Min</option> */} <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option> - {/* <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Time}>Time</option> */} <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel}>Slides</option> </select> <div className="presBox-presentPanel"> - <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ minWidth: 60, gridColumn: 2 }}> - <div className="presBox-button-left" onClick={() => this.startOrResetPres(0)}> - <FontAwesomeIcon icon={"clock"} /> - <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /> - </div> - <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}> - <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} /> - {this.playDropdown} - </div> - </span> - <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`} title="Present"> + <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}> <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}><FontAwesomeIcon icon={"play-circle"} /> Present </div> <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePresent(); }}> <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} /> {this.presentDropdown} </div> </span> - <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Back" onClick={this.back}> - <FontAwesomeIcon icon={"arrow-left"} /> - </div> - <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Next" onClick={this.next}> - <FontAwesomeIcon icon={"arrow-right"} /> - </div> - <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "edit" : ""}`} title="Next" onClick={() => this.layoutDoc.presStatus = "edit"}> - <FontAwesomeIcon icon={"times"} /> + <div className="miniPresOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}> + {/* <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`}> + <div className="presBox-button-left" onClick={() => this.startOrResetPres(0)}> + <FontAwesomeIcon icon={"clock"} /> + <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /> + </div> + <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}> + <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} /> + {this.playDropdown} + </div> + </span> */} + <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div> + <div className="miniPres-button" onClick={() => this.startOrResetPres(this.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div> + <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div> + <div className="miniPres-divider"></div> + <div className="miniPres-button-text">Slide {this.itemIndex + 1} / {this.childDocs.length}</div> + <div className="miniPres-divider"></div> + <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}> + <FontAwesomeIcon icon={"times"} /> + </div> </div> </div> </div> @@ -1809,14 +1730,4 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d 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<Doc>(this.childDocs.slice()); -// } - - +});
\ No newline at end of file diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index fc65f34eb..76d23ddfe 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -536,6 +536,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp Doc.AddDocToList(Cast(Doc.UserDoc()["template-notes"], Doc, null), "data", this.rootDoc); }, icon: "eye" }); + appearanceItems.push({ description: "Create progressivized slide...", event: this.progressivizeText, icon: "desktop" }); cm.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); const options = cm.findByDescription("Options..."); @@ -547,6 +548,69 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._downX = this._downY = Number.NaN; } + progressivizeText = () => { + const list = this.ProseRef?.getElementsByTagName("li"); + const mainBulletText: string[] = []; + const mainBulletList: Doc[] = []; + if (list) { + const newBullets: Doc[] = this.recursiveProgressivize(1, list); + mainBulletList.push.apply(mainBulletList, newBullets); + } + console.log(mainBulletList.length); + const title = Docs.Create.TextDocument(StrCast(this.rootDoc.title), { title: "Title", _width: 800, _height: 70, x: 20, y: -10, _fontSize: '20pt', backgroundColor: "rgba(0,0,0,0)", appearFrame: 0, _fontWeight: 700 }); + mainBulletList.push(title); + const doc = Docs.Create.FreeformDocument(mainBulletList, { + title: StrCast(this.rootDoc.title), + x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y) + NumCast(this.props.Document._height) + 10, + _width: 400, _height: 225, _fitToBox: true, + }); + this.props.addDocument?.(doc); + } + + recursiveProgressivize = (nestDepth: number, list: HTMLCollectionOf<HTMLLIElement>, d?: number, y?: number, before?: string): Doc[] => { + const mainBulletList: Doc[] = []; + let b = d ? d : 0; + let yLoc = y ? y : 0; + let nestCount = 0; + let count: string = before ? before : ''; + const fontSize: string = (16 - (nestDepth * 2)) + 'pt'; + const xLoc: number = (nestDepth * 20); + const width: number = 390 - xLoc; + const height: number = 55 - (nestDepth * 5); + for (let i = 0; i < list.length; i++) { + const mainBullets: number = Number(list[i].getAttribute("data-bulletstyle")); + if (mainBullets === nestDepth) { + if (list[i].childElementCount > 1) { + b++; + nestCount++; + count = before ? count + nestCount + "." : nestCount + "."; + yLoc += height; + const text = list[i].getElementsByTagName("p")[0].innerText; + const length = text.length; + console.log(yLoc); + const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b }); + mainBulletList.push(bullet1); + const newList = this.recursiveProgressivize(nestDepth + 1, list[i].getElementsByTagName("li"), b, yLoc, count); + mainBulletList.push.apply(mainBulletList, newList); + b += newList.length; + yLoc += newList.length * (55 - ((nestDepth + 1) * 5)); + } else { + b++; + nestCount++; + count = before ? count + nestCount + "." : nestCount + "."; + yLoc += height; + const text = list[i].innerText; + const length = text.length; + console.log(yLoc); + const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b }); + mainBulletList.push(bullet1); + } + } + } + console.log("b: " + b); + return mainBulletList; + } + recordDictation = () => { DictationManager.Controls.listen({ interimHandler: this.setCurrentBulletContent, @@ -1374,6 +1438,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"), pointerEvents: interactive ? undefined : "none", fontSize: Cast(this.layoutDoc._fontSize, "string", null), + fontWeight: Cast(this.layoutDoc._fontWeight, "number", null), fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"), transition: "opacity 1s" }} diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 159cb5f8a..fa70b2a41 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -2,7 +2,8 @@ display: grid; grid-template-columns: max-content max-content max-content; background-color: #d5dce2; - // box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.25); + font-family: Roboto; + letter-spacing: normal; position: relative; pointer-events: all; width: 100%; @@ -21,13 +22,30 @@ .presElementBox-highlight { position: absolute; - transform: translate(-100px, -6px); + transform: translate(-100px, -4px); z-index: -1; width: calc(100% + 200px); - height: calc(100% + 12px); + height: calc(100% + 8px); background-color: #AEDDF8; } + .presElementBox-highlightTop { + position: absolute; + transform: translate(-100px, -4px); + z-index: -1; + width: calc(100% + 200px); + height: calc(50% + 4px); + } + + .presElementBox-highlightBottom { + position: absolute; + transform: translate(-100px, 0px); + z-index: -1; + top: 50%; + width: calc(100% + 200px); + height: calc(50% + 4px); + } + .documentView-node { position: absolute; z-index: 1; @@ -79,8 +97,12 @@ .presElementBox-number { font-size: 12px; + width: 20; font-weight: 700; - left: -15; + text-align: right; + justify-content: center; + align-content: center; + left: -20; position: absolute; display: inline-block; overflow: hidden; @@ -110,9 +132,8 @@ font-size: 10; font-weight: 300; font-family: Roboto; - /* font-style: italic; */ + z-index: 300; letter-spacing: normal; - /* left: 10px; */ } .presElementBox-embedded { @@ -174,7 +195,7 @@ bottom: 3px; width: 20px; height: 20px; - z-index: 200; + z-index: 300; display: flex; background-color: black; color: white; diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index b3d8cca98..e035ed0b8 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -220,7 +220,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc let durationInS: number; if (this.targetDoc.presDuration) durationInS = NumCast(this.targetDoc.presDuration) / 1000; else durationInS = 2; - return "V: " + durationInS + "s"; + return "D: " + durationInS + "s"; } @computed get transition() { @@ -245,25 +245,61 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc } } + headerUp = (e: React.PointerEvent<HTMLDivElement>) => { + e.stopPropagation(); + e.preventDefault(); + DragManager.docsBeingDragged = []; + this._highlightTopRef.current!.style.borderBottom = "0px"; + this._highlightBottomRef.current!.style.borderBottom = "0px"; + } + startDrag = (e: PointerEvent, down: number[], delta: number[]) => { // const ele: HTMLElement[] = PresBox.Instance._eleArray.map(doc => doc); const activeItem = this.rootDoc; const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc)); // let value = this.getValue(this._heading); // value = typeof value === "string" ? `"${value}"` : value; + let dragItem: HTMLElement[] = []; + PresBox.Instance._dragArray.map(ele => { + const drag = ele; + drag.style.backgroundColor = "#d5dce2"; + drag.style.borderRadius = '5px'; + dragItem.push(drag); + }); if (activeItem) { - DragManager.StartDocumentDrag(PresBox.Instance._dragArray.map(ele => ele), dragData, e.clientX, e.clientY); + DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY); activeItem.dragging = true; return true; } return false; } + private _highlightTopRef: React.RefObject<HTMLDivElement> = React.createRef(); + private _highlightBottomRef: React.RefObject<HTMLDivElement> = React.createRef(); + onPointerTop = (e: React.PointerEvent<HTMLDivElement>) => { + if (DragManager.docsBeingDragged.length > 0) { + this._highlightTopRef.current!.style.borderTop = "solid 2px #5B9FDD"; + } + } + + onPointerBottom = (e: React.PointerEvent<HTMLDivElement>) => { + if (DragManager.docsBeingDragged.length > 0) { + this._highlightBottomRef.current!.style.borderBottom = "solid 2px #5B9FDD"; + } + } + + onPointerLeave = (e: React.PointerEvent<HTMLDivElement>) => { + if (DragManager.docsBeingDragged.length > 0) { + this._highlightBottomRef.current!.style.borderBottom = "0px"; + this._highlightTopRef.current!.style.borderTop = "0px"; + } + } + render() { const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree; - const className = "presElementBox-item" + (this.itemIndex === this.indexInPres ? " presElementBox-active" : ""); + const className = "presElementBox-item" + (PresBox.Instance._selectedArray.includes(this.rootDoc) ? " presElementBox-active" : ""); const pbi = "presElementBox-interaction"; return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : ( <div className={className} key={this.props.Document[Id] + this.indexInPres} @@ -288,6 +324,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc } }} onPointerDown={this.headerDown} + onPointerUp={this.headerUp} > <> <div className="presElementBox-number"> @@ -297,7 +334,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc {`${this.targetDoc?.title}`} </div> <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.transition}</div></Tooltip> - <Tooltip title={<><div className="dash-tooltip">{"Duration of visibility"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip> + <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip> <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div className="presElementBox-closeIcon" // onPointerDown={e => e.stopPropagation()} @@ -311,7 +348,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc <FontAwesomeIcon icon={(this.rootDoc.presExpandInlineButton ? "angle-up" : "angle-down")} onPointerDown={e => e.stopPropagation()} /> </div></Tooltip> </> - <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} /> + <div ref={this._highlightTopRef} onPointerOver={this.onPointerTop} onPointerLeave={this.onPointerLeave} className="presElementBox-highlightTop" style={{ zIndex: 299, backgroundColor: "rgba(0,0,0,0)" }} /> + <div ref={this._highlightBottomRef} onPointerOver={this.onPointerBottom} onPointerLeave={this.onPointerLeave} className="presElementBox-highlightBottom" style={{ zIndex: 299, backgroundColor: "rgba(0,0,0,0)" }} /> + <div className="presElementBox-highlight" style={{ backgroundColor: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "#AEDDF8" : "rgba(0,0,0,0)" }} /> <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}> <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} onPointerDown={e => e.stopPropagation()} /></button> <button title="Navigate" className={pbi + (this.rootDoc.presNavButton ? "-selected" : "")} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} /></button> |