From b92d5e0a6be06ad38a11cf347b49b52a1bee8822 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 25 Oct 2020 22:59:52 +0800 Subject: undo/redo for slider changes + updating options for pan / scroll pinned views --- src/client/views/PropertiesView.scss | 4 + src/client/views/PropertiesView.tsx | 12 ++- src/client/views/nodes/PresBox.tsx | 141 ++++++++++++++++++++++++----------- 3 files changed, 110 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 9fdc8bc47..ed3a82236 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -686,6 +686,10 @@ font-weight: 500; display: inline-flex; + .propertiesView-selectedCount { + + } + .propertiesView-selectedList { border-left: solid 1px darkgrey; margin-left: 10px; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index e93173c9e..65594b634 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -27,6 +27,7 @@ import { PresBox } from "./nodes/PresBox"; import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; +import { CollectionViewType } from "./collections/CollectionView"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -984,6 +985,9 @@ export class PropertiesView extends React.Component { if (this.isPres) { const selectedItem: boolean = PresBox.Instance?._selectedArray.length > 0; const type = PresBox.Instance.activeItem?.type; + const viewType = PresBox.Instance.activeItem?._viewType; + const pannable: boolean = (type === DocumentType.COL && viewType === CollectionViewType.Freeform) || type === DocumentType.IMG; + const scrollable: boolean = type === DocumentType.PDF || type === DocumentType.WEB || type === DocumentType.RTF || viewType === CollectionViewType.Stacking; return
Presentation @@ -991,7 +995,7 @@ export class PropertiesView extends React.Component {
{this.editableTitle}
- {PresBox.Instance?._selectedArray.length} selected +
{PresBox.Instance?._selectedArray.length} selected
{PresBox.Instance?.listOfSelected}
@@ -1023,12 +1027,12 @@ export class PropertiesView extends React.Component { {PresBox.Instance.progressivizeDropdown}
: null}
} */} - {!selectedItem || (type !== DocumentType.COL && type !== DocumentType.AUDIO) ? (null) :
+ {!selectedItem || (!scrollable && !pannable) ? (null) :
{ this.openSlideOptions = !this.openSlideOptions; })} style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}> -     {PresBox.Instance.stringType} options -
+     {scrollable ? "Scroll options" : "Pan options"} +
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 90a0b750c..628392b2f 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -19,7 +19,7 @@ import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DocumentManager } from "../../util/DocumentManager"; import { Scripting } from "../../util/Scripting"; import { SelectionManager } from "../../util/SelectionManager"; -import { undoBatch } from "../../util/UndoManager"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; import { TabDocView } from "../collections/TabDocView"; @@ -85,6 +85,14 @@ export class PresBox extends ViewBoxBaseComponent @observable private openEffectDropdown: boolean = false; @observable private presentTools: boolean = false; @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); } + @computed get tagDocs() { + const tagDocs: Doc[] = []; + for (const doc of this.childDocs) { + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + tagDocs.push(tagDoc) + } + return tagDocs; + } @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); } @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); } @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); } @@ -267,7 +275,7 @@ export class PresBox extends ViewBoxBaseComponent setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 1010); } }); - } else { + } else if (presTargetDoc) { presTargetDoc && runInAction(() => { if (activeItem.presMovement === PresMovement.Jump) presTargetDoc.focusSpeed = 0; else presTargetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; @@ -294,7 +302,7 @@ export class PresBox extends ViewBoxBaseComponent navigateToElement = async (curDoc: Doc) => { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const srcContext = await DocCastAsync(targetDoc.context); + const srcContext = await DocCastAsync(targetDoc?.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined; this.turnOffEdit(); @@ -319,8 +327,8 @@ export class PresBox extends ViewBoxBaseComponent self._eleArray.splice(0, self._eleArray.length, ...eleViewCache); }); const openInTab = () => { - collectionDocView ? collectionDocView.props.addDocTab(activeItem, "") : this.props.addDocTab(activeItem, ":left"); - this.layoutDoc.presCollection = activeItem; + collectionDocView ? collectionDocView.props.addDocTab(targetDoc, "") : this.props.addDocTab(targetDoc, ":left"); + this.layoutDoc.presCollection = targetDoc; // this still needs some fixing setTimeout(resetSelection, 500); }; @@ -368,9 +376,6 @@ export class PresBox extends ViewBoxBaseComponent // If website and has presWebsite data associated then on click it should // go back to that specific website // TODO: Add progressivize for navigating web (storing websites for given frames) - if (targetDoc.presWebsiteData) { - targetDoc.data = targetDoc.presWebsiteData; - } } /** @@ -418,7 +423,6 @@ export class PresBox extends ViewBoxBaseComponent } } - /** * For 'Hide Before' and 'Hide After' buttons making sure that * they are hidden each time the presentation is updated. @@ -429,14 +433,18 @@ export class PresBox extends ViewBoxBaseComponent const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc!, Doc, null); if (tagDoc) tagDoc.opacity = 1; - if (curDoc.presHideBefore) { + const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc); + const curInd: number = itemIndexes.indexOf(index); + if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { } + else if (curDoc.presHideBefore) { if (index > this.itemIndex) { tagDoc.opacity = 0; } else if (!curDoc.presHideAfter) { tagDoc.opacity = 1; } } - if (curDoc.presHideAfter) { + if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== (itemIndexes.length - 1)) { } + else if (curDoc.presHideAfter) { if (index < this.itemIndex) { tagDoc.opacity = 0; } else if (!curDoc.presHideBefore) { @@ -641,8 +649,9 @@ export class PresBox extends ViewBoxBaseComponent const list = this._selectedArray.map((doc: Doc, index: any) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc!, Doc, null); - if (tagDoc) return
{index + 1}. {curDoc.title}
; - if (curDoc) return
{index + 1}. {curDoc.title}
; + if (curDoc && curDoc === this.activeItem) return
{index + 1}. {curDoc.title}
+ else if (tagDoc) return
{index + 1}. {curDoc.title}
; + else if (curDoc) return
{index + 1}. {curDoc.title}
; }); return list; } @@ -788,12 +797,12 @@ export class PresBox extends ViewBoxBaseComponent } } - getAllIndexes = (arr: Doc[], val: Doc): number => { + getAllIndexes = (arr: Doc[], val: Doc): number[] => { var indexes = [], i; for (i = 0; i < arr.length; i++) if (arr[i] === val) indexes.push(i); - return indexes.length; + return indexes; } // Adds the index in the pres path graphically @@ -811,7 +820,7 @@ export class PresBox extends ViewBoxBaseComponent // Case A: Document is contained within the collection if (this.rootDoc.presCollection === srcContext) { if (docs.includes(tagDoc)) { - const prevOccurances: number = this.getAllIndexes(docs, tagDoc); + const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length; docs.push(tagDoc); order.push(
}); } + _batch: UndoManager.Batch | undefined = undefined; + + @computed get transitionDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; @@ -1010,11 +1022,6 @@ export class PresBox extends ViewBoxBaseComponent
Transition Speed
console.log('onInput')} - onDrag={() => console.log('onDrag')} - onDragEnd={() => console.log('onDragEnd')} - onBlur={() => console.log('onBlur')} - onCompositionEnd={() => console.log('onCompEnd')} type="number" value={transitionSpeed} onChange={action((e) => this.setTransitionTime(e.target.value))} /> s
@@ -1027,7 +1034,15 @@ export class PresBox extends ViewBoxBaseComponent
- ) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> + { this._batch = UndoManager.StartBatch("presTransition"); }} + onPointerUp={() => { if (this._batch) this._batch.end(); }} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + this.setTransitionTime(e.target.value); + }} />
Fast
Medium
@@ -1057,7 +1072,13 @@ export class PresBox extends ViewBoxBaseComponent
- ) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} /> + { this._batch = UndoManager.StartBatch("presDuration"); }} + onPointerUp={() => { if (this._batch) this._batch.end(); }} + onChange={(e: React.ChangeEvent) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} + />
Short
Medium
@@ -1168,13 +1189,45 @@ export class PresBox extends ViewBoxBaseComponent onChange={action((e: React.ChangeEvent) => { const val = e.target.value; activeItem.presEndTime = Number(val); })} />
: (null)} - {targetDoc.type === DocumentType.COL ? 'Presentation Pin View' : (null)} -
-
+
{activeItem.presPinView ? "Turn off pin with view" : "Pin with current view"}
}>
{ activeItem.presPinView = !activeItem.presPinView; targetDoc.presPinView = activeItem.presPinView; if (activeItem.presPinView) { + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { + const scroll = targetDoc._scrollTop; + activeItem.presPinView = true; + activeItem.presPinViewScroll = scroll; + } else if (targetDoc.type === DocumentType.VID) { + activeItem.presPinTimecode = targetDoc._currentTimecode; + } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinView = true; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const width = targetDoc._clipWidth; + activeItem.presPinClipWidth = width; + activeItem.presPinView = true; + } + } + }}>{presPinWithViewIcon}
+ {activeItem.presPinView ?
{"Update the pinned view with the view of the selected document"}
}>
{ + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { + const scroll = targetDoc._scrollTop; + activeItem.presPinViewScroll = scroll; + } else if (targetDoc.type === DocumentType.VID) { + activeItem.presPinTimecode = targetDoc._currentTimecode; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const clipWidth = targetDoc._clipWidth; + activeItem.presPinClipWidth = clipWidth; + } else { const x = targetDoc._panX; const y = targetDoc._panY; const scale = targetDoc._viewScale; @@ -1182,18 +1235,9 @@ export class PresBox extends ViewBoxBaseComponent activeItem.presPinViewY = y; activeItem.presPinViewScale = scale; } - }}>{presPinWithViewIcon}
- {activeItem.presPinView ?
{ - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - }}>Update
: (null)} + }}>Update
: (null)}
-
+ {this.panable ?
Pan X
@@ -1221,7 +1265,18 @@ export class PresBox extends ViewBoxBaseComponent onChange={action((e: React.ChangeEvent) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} />
-
+
: (null)} + {this.scrollable ?
+
+
Scroll
+
+ ) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} /> +
+
+
: (null)} {/*
Store original website
*/} @@ -1958,11 +2013,11 @@ export class PresBox extends ViewBoxBaseComponent @computed get playButtons() { // Case 1: There are still other frames and should go through all frames before going to next slide return (
-
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
+
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
-
+
{ this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
-
+
{ this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
250 ? "inline-flex" : "none" }}> Slide {this.itemIndex + 1} / {this.childDocs.length} @@ -1998,9 +2053,9 @@ export class PresBox extends ViewBoxBaseComponent
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
-
+
{ this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
-
+
{ this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
Slide {this.itemIndex + 1} / {this.childDocs.length} -- cgit v1.2.3-70-g09d2