From 223262242f7db021c8449e920645892cc5ed2820 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 17 Oct 2020 17:45:10 -0400 Subject: major rewrite of native width/height/aspect. Fixed scaling of text note sidebars. --- .../CollectionFreeFormLayoutEngines.tsx | 8 +++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 25 +++++++++++----------- 2 files changed, 16 insertions(+), 17 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index bc2cb2d20..edf473a90 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -241,10 +241,10 @@ export function computePivotLayout( val.docs.forEach((doc, i) => { const layoutDoc = Doc.Layout(doc); let wid = pivotAxisWidth; - let hgt = layoutDoc._nativeWidth ? (NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth)) * pivotAxisWidth : pivotAxisWidth; + let hgt = pivotAxisWidth / (Doc.NativeAspect(layoutDoc) || 1); if (hgt > pivotAxisWidth) { hgt = pivotAxisWidth; - wid = layoutDoc._nativeHeight ? (NumCast(layoutDoc._nativeWidth) / NumCast(layoutDoc._nativeHeight)) * pivotAxisWidth : pivotAxisWidth; + wid = (Doc.NativeAspect(layoutDoc) || 1) * pivotAxisWidth; } docMap.set(doc[Id] + (val.replicas || ""), { x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2 + (val.docs.length < numCols ? (numCols - val.docs.length) * pivotAxisWidth / 2 : 0), @@ -368,10 +368,10 @@ export function computeTimelineLayout( const stack = findStack(x, stacking); const layoutDoc = Doc.Layout(doc); let wid = pivotAxisWidth; - let hgt = layoutDoc._nativeWidth ? (NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth)) * pivotAxisWidth : pivotAxisWidth; + let hgt = pivotAxisWidth / (Doc.NativeAspect(layoutDoc) || 1); if (hgt > pivotAxisWidth) { hgt = pivotAxisWidth; - wid = layoutDoc._nativeHeight ? (NumCast(layoutDoc._nativeWidth) / NumCast(layoutDoc._nativeHeight)) * pivotAxisWidth : pivotAxisWidth; + wid = (Doc.NativeAspect(layoutDoc) || 1) * pivotAxisWidth; } docMap.set(doc[Id], { x: x, y: -Math.sqrt(stack) * pivotAxisWidth / 2 - pivotAxisWidth + (pivotAxisWidth - hgt) / 2, diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b32a3bd52..c863addd2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -105,11 +105,11 @@ export class CollectionFreeFormView extends CollectionSubView e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); } - @computed get nativeWidth() { return this.fitToContent ? 0 : returnVal(this.props.NativeWidth?.(), NumCast(this.Document._nativeWidth)); } - @computed get nativeHeight() { return this.fitToContent ? 0 : returnVal(this.props.NativeHeight?.(), NumCast(this.Document._nativeHeight)); } + @computed get nativeWidth() { return this.fitToContent ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); } + @computed get nativeHeight() { return this.fitToContent ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.Document)); } private get isAnnotationOverlay() { return this.props.isAnnotationOverlay; } private get scaleFieldKey() { return this.props.scaleField || "_viewScale"; } private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; } @@ -120,7 +120,7 @@ export class CollectionFreeFormView extends CollectionSubView { - const pw = this.isAnnotationOverlay ? NumCast(this.props.Document._nativeWidth) : this.props.PanelWidth(); - const ph = this.isAnnotationOverlay ? NumCast(this.props.Document._nativeHeight) : this.props.PanelHeight(); + const pw = this.isAnnotationOverlay ? Doc.NativeWidth(this.props.Document) : this.props.PanelWidth(); + const ph = this.isAnnotationOverlay ? Doc.NativeHeight(this.props.Document) : this.props.PanelHeight(); pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height))); } @@ -979,7 +979,6 @@ export class CollectionFreeFormView extends CollectionSubView Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" }); if (!Doc.UserDoc().noviceMode) { - optionItems.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" }); + optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" }); optionItems.push({ description: `${this.Document._freeformLOD ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._freeformLOD = !this.Document._freeformLOD, icon: "table" }); } @@ -1454,8 +1453,8 @@ export class CollectionFreeFormView extends CollectionSubView Date: Sat, 17 Oct 2020 22:01:53 -0400 Subject: fixed rubberbadning ink shapes not to get cutoff. fixed animating annotations. fixed ink masks. fixed warnings. --- src/client/views/InkingStroke.tsx | 4 +--- src/client/views/collections/CollectionMenu.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 ++++-- src/client/views/nodes/PresBox.tsx | 12 ++++++------ src/client/views/pdf/PDFViewer.tsx | 6 +++++- src/server/websocket.ts | 4 ++-- 6 files changed, 19 insertions(+), 15 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 186406424..7e424d8f0 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -38,7 +38,7 @@ export class InkingStroke extends ViewBoxBaseComponent pair.layout).slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex)); zsorted.forEach((doc, index) => doc.zIndex = doc.isInkMask ? 5000 : index + 1); - const dropPos = [NumCast(docDragData.droppedDocuments[0].x), NumCast(docDragData.droppedDocuments[0].y)]; + const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000)); + const dropPos = this.Document._currentFrame !== undefined ? [dvals.x, dvals.y] : [NumCast(refDoc.x), NumCast(refDoc.y)]; for (let i = 0; i < docDragData.droppedDocuments.length; i++) { const d = docDragData.droppedDocuments[i]; const layoutDoc = Doc.Layout(d); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 3b7794815..01a7bed8c 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -288,7 +288,7 @@ export class PresBox extends ViewBoxBaseComponent const willZoom = false; const openInTab = () => { collectionDocView ? collectionDocView.props.addDocTab(activeItem, "replace") : this.props.addDocTab(activeItem, "replace:left"); - } + }; // If openDocument is selected then it should open the document for the user if (activeItem.openDocument) { openInTab(); @@ -299,10 +299,10 @@ export class PresBox extends ViewBoxBaseComponent } else if (docToJump === curDoc) { //checking if curDoc has navigation open if (curDoc.presMovement === PresMovement.Pan && targetDoc) { - await DocumentManager.Instance.jumpToDocument(targetDoc, false, () => { openInTab() }, srcContext); // documents open in new tab instead of on right + await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext); // documents open in new tab instead of on right } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(targetDoc, true, () => { openInTab() }, srcContext); // documents open in new tab instead of on right + await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext); // documents open in new tab instead of on right } } else { //awaiting jump so that new scale can be found, since jumping is async @@ -442,7 +442,7 @@ export class PresBox extends ViewBoxBaseComponent } } }; - this.layoutDoc.presStatus = PresStatus.Auto; + this.layoutDoc.presStatus = PresStatus.Autoplay; this.startPresentation(startSlide); this.gotoDocument(startSlide, this.itemIndex); load(); @@ -450,7 +450,7 @@ export class PresBox extends ViewBoxBaseComponent @action pauseAutoPres = () => { - if (this.layoutDoc.presStatus === PresStatus.Auto) { + if (this.layoutDoc.presStatus === PresStatus.Autoplay) { if (this._presTimer) clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; this.layoutDoc.presLoop = false; @@ -611,7 +611,7 @@ export class PresBox extends ViewBoxBaseComponent return true; } childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement; - removeDocument = (doc: Doc) => { return Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); }; + removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground) && diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index d278612b1..76b218972 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -730,7 +730,11 @@ export class PDFViewer extends ViewBoxAnnotatableComponent this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); @computed get overlayLayer() { return
+ style={{ + pointerEvents: SnappingManager.GetIsDragging() ? "all" : undefined, + mixBlendMode: this.allAnnotations.some(anno => anno.mixBlendMode) ? "hard-light" : undefined, + transform: `scale(${this._zoomed})` + }}> !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))]; + const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields.filter((item: any) => item !== undefined) || []; + diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => newItem && !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))]; const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length; delete diff.diff.length; Database.Instance.update(diff.id, diff.diff, -- cgit v1.2.3-70-g09d2 From 65940c176cca651bf4bfface9be5d86d49c881c6 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Tue, 20 Oct 2020 18:21:05 +0800 Subject: presBox updates for pull drag changes + renaming marquee options + fixes --- src/client/views/DocumentButtonBar.tsx | 46 ++++++++----- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 2 +- src/client/views/nodes/PresBox.scss | 1 + src/client/views/nodes/PresBox.tsx | 78 +++++++++++++--------- .../views/presentationview/PresElementBox.scss | 77 ++++++++++++++++++--- .../views/presentationview/PresElementBox.tsx | 75 +++++++++++++-------- 6 files changed, 194 insertions(+), 85 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 076502042..ed248c473 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -26,6 +26,7 @@ import { TemplateMenu } from "./TemplateMenu"; import React = require("react"); import { PresBox } from './nodes/PresBox'; import { undoBatch } from '../util/UndoManager'; +import { CollectionViewType } from './collections/CollectionView'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -186,7 +187,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV get pinButton() { const targetDoc = this.view0?.props.Document; const isPinned = targetDoc && Doc.isDocPinned(targetDoc); - return !targetDoc ? (null) :
{"Pin to presentation"}
}> + return !targetDoc ? (null) :
{SelectionManager.SelectedDocuments().length > 1 ? "Pin multiple documents to presentation" : "Pin to presentation"}
}>
this.props.views().map(view => view && TabDocView.PinDoc(view.props.Document, false)))}> @@ -194,25 +195,40 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
; } + @undoBatch + @action + pinWithView = (targetDoc: Doc) => { + if (targetDoc) { + TabDocView.PinDoc(targetDoc, false); + const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1]; + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { + const scroll = targetDoc._scrollTop; + activeDoc.presPinView = true; + activeDoc.presPinViewScroll = scroll; + } 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; + activeDoc.presPinView = true; + activeDoc.presPinViewX = x; + activeDoc.presPinViewY = y; + activeDoc.presPinViewScale = scale; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const width = targetDoc._clipWidth; + activeDoc.presPinClipWidth = width; + activeDoc.presPinView = true; + } + } + } + @computed get pinWithViewButton() { const presPinWithViewIcon = ; const targetDoc = this.view0?.props.Document; return !targetDoc ? (null) :
{"Pin with current view"}
}> -
{ - if (targetDoc) { - TabDocView.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; - } - })}> +
this.pinWithView(targetDoc)}> {presPinWithViewIcon}
; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index fd4fa0c7e..d8e44e781 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -54,7 +54,7 @@ export class MarqueeOptionsMenu extends AntimodeMenu { , -
Pin with selected view
} placement="bottom"> +
Pin the selected region to presentation
} placement="bottom">
-
; + ); } @computed get selectedDocumentView() { @@ -425,7 +426,7 @@ export class CollectionViewBaseChrome extends React.Component; const targetDoc = this.selectedDoc; {/* return (!targetDoc || (targetDoc._viewType !== CollectionViewType.Freeform && targetDoc.type !== DocumentType.IMG)) ? (null) :
{"Pin to presentation trail with current view"}
} placement="top"> */ } - return (targetDoc && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top"> + return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top"> diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index f95c21972..42a601aa2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -397,7 +397,7 @@ export class MarqueeView extends React.Component this._pathBoolean = false; srcContext.presPathView = false; } else { - undoBatch(() => { - runInAction(() => this._pathBoolean = !this._pathBoolean); - srcContext.presPathView = this._pathBoolean; - }) + runInAction(() => this._pathBoolean = !this._pathBoolean); + srcContext.presPathView = this._pathBoolean; } } @@ -562,8 +560,26 @@ export class PresBox extends ViewBoxBaseComponent * When the movement dropdown is changes */ @undoBatch - updateMovement = action((movement: any) => { - if (this._selectedArray) this._selectedArray.forEach((doc) => { + updateMovement = action((movement: any, all?: boolean) => { + if (all) { + this.childDocs.forEach((doc) => { + switch (movement) { + case PresMovement.Zoom: //Pan and zoom + doc.presMovement = PresMovement.Zoom; + break; + case PresMovement.Pan: //Pan + doc.presMovement = PresMovement.Pan; + break; + case PresMovement.Jump: //Jump Cut + doc.presJump = true; + doc.presMovement = PresMovement.Jump; + break; + case PresMovement.None: default: + doc.presMovement = PresMovement.None; + break; + } + }) + } else if (this._selectedArray) this._selectedArray.forEach((doc) => { switch (movement) { case PresMovement.Zoom: //Pan and zoom doc.presMovement = PresMovement.Zoom; @@ -1008,6 +1024,7 @@ export class PresBox extends ViewBoxBaseComponent applyTo = (array: Doc[]) => { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; + this.updateMovement(activeItem.presMovement, true); array.forEach((doc) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); @@ -1016,9 +1033,6 @@ export class PresBox extends ViewBoxBaseComponent curDoc.presDuration = activeItem.presDuration; tagDoc.presEffect = targetDoc.presEffect; tagDoc.presEffectDirection = targetDoc.presEffectDirection; - tagDoc.presMovement = targetDoc.presMovement; - curDoc.presMovement = activeItem.presMovement; - this.updateMovement(activeItem.presMovement, curDoc, tagDoc); curDoc.presHideTillShownButton = activeItem.presHideTillShownButton; curDoc.presHideAfterButton = activeItem.presHideAfterButton; } @@ -1033,12 +1047,12 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-
+
activeItem.playAuto = !activeItem.playAuto}>Play automatically
activeItem.playAuto = !activeItem.playAuto}>Play on next
- {targetDoc.type === DocumentType.VID ?
activeItem.presVidFullScreen = !activeItem.presVidFullScreen}>Full screen
: (null)} - {targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.AUDIO ?
+ {/* {targetDoc.type === DocumentType.VID ?
activeItem.presVidFullScreen = !activeItem.presVidFullScreen}>Full screen
: (null)} */} + {targetDoc.type === DocumentType.AUDIO ?
Start time
onChange={action((e: React.ChangeEvent) => { activeItem.presStartTime = Number(e.target.value); })} />
: (null)} - {targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.AUDIO ?
+ {targetDoc.type === DocumentType.AUDIO ?
End time
Date: Tue, 20 Oct 2020 23:36:45 -0400 Subject: fixes for overlayDocs for undo/redo in presBox - undo/redo of minimize/show sidebar. --- src/client/util/CurrentUserUtils.ts | 1 + src/client/views/OverlayView.tsx | 9 ++------- .../collectionFreeForm/CollectionFreeFormView.tsx | 5 +++-- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/client/views/nodes/PresBox.tsx | 19 +++++++++---------- src/fields/documentSchemas.ts | 1 - 6 files changed, 19 insertions(+), 24 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f43b6df44..38bfe3fb6 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1190,6 +1190,7 @@ export class CurrentUserUtils { public static get MyRecentlyClosed() { return Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc, null); } public static get MyDashboards() { return Cast(Doc.UserDoc().myDashboards, Doc, null); } public static get EmptyPane() { return Cast(Doc.UserDoc().emptyPane, Doc, null); } + public static get OverlayDocs() { return DocListCast((Doc.UserDoc().myOverlayDocs as Doc)?.data); } } Scripting.addGlobal(function openDragFactory(dragFactory: Doc) { diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index b40c9edfb..7d47abdce 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -14,6 +14,7 @@ import { Scripting } from "../util/Scripting"; import { ScriptingRepl } from './ScriptingRepl'; import { DragManager } from "../util/DragManager"; import { List } from "../../fields/List"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; export type OverlayDisposer = () => void; @@ -146,12 +147,7 @@ export class OverlayView extends React.Component { @computed get overlayDocs() { - const userDocOverlays = Doc.UserDoc().myOverlayDocs; - if (!userDocOverlays) { - return null; - } - return userDocOverlays instanceof Doc && DocListCast(userDocOverlays.data).map(d => { - setTimeout(() => d.inOverlay = true, 0); + return CurrentUserUtils.OverlayDocs?.map(d => { let offsetx = 0, offsety = 0; const dref = React.createRef(); const onPointerMove = action((e: PointerEvent, down: number[]) => { @@ -161,7 +157,6 @@ export class OverlayView extends React.Component { } if (e.metaKey) { const dragData = new DragManager.DocumentDragData([d]); - d.removeDropProperties = new List(["inOverlay"]); dragData.offset = [-offsetx, -offsety]; dragData.dropAction = "move"; dragData.removeDocument = (doc: Doc | Doc[]) => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 56624f42d..fdcfb00d8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -46,6 +46,7 @@ import "./CollectionFreeFormView.scss"; import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); +import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; export const panZoomSchema = createSchema({ _panX: "number", @@ -803,7 +804,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay || this.props.Document.treeViewOutlineMode) return; + if (this.layoutDoc._lockedTransform || CurrentUserUtils.OverlayDocs.includes(this.props.Document) || this.props.Document.treeViewOutlineMode) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -839,7 +840,7 @@ export class CollectionFreeFormView extends CollectionSubView(Docu this._downX = touch.clientX; this._downY = touch.clientY; if (!e.nativeEvent.cancelBubble) { - if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation(); + if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) e.stopPropagation(); this.removeMoveListeners(); this.addMoveListeners(); this.removeEndListeners(); @@ -438,7 +438,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { this.removeMoveListeners(); } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { const touch = me.touchEvent.changedTouches.item(0); if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { @@ -554,7 +554,7 @@ export class DocumentView extends DocComponent(Docu if ((this.active || this.layoutDoc.onDragStart) && !e.ctrlKey && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && - !this.layoutDoc.inOverlay) { + !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { e.stopPropagation(); if (SelectionManager.IsSelected(this, true) && this.layoutDoc._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it } @@ -573,7 +573,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView) } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 53b2433e8..9723937a7 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -520,11 +520,10 @@ export class PresBox extends ViewBoxBaseComponent @action updateMinimize = () => { const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc); - if (this.layoutDoc.inOverlay) { + if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.layoutDoc.presStatus = PresStatus.Edit; Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); CollectionDockingView.AddSplit(this.rootDoc, "right"); - this.layoutDoc.inOverlay = false; } else if (this.layoutDoc.context && docView) { this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); @@ -716,7 +715,7 @@ export class PresBox extends ViewBoxBaseComponent const anchorNode = document.activeElement as HTMLDivElement; if (anchorNode && anchorNode.className?.includes("lm_title")) return; if (e.keyCode === 27) { // Escape key - if (this.layoutDoc.inOverlay) { this.updateMinimize(); } + if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.updateMinimize(); } else if (this.layoutDoc.presStatus === "edit") { this._selectedArray = []; this._eleArray = []; this._dragArray = []; } else this.layoutDoc.presStatus = "edit"; if (this._presTimer) clearTimeout(this._presTimer); @@ -1360,10 +1359,10 @@ export class PresBox extends ViewBoxBaseComponent @computed get presentDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
{ this.updateMinimize(); this.turnOffEdit(true); }))}> +
{ this.updateMinimize(); this.turnOffEdit(true); })))}> Minimize
-
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); }))}> +
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); })))}> Sidebar view
@@ -1949,8 +1948,8 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
- {this.props.PanelWidth() > 250 ?
{ this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }}>EXIT
- :
this.layoutDoc.presStatus = "edit"}> + {this.props.PanelWidth() > 250 ?
{ this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
+ :
this.layoutDoc.presStatus = "edit"))}>
}
); @@ -1968,7 +1967,7 @@ export class PresBox extends ViewBoxBaseComponent // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; - return this.layoutDoc.inOverlay ? + return CurrentUserUtils.OverlayDocs.includes(this.rootDoc) ?
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
@@ -1982,11 +1981,11 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
-
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }}>EXIT
+
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
: -
+
{this.topPanel} {this.toolbar} {this.newDocumentToolbarDropdown} diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 71294c59c..311aaa769 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -19,7 +19,6 @@ export const documentSchema = createSchema({ activeFrame: "number", // the active frame of a frame based animated document _currentTimecode: "number", // current play back time of a temporal document (video / audio) displayTimecode: "number", // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) - inOverlay: "boolean", // whether the document is rendered in an OverlayView which handles selection/dragging differently isLabel: "boolean", // whether the document is a label or not (video / audio) audioStart: "number", // the time frame where the audio should begin playing audioEnd: "number", // the time frame where the audio should stop playing -- cgit v1.2.3-70-g09d2 From a714d27782c454874a2ea6206f29ed0c5058ead2 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sat, 24 Oct 2020 13:40:51 +0800 Subject: add slide title and fix shift-arrow selection --- src/client/views/collections/TabDocView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 29 ++++++++++++++-------- .../views/presentationview/PresElementBox.scss | 2 -- 4 files changed, 21 insertions(+), 14 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 5bdf19a31..1ab8065b4 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -130,7 +130,7 @@ export class TabDocView extends React.Component { const batch = UndoManager.StartBatch("pinning doc"); const pinDoc = Doc.MakeAlias(doc); pinDoc.presentationTargetDoc = doc; - pinDoc.title = doc.title; + pinDoc.title = doc.title + " - slide"; pinDoc.presMovement = PresMovement.Zoom; pinDoc.context = curPres; Doc.AddDocToList(curPres, "data", pinDoc); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 42a601aa2..292ddb19a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -397,7 +397,7 @@ export class MarqueeView extends React.Component const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null); const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); - const currentFrame = Cast(targetDoc._currentFrame, "number", null); - const lastFrame = Cast(targetDoc.lastFrame, "number", null); - const curFrame = NumCast(targetDoc._currentFrame); + const currentFrame = Cast(targetDoc?._currentFrame, "number", null); + const lastFrame = Cast(targetDoc?.lastFrame, "number", null); + const curFrame = NumCast(targetDoc?._currentFrame); let internalFrames: boolean = false; if (activeItem.presProgressivize || activeItem.zoomProgressivize || targetDoc.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) { + const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); targetDoc._viewTransition = "all 1s"; setTimeout(() => targetDoc._viewTransition = undefined, 1010); // targetDoc._currentFrame = curFrame + 1; @@ -317,8 +317,6 @@ export class PresBox extends ViewBoxBaseComponent // this still needs some fixing setTimeout(resetSelection, 500); }; - const tabMap = CollectionDockingView.Instance.tabMap; - console.log(tabMap); // If openDocument is selected then it should open the document for the user if (activeItem.openDocument) { openInTab(); @@ -728,7 +726,9 @@ export class PresBox extends ViewBoxBaseComponent break; case "Down": case "ArrowDown": case "Right": case "ArrowRight": + if (this.itemIndex >= this.childDocs.length - 1) return; if (e.shiftKey) { // TODO: update to work properly + console.log("Down: " + this.rootDoc._itemIndex, this.itemIndex, this.childDocs.length) this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1; this._selectedArray.push(this.childDocs[this.rootDoc._itemIndex]); } else { @@ -739,7 +739,9 @@ export class PresBox extends ViewBoxBaseComponent break; case "Up": case "ArrowUp": case "Left": case "ArrowLeft": + if (this.itemIndex === 0) return; if (e.shiftKey) { // TODO: update to work properly + console.log("Up: " + this.rootDoc._itemIndex, this.itemIndex, this.childDocs.length) this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1; this._selectedArray.push(this.childDocs[this.rootDoc._itemIndex]); } else { @@ -795,21 +797,28 @@ export class PresBox extends ViewBoxBaseComponent if (docs.includes(tagDoc)) { docs.push(tagDoc); order.push( -
+
{index + 1}
); } else { docs.push(tagDoc); order.push( -
+
{index + 1}
); } - // Case B: Document is not inside of the collection + // Case B: Document is presPinView and is presCollection + } else if (doc.pinWithView && this.rootDoc.presCollection === tagDoc) { + docs.push(tagDoc); + order.push( +
+
{index + 1}
+
); + // Case C: Document is not contained within presCollection } else { docs.push(tagDoc); order.push( -
+
{index + 1}
); } diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 00ba5f9bb..919142975 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -64,7 +64,6 @@ $slide-active: #5B9FDD; text-overflow: ellipsis; overflow: hidden; white-space: pre; - transition: 500ms; } .presItem-docName { @@ -82,7 +81,6 @@ $slide-active: #5B9FDD; text-overflow: ellipsis; overflow: hidden; white-space: pre; - transition: 500ms; grid-row: 2; grid-column: 1/6; } -- cgit v1.2.3-70-g09d2 From 98a39486cc1a6c9cc272aa5a8d69bf4fd3e7b6bc Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 25 Oct 2020 05:12:48 +0800 Subject: code cleanup and changes - fix open in new tab bug changed from replace --- src/client/views/collections/TabDocView.tsx | 3 +- .../collections/collectionFreeForm/MarqueeView.tsx | 3 +- src/client/views/nodes/PresBox.tsx | 300 +++++++++------------ .../views/presentationview/PresElementBox.scss | 1 - .../views/presentationview/PresElementBox.tsx | 6 +- 5 files changed, 139 insertions(+), 174 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 1ab8065b4..fd91d4841 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -127,10 +127,11 @@ export class TabDocView extends React.Component { //add this new doc to props.Document const curPres = CurrentUserUtils.ActivePresentation; if (curPres) { + if (doc === curPres) { alert("Cannot pin presentation document to itself"); return; } const batch = UndoManager.StartBatch("pinning doc"); const pinDoc = Doc.MakeAlias(doc); pinDoc.presentationTargetDoc = doc; - pinDoc.title = doc.title + " - slide"; + pinDoc.title = doc.title + " - Slide"; pinDoc.presMovement = PresMovement.Zoom; pinDoc.context = curPres; Doc.AddDocToList(curPres, "data", pinDoc); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 292ddb19a..c6d1c9da2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -393,11 +393,12 @@ export class MarqueeView extends React.Component; @@ -84,7 +86,7 @@ export class PresBox extends ViewBoxBaseComponent @observable private presentTools: boolean = false; @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); } @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); } - @computed get activeItem() { return Cast(this.childDocs[this.itemIndex], Doc, null); } + @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); } @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); } @computed get scrollable(): boolean { if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true; @@ -100,7 +102,7 @@ export class PresBox extends ViewBoxBaseComponent if (Doc.UserDoc().activePresentation = this.rootDoc) 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" + title: "pres element template", type: DocumentType.PRESELEMENT, 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 @@ -113,7 +115,7 @@ export class PresBox extends ViewBoxBaseComponent } @computed get selectedDocumentView() { if (SelectionManager.SelectedDocuments().length) return SelectionManager.SelectedDocuments()[0]; - if (PresBox.Instance?._selectedArray) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); + if (this._selectedArray) return DocumentManager.Instance.getDocumentView(this.rootDoc); return undefined; } @computed get isPres(): boolean { @@ -131,6 +133,7 @@ export class PresBox extends ViewBoxBaseComponent componentWillUnmount() { document.removeEventListener("keydown", this.keyEvents, true); this._presKeyEventsActive = false; + this.resetPresentation(); // Turn of progressivize editors this.turnOffEdit(true); } @@ -151,12 +154,24 @@ export class PresBox extends ViewBoxBaseComponent !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc)); } - updateCurrentPresentation = () => { - Doc.UserDoc().activePresentation = this.rootDoc; + updateCurrentPresentation = (pres?: Doc) => { + if (pres && pres.type === DocumentType.PRES) { + Doc.UserDoc().activePresentation = pres; + this.selectPres(pres); + } else { + Doc.UserDoc().activePresentation = this.rootDoc; + this.selectPres(); + } document.removeEventListener("keydown", this.keyEvents, true); document.addEventListener("keydown", this.keyEvents, true); - this.selectPres(); PresBox.Instance = this; + if (Doc.UserDoc().activePresentation !== this.rootDoc) { + PresBox.Instance.forceUpdate(); + } + console.log("PresBox.Instance: " + PresBox.Instance) + console.log("Active item title: " + this.activeItem.title) + console.log("ChildDocs length: " + this.childDocs.length) + console.log("rootDoc.title: " + this.rootDoc.title) } /** @@ -202,9 +217,9 @@ export class PresBox extends ViewBoxBaseComponent if (targetNext.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeNext.presStartTime)); // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() }; } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } - this.gotoDocument(nextSelected, this.itemIndex); + this.gotoDocument(nextSelected); } else if (this.childDocs[this.itemIndex + 1] === undefined && this.layoutDoc.presLoop) { - this.gotoDocument(0, this.itemIndex); + this.gotoDocument(0); } } @@ -229,15 +244,14 @@ export class PresBox extends ViewBoxBaseComponent } else if (activeItem) { let prevSelected = this.itemIndex; prevSelected = Math.max(0, prevSelected - 1); - this.gotoDocument(prevSelected, this.itemIndex); + this.gotoDocument(prevSelected); if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc._currentFrame = NumCast(prevTargetDoc.lastFrame); } } //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(); + public gotoDocument = action((index: number) => { Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; @@ -263,9 +277,8 @@ export class PresBox extends ViewBoxBaseComponent if (presTargetDoc?.lastFrame !== undefined) { presTargetDoc._currentFrame = 0; } - this._selectedArray.splice(0, this._selectedArray.length, this.childDocs[index]); //Update selected array - //Handles movement to element - if (this.layoutDoc._viewType === "stacking") this.navigateToElement(this.childDocs[index]); + this._selectedArray.splice(0, this._selectedArray.length, this.childDocs[index]); //Updates selected array + if (this.layoutDoc._viewType === "stacking") this.navigateToElement(this.childDocs[index]); // Handles movement to element this.onHideDocument(); //Handles hide after/before } }); @@ -290,13 +303,6 @@ export class PresBox extends ViewBoxBaseComponent this.layoutDoc.presCollection = srcContext; } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; } - // if (collectionDocView) { - // 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"); - // } - // } - this.updateCurrentPresentation(); const docToJump = curDoc; const willZoom = false; const presStatus = this.rootDoc.presStatus; @@ -313,7 +319,8 @@ export class PresBox extends ViewBoxBaseComponent self._eleArray.splice(0, self._eleArray.length, ...eleViewCache); }); const openInTab = () => { - collectionDocView ? collectionDocView.props.addDocTab(activeItem, "replace") : this.props.addDocTab(activeItem, "replace:left"); + collectionDocView ? collectionDocView.props.addDocTab(activeItem, "") : this.props.addDocTab(activeItem, ":left"); + this.layoutDoc.presCollection = activeItem; // this still needs some fixing setTimeout(resetSelection, 500); }; @@ -422,17 +429,17 @@ 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.presHideTillShownButton) { + if (curDoc.presHideBefore) { if (index > this.itemIndex) { tagDoc.opacity = 0; - } else if (!curDoc.presHideAfterButton) { + } else if (!curDoc.presHideAfter) { tagDoc.opacity = 1; } } - if (curDoc.presHideAfterButton) { + if (curDoc.presHideAfter) { if (index < this.itemIndex) { tagDoc.opacity = 0; - } else if (!curDoc.presHideTillShownButton) { + } else if (!curDoc.presHideBefore) { tagDoc.opacity = 1; } } @@ -473,7 +480,7 @@ export class PresBox extends ViewBoxBaseComponent }; this.layoutDoc.presStatus = PresStatus.Autoplay; this.startPresentation(startSlide); - this.gotoDocument(startSlide, this.itemIndex); + this.gotoDocument(startSlide); load(); } @@ -489,8 +496,8 @@ export class PresBox extends ViewBoxBaseComponent //The function that resets the presentation by removing every action done by it. It also //stops the presentaton. resetPresentation = () => { - this.updateCurrentPresentation(); this.rootDoc._itemIndex = 0; + for (const doc of this.childDocs) Cast(doc.presentationTargetDoc, Doc, null).opacity = 1; } @action togglePath = (srcContext: Doc, off?: boolean) => { @@ -519,10 +526,10 @@ export class PresBox extends ViewBoxBaseComponent this.updateCurrentPresentation(); this.childDocs.map(doc => { const tagDoc = doc.presentationTargetDoc as Doc; - if (doc.presHideTillShownButton && this.childDocs.indexOf(doc) > startIndex) { + if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) { tagDoc.opacity = 0; } - if (doc.presHideAfterButton && this.childDocs.indexOf(doc) < startIndex) { + if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) { tagDoc.opacity = 0; } }); @@ -641,17 +648,18 @@ export class PresBox extends ViewBoxBaseComponent } @action - selectPres = () => { - const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc)!; + selectPres = (pres?: Doc) => { + const presDocView = DocumentManager.Instance.getDocumentView(pres ? pres : this.rootDoc)!; SelectionManager.SelectDoc(presDocView, false); } //Regular click @action selectElement = (doc: Doc) => { - this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex)); - if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(), 0); - else this.updateCurrentPresentation(); + const context = Cast(doc.context, Doc, null) + this.gotoDocument(this.childDocs.indexOf(doc)); + if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0); + else this.updateCurrentPresentation(context); } //Command click @@ -728,12 +736,12 @@ export class PresBox extends ViewBoxBaseComponent case "Right": case "ArrowRight": if (this.itemIndex >= this.childDocs.length - 1) return; if (e.shiftKey) { // TODO: update to work properly - console.log("Down: " + this.rootDoc._itemIndex, this.itemIndex, this.childDocs.length) + // console.log("Down: " + this.rootDoc._itemIndex, this.itemIndex, this.childDocs.length) this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1; this._selectedArray.push(this.childDocs[this.rootDoc._itemIndex]); } else { this.next(); - if (this._presTimer) clearTimeout(this._presTimer); + if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } } handled = true; break; @@ -741,22 +749,22 @@ export class PresBox extends ViewBoxBaseComponent case "Left": case "ArrowLeft": if (this.itemIndex === 0) return; if (e.shiftKey) { // TODO: update to work properly - console.log("Up: " + this.rootDoc._itemIndex, this.itemIndex, this.childDocs.length) + // console.log("Up: " + this.rootDoc._itemIndex, this.itemIndex, this.childDocs.length) this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1; this._selectedArray.push(this.childDocs[this.rootDoc._itemIndex]); } else { this.back(); - if (this._presTimer) clearTimeout(this._presTimer); + if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } } handled = true; break; case "Spacebar": case " ": - if (this.layoutDoc.presStatus === "manual") this.startAutoPres(this.itemIndex); - else if (this.layoutDoc.presStatus === "auto") if (this._presTimer) clearTimeout(this._presTimer); + if (this.layoutDoc.presStatus === PresStatus.Manual) this.startAutoPres(this.itemIndex); + else if (this.layoutDoc.presStatus === PresStatus.Autoplay) if (this._presTimer) clearTimeout(this._presTimer); handled = true; break; case "a": - if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === "edit") { + if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === PresStatus.Edit) { this._selectedArray.splice(0, this._selectedArray.length, ...this.childDocs); handled = true; } @@ -780,11 +788,18 @@ export class PresBox extends ViewBoxBaseComponent } } + 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; + } + // Adds the index in the pres path graphically @computed get order() { const order: JSX.Element[] = []; const docs: Doc[] = []; - const number: number[] = []; this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => { const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); const srcContext = Cast(tagDoc.context, Doc, null); @@ -792,18 +807,26 @@ export class PresBox extends ViewBoxBaseComponent const height = Math.max(NumCast(tagDoc._height) / 10, 15); const edge = Math.max(width, height); const fontSize = edge * 0.8; + const gap = 2; // Case A: Document is contained within the collection if (this.rootDoc.presCollection === srcContext) { if (docs.includes(tagDoc)) { + const prevOccurances: number = this.getAllIndexes(docs, tagDoc); docs.push(tagDoc); order.push( -
+
this.selectElement(doc)}>
{index + 1}
); } else { docs.push(tagDoc); order.push( -
+
this.selectElement(doc)}>
{index + 1}
); } @@ -865,29 +888,6 @@ export class PresBox extends ViewBoxBaseComponent />); } - /** - * 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: Doc = this.activeItem; - // const targetDoc: Doc = this.targetDoc; - // 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; - // } - // } - // } - // Converts seconds to ms and updates presTransition setTransitionTime = (number: String, change?: number) => { let timeInMS = Number(number) * 1000; @@ -911,57 +911,38 @@ export class PresBox extends ViewBoxBaseComponent */ @undoBatch updateMovement = action((movement: any, all?: boolean) => { - if (all) { - this.childDocs.forEach((doc) => { - switch (movement) { - case PresMovement.Zoom: //Pan and zoom - doc.presMovement = PresMovement.Zoom; - break; - case PresMovement.Pan: //Pan - doc.presMovement = PresMovement.Pan; - break; - case PresMovement.Jump: //Jump Cut - doc.presJump = true; - doc.presMovement = PresMovement.Jump; - break; - case PresMovement.None: default: - doc.presMovement = PresMovement.None; - break; - } - }); - } else { - this._selectedArray?.forEach((doc) => { - switch (movement) { - case PresMovement.Zoom: //Pan and zoom - doc.presMovement = PresMovement.Zoom; - break; - case PresMovement.Pan: //Pan - doc.presMovement = PresMovement.Pan; - break; - case PresMovement.Jump: //Jump Cut - doc.presJump = true; - doc.presMovement = PresMovement.Jump; - break; - case PresMovement.None: default: - doc.presMovement = PresMovement.None; - break; - } - }); - } + const array: any[] = all ? this.childDocs : this._selectedArray; + array.forEach((doc) => { + switch (movement) { + case PresMovement.Zoom: //Pan and zoom + doc.presMovement = PresMovement.Zoom; + break; + case PresMovement.Pan: //Pan + doc.presMovement = PresMovement.Pan; + break; + case PresMovement.Jump: //Jump Cut + doc.presJump = true; + doc.presMovement = PresMovement.Jump; + break; + case PresMovement.None: default: + doc.presMovement = PresMovement.None; + break; + } + }) }); @undoBatch @action updateHideBefore = (activeItem: Doc) => { - activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton; - this._selectedArray?.forEach((doc) => doc.presHideTillShownButton = activeItem.presHideTillShownButton); + activeItem.presHideBefore = !activeItem.presHideBefore; + this._selectedArray?.forEach((doc) => doc.presHideBefore = activeItem.presHideBefore); } @undoBatch @action updateHideAfter = (activeItem: Doc) => { - activeItem.presHideAfterButton = !activeItem.presHideAfterButton; - this._selectedArray?.forEach((doc) => doc.presHideAfterButton = activeItem.presHideAfterButton); + activeItem.presHideAfter = !activeItem.presHideAfter; + this._selectedArray?.forEach((doc) => doc.presHideAfter = activeItem.presHideAfter); } @undoBatch @@ -976,55 +957,30 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action updateEffect = (effect: any, all?: boolean) => { - if (all) { - this.childDocs.forEach((doc) => { - const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); - switch (effect) { - case PresEffect.Bounce: - tagDoc.presEffect = PresEffect.Bounce; - break; - case PresEffect.Fade: - tagDoc.presEffect = PresEffect.Fade; - break; - case PresEffect.Flip: - tagDoc.presEffect = PresEffect.Flip; - break; - case PresEffect.Roll: - tagDoc.presEffect = PresEffect.Roll; - break; - case PresEffect.Rotate: - tagDoc.presEffect = PresEffect.Rotate; - break; - case PresEffect.None: default: - tagDoc.presEffect = PresEffect.None; - break; - } - }); - } else { - this._selectedArray?.forEach((doc) => { - const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); - switch (effect) { - case PresEffect.Bounce: - tagDoc.presEffect = PresEffect.Bounce; - break; - case PresEffect.Fade: - tagDoc.presEffect = PresEffect.Fade; - break; - case PresEffect.Flip: - tagDoc.presEffect = PresEffect.Flip; - break; - case PresEffect.Roll: - tagDoc.presEffect = PresEffect.Roll; - break; - case PresEffect.Rotate: - tagDoc.presEffect = PresEffect.Rotate; - break; - case PresEffect.None: default: - tagDoc.presEffect = PresEffect.None; - break; - } - }); - } + const array: any[] = all ? this.childDocs : this._selectedArray; + array.forEach((doc) => { + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + switch (effect) { + case PresEffect.Bounce: + tagDoc.presEffect = PresEffect.Bounce; + break; + case PresEffect.Fade: + tagDoc.presEffect = PresEffect.Fade; + break; + case PresEffect.Flip: + tagDoc.presEffect = PresEffect.Flip; + break; + case PresEffect.Roll: + tagDoc.presEffect = PresEffect.Roll; + break; + case PresEffect.Rotate: + tagDoc.presEffect = PresEffect.Rotate; + break; + case PresEffect.None: default: + tagDoc.presEffect = PresEffect.None; + break; + } + }); } @computed get transitionDropdown() { @@ -1081,8 +1037,8 @@ export class PresBox extends ViewBoxBaseComponent
Visibility {"&"} Duration
-
{"Hide before presented"}
}>
this.updateHideBefore(activeItem)}>Hide before
-
{"Hide after presented"}
}>
this.updateHideAfter(activeItem)}>Hide after
+
{"Hide before presented"}
}>
this.updateHideBefore(activeItem)}>Hide before
+
{"Hide after presented"}
}>
this.updateHideAfter(activeItem)}>Hide after
{"Open document in a new tab"}
}>
this.updateOpenDoc(activeItem)}>Open
@@ -1175,8 +1131,8 @@ export class PresBox extends ViewBoxBaseComponent curDoc.presTransition = activeItem.presTransition; curDoc.presDuration = activeItem.presDuration; tagDoc.presEffectDirection = targetDoc.presEffectDirection; - curDoc.presHideTillShownButton = activeItem.presHideTillShownButton; - curDoc.presHideAfterButton = activeItem.presHideAfterButton; + curDoc.presHideBefore = activeItem.presHideBefore; + curDoc.presHideAfter = activeItem.presHideAfter; } }); } @@ -1372,7 +1328,7 @@ export class PresBox extends ViewBoxBaseComponent if (data && presData) { data.push(doc); TabDocView.PinDoc(doc, false); - this.gotoDocument(this.childDocs.length, this.itemIndex); + this.gotoDocument(this.childDocs.length); } else { this.props.addDocTab(doc, "add:right"); } @@ -1866,7 +1822,7 @@ export class PresBox extends ViewBoxBaseComponent
-
{presKeyEvents ? "Key are active" : "Keys are not active - click anywhere on the presentation trail to activate keys"}
}> +
{presKeyEvents ? "Keys are active" : "Keys are not active - click anywhere on the presentation trail to activate keys"}
}>
@@ -2005,7 +1961,7 @@ export class PresBox extends ViewBoxBaseComponent
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
-
{this.layoutDoc.presStatus === "auto" ? "Pause" : "Autoplay"}
}>
+
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
250 ? "inline-flex" : "none" }}> @@ -2022,13 +1978,17 @@ export class PresBox extends ViewBoxBaseComponent @action startOrPause = () => { - if (this.layoutDoc.presStatus === "manual" || this.layoutDoc.presStatus === "edit") this.startAutoPres(this.itemIndex); + if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex); else this.pauseAutoPres(); } render() { // calling this method for keyEvents this.isPres; + // console.log("ActivePres Title: " + Cast(Doc.UserDoc().activePresentation, Doc, null).title); + // for (const doc of this._selectedArray) { + // console.log(doc.title); + // } // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; @@ -2039,7 +1999,7 @@ export class PresBox extends ViewBoxBaseComponent
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
-
{this.layoutDoc.presStatus === "auto" ? "Pause" : "Autoplay"}
}>
+
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
@@ -2047,7 +2007,7 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
-
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
+
{ this.updateMinimize(); this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); }))}>EXIT
: diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 919142975..df5e346e1 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -2,7 +2,6 @@ $light-blue: #AEDDF8; $dark-blue: #5B9FDD; $light-background: #ececec; $slide-background: #d5dce2; -$slide-hover: #98b7da; $slide-active: #5B9FDD; .presItem-container { diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 0dc8a2148..aee309d5b 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -194,7 +194,11 @@ export class PresElementBox extends ViewBoxBaseComponent { const slide = this._itemRef.current!; - if (slide && DragManager.docsBeingDragged.length > 0) { + let dragIsPresItem: boolean = DragManager.docsBeingDragged.length > 0 ? true : false; + for (const doc of DragManager.docsBeingDragged) { + if (!doc.presentationTargetDoc) dragIsPresItem = false; + } + if (slide && dragIsPresItem) { const rect = slide.getBoundingClientRect(); const y = e.clientY - rect.top; //y position within the element. const height = slide.clientHeight; -- cgit v1.2.3-70-g09d2 From ee1f52496d44baa8566b03a05eb24d67fe80a89a Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Tue, 27 Oct 2020 12:43:00 +0800 Subject: Performance updates for up/down arrows Only calls resetSelection when necessary --- src/client/util/DocumentManager.ts | 11 +--- src/client/views/collections/CollectionMenu.tsx | 5 +- src/client/views/collections/TabDocView.tsx | 7 ++- .../collections/collectionFreeForm/MarqueeView.tsx | 7 ++- src/client/views/nodes/PresBox.tsx | 65 +++++++++------------- 5 files changed, 45 insertions(+), 50 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 805e0e897..14aaeaec0 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -128,14 +128,9 @@ export class DocumentManager { } - static addView = (doc: Doc, finished?: () => void, presCollection?: Doc) => { - if (presCollection) { - const collectionDocView = DocumentManager.Instance.getDocumentView(presCollection); - if (collectionDocView) collectionDocView.props.addDocTab(doc, "replace"); - } else { - CollectionDockingView.AddSplit(doc, "right"); - finished?.(); - } + static addView = (doc: Doc, finished?: () => void) => { + CollectionDockingView.AddSplit(doc, "right"); + finished?.(); } public jumpToDocument = async ( targetDoc: Doc, // document to display diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 34a1c0697..338b067fa 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -400,7 +400,10 @@ export class CollectionViewBaseChrome extends React.Component) => { if (targetDoc) { TabDocView.PinDoc(targetDoc, false); - const activeDoc = PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1]; + const presArray: Doc[] = PresBox.Instance?.sortArray(); + const size: number = PresBox.Instance?._selectedArray.size; + const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; + const activeDoc = presSelected ? PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.indexOf(presSelected) + 1] : PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1]; if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { const scroll = targetDoc._scrollTop; activeDoc.presPinView = true; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index dcd94a7e6..82530c26d 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -134,7 +134,10 @@ export class TabDocView extends React.Component { pinDoc.title = doc.title + " - Slide"; pinDoc.presMovement = PresMovement.Zoom; pinDoc.context = curPres; - Doc.AddDocToList(curPres, "data", pinDoc); + const presArray: Doc[] = PresBox.Instance?.sortArray(); + const size: number = PresBox.Instance?._selectedArray.size; + const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; + Doc.AddDocToList(curPres, "data", pinDoc, presSelected); if (pinDoc.type === "audio" && !audioRange) { pinDoc.presStartTime = 0; pinDoc.presEndTime = doc.duration; @@ -149,6 +152,8 @@ export class TabDocView extends React.Component { tabdocs?.push(curPres); // bcz: Argh! this is annoying. if multiple documents are pinned, this will get called multiple times before the presentation view is drawn. Thus it won't be in the tabdocs list and it will get created multple times. so need to explicilty add the presbox to the list of open tabs CollectionDockingView.AddSplit(curPres, "right"); } + PresBox.Instance?._selectedArray.clear(); + pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array DocumentManager.Instance.jumpToDocument(doc, false, undefined); batch.end(); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c6d1c9da2..efbe85f1a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -25,7 +25,7 @@ import "./MarqueeView.scss"; import React = require("react"); import { Id } from "../../../../fields/FieldSymbols"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; -import { PresMovement } from "../../nodes/PresBox"; +import { PresBox, PresMovement } from "../../nodes/PresBox"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -399,7 +399,10 @@ export class MarqueeView extends React.Component this.layoutDoc.presStatus = PresStatus.Edit; this.layoutDoc._gridGap = 0; this.layoutDoc._yMargin = 0; - document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); - document.addEventListener("keydown", PresBox.keyEventsWrapper, true); - this._presKeyEventsActive = true; this.turnOffEdit(true); DocListCastAsync((Doc.UserDoc().myPresentations as Doc).data).then(pres => !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc)); @@ -172,6 +169,7 @@ export class PresBox extends ViewBoxBaseComponent else Doc.UserDoc().activePresentation = this.rootDoc; document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); document.addEventListener("keydown", PresBox.keyEventsWrapper, true); + this._presKeyEventsActive = true; PresBox.Instance = this; } @@ -264,17 +262,7 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc._itemIndex = index; const activeItem: Doc = this.activeItem; const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); - if (activeItem.presPinView) { - const bestTarget = DocumentManager.Instance.getFirstDocumentView(presTargetDoc)?.props.Document; - bestTarget && runInAction(() => { - if (activeItem.presMovement === PresMovement.Jump) { - bestTarget._viewTransition = '0s'; - } else { - bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 1s'; - setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 1010); - } - }); - } else if (presTargetDoc) { + if (presTargetDoc) { presTargetDoc && runInAction(() => { if (activeItem.presMovement === PresMovement.Jump) presTargetDoc.focusSpeed = 0; else presTargetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; @@ -291,11 +279,13 @@ export class PresBox extends ViewBoxBaseComponent } }); - + _navTimer!: NodeJS.Timeout; navigateToView = (targetDoc: Doc, activeItem: Doc) => { + clearTimeout(this._navTimer); const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document; bestTarget && runInAction(() => { if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) { + bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; bestTarget._scrollY = activeItem.presPinViewScroll; } else if (bestTarget.type === DocumentType.COMPARISON) { bestTarget._clipWidth = activeItem.presPinClipWidth; @@ -307,8 +297,8 @@ export class PresBox extends ViewBoxBaseComponent bestTarget._panY = activeItem.presPinViewY; bestTarget._viewScale = activeItem.presPinViewScale; } + this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510); }); - setTimeout(() => targetDoc._viewTransition = undefined, 1010); } /** @@ -325,14 +315,11 @@ export class PresBox extends ViewBoxBaseComponent const srcContext = await DocCastAsync(targetDoc?.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined; + const includesDoc: boolean = DocListCast(presCollection?.data).includes(targetDoc); this.turnOffEdit(); - if (this.itemIndex >= 0) { - if (srcContext && targetDoc) { - this.layoutDoc.presCollection = srcContext; - } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; - } - const docToJump = curDoc; - const willZoom = false; + if (includesDoc) { + this.layoutDoc.presCollection = srcContext; + } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; const presStatus = this.rootDoc.presStatus; const selViewCache = Array.from(this._selectedArray.keys()); const dragViewCache = Array.from(this._dragArray); @@ -356,19 +343,11 @@ export class PresBox extends ViewBoxBaseComponent // If openDocument is selected then it should open the document for the user if (activeItem.openDocument) { openInTab(); - } else { - if (docToJump === curDoc) { - //checking if curDoc has navigation open - if (curDoc.presMovement === PresMovement.Pan && targetDoc) { - await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext); // documents open in new tab instead of on right - } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { - //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, resetSelection); // documents open in new tab instead of on right - } - } else { - //awaiting jump so that new scale can be found, since jumping is async - targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext); - } + } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) { + await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc ? undefined : resetSelection); // documents open in new tab instead of on right + } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { + //awaiting jump so that new scale can be found, since jumping is async + await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc ? undefined : resetSelection); // documents open in new tab instead of on right } // After navigating to the document, if it is added as a presPinView then it will // adjust the pan and scale to that of the pinView when it was added. @@ -688,10 +667,20 @@ export class PresBox extends ViewBoxBaseComponent this._selectedArray.set(doc, undefined); this._eleArray.push(ref); this._dragArray.push(drag); + } else { + this._selectedArray.delete(doc); + this.removeFromArray(this._eleArray, doc); + this.removeFromArray(this._dragArray, doc); } this.selectPres(); } + removeFromArray = (arr: any[], val: any) => { + const index: number = arr.indexOf(val); + const ret: any[] = arr.splice(index, 1); + arr = ret; + } + //Shift click @action shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => { @@ -1614,12 +1603,12 @@ export class PresBox extends ViewBoxBaseComponent @action turnOffEdit = (paths?: boolean) => { + // Turn off paths if (paths) { - // Turn off paths const srcContext = Cast(this.rootDoc.presCollection, Doc, null); if (srcContext) this.togglePath(srcContext, true); } - // Turn off the progressivize editors for each + // Turn off the progressivize editors for each document this.childDocs.forEach((doc) => { doc.editSnapZoomProgressivize = false; doc.editZoomProgressivize = false; -- cgit v1.2.3-70-g09d2 From 6c6da53ef18ed6d28c507115571fcdb980ec260c Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 1 Nov 2020 18:04:08 +0800 Subject: pinWithView works with view paths + removed Pan options and Scroll options --- src/client/views/DocumentButtonBar.tsx | 6 ++- src/client/views/PropertiesView.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.scss | 9 ++++- src/client/views/nodes/PresBox.tsx | 43 +++++++++++++++++----- .../views/presentationview/PresElementBox.tsx | 4 +- 5 files changed, 49 insertions(+), 17 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 3b22cf51c..fa0b9a238 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -201,13 +201,15 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV if (targetDoc) { TabDocView.PinDoc(targetDoc, false); const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1]; - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { + const scrollable: boolean = (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking); + const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG); + if (scrollable) { const scroll = targetDoc._scrollTop; activeDoc.presPinView = true; activeDoc.presPinViewScroll = scroll; } else if (targetDoc.type === DocumentType.VID) { activeDoc.presPinTimecode = targetDoc._currentTimecode; - } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { + } else if (pannable) { const x = targetDoc._panX; const y = targetDoc._panY; const scale = targetDoc._viewScale; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 4dea0ddaa..9b77e2736 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1029,7 +1029,7 @@ export class PropertiesView extends React.Component { {PresBox.Instance.progressivizeDropdown}
: null}
} */} - {!selectedItem || (!scrollable && !pannable) ? (null) :
+ {/* {!selectedItem || (!scrollable && !pannable) ? (null) :
{ this.openSlideOptions = !this.openSlideOptions; })} style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}> @@ -1041,7 +1041,7 @@ export class PropertiesView extends React.Component { {this.openSlideOptions ?
{PresBox.Instance.optionsDropdown}
: null} -
} +
} */} {/*
{ this.openAddSlide = !this.openAddSlide; })} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index 75cbc20ca..e92100c50 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -57,7 +57,7 @@ min-height: 15px; text-align: center; background-color: #69a6db; - border-radius: 5px; + border-radius: 10%; box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); font-family: Roboto; font-weight: 500; @@ -65,6 +65,13 @@ } } +.pathOrder-presPinView { + position: absolute; + z-index: 190000; + border-style: dashed; + border-color: #69a5db; +} + .progressivizeButton { position: absolute; display: grid; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index f8f794a4b..d7f15166f 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -808,6 +808,8 @@ export class PresBox extends ViewBoxBaseComponent @computed get order() { const order: JSX.Element[] = []; const docs: Doc[] = []; + const presCollection = Cast(this.rootDoc.presCollection, Doc, null); + const dv = DocumentManager.Instance.getDocumentView(presCollection); this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => { const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); const srcContext = Cast(tagDoc.context, Doc, null); @@ -816,8 +818,9 @@ export class PresBox extends ViewBoxBaseComponent const edge = Math.max(width, height); const fontSize = edge * 0.8; const gap = 2; - // Case A: Document is contained within the collection - if (this.rootDoc.presCollection === srcContext) { + if (presCollection === srcContext) { + // Case A: Document is contained within the collection + console.log(`-------Case A: ${index}-------`); if (docs.includes(tagDoc)) { const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length; docs.push(tagDoc); @@ -838,15 +841,33 @@ export class PresBox extends ViewBoxBaseComponent
{index + 1}
); } + } else if (doc.presPinView && presCollection === tagDoc && dv) { // Case B: Document is presPinView and is presCollection - } else if (doc.pinWithView && this.layoutDoc.presCollection === tagDoc) { + console.log(`-------Case B: ${index}-------`); + const scale: number = 1 / NumCast(doc.presPinViewScale); + const height: number = dv.props.PanelHeight() * scale; + const width: number = dv.props.PanelWidth() * scale; + const indWidth = width / 10; + const indHeight = Math.max(height / 10, 15); + const indEdge = Math.max(indWidth, indHeight); + const indFontSize = indEdge * 0.8; + const xLoc: number = NumCast(doc.presPinViewX) - (width / 2); + const yLoc: number = NumCast(doc.presPinViewY) - (height / 2); docs.push(tagDoc); order.push( -
-
{index + 1}
-
); - // Case C: Document is not contained within presCollection + <> +
this.selectElement(doc)} + > +
{index + 1}
+
+
+ ); } else { + // Case C: Document is not contained within presCollection + console.log(`-------Case C: ${index}-------`); docs.push(tagDoc); order.push(
@@ -875,9 +896,11 @@ export class PresBox extends ViewBoxBaseComponent const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._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; + } else if (doc.presPinView) { + const n1x = NumCast(doc.presPinViewX); + const n1y = NumCast(doc.presPinViewY); + if (index = 0) pathPoints = n1x + "," + n1y; + else pathPoints = pathPoints + " " + n1x + "," + n1y; } }); return ( = React.createRef(); -- cgit v1.2.3-70-g09d2 From d000fe7a7f89cb7252c8a23e0f88a61775ba2933 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 1 Nov 2020 21:07:31 +0800 Subject: Remove any attempt at auto playing audio --- src/client/views/collections/CollectionMenu.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 62 ++++++++++++++++------ .../collectionFreeForm/MarqueeOptionsMenu.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 33 ++++++------ 4 files changed, 65 insertions(+), 34 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 338b067fa..38817a601 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -432,7 +432,7 @@ export class CollectionViewBaseChrome extends React.Component; const targetDoc = this.selectedDoc; {/* return (!targetDoc || (targetDoc._viewType !== CollectionViewType.Freeform && targetDoc.type !== DocumentType.IMG)) ? (null) :
{"Pin to presentation trail with current view"}
} placement="top"> */ } - return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top"> + return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin with current view"}
} placement="top">
; + return ( + <> +
{ + const target = e.target as any; + if (getComputedStyle(target)?.overflow === "visible") { // if collection is visible, then scrolling will mess things up since there are no scroll bars + target.scrollTop = target.scrollLeft = 0; + } + }} + style={{ + transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`, + transition: this.props.transition, + //willChange: "transform" + }}> + {this.props.children()} + {this.presPaths} + {this.progressivize} + {this.zoomProgressivize} +
+ {/*
{this.presPathsOutsideCollection}
*/} + ); } } \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index d8e44e781..cedeb1112 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -54,7 +54,7 @@ export class MarqueeOptionsMenu extends AntimodeMenu { , -
Pin the selected region to presentation
} placement="bottom"> +
Pin with selected region
} placement="bottom">
); - } else { - // Case C: Document is not contained within presCollection - console.log(`-------Case C: ${index}-------`); - docs.push(tagDoc); - order.push( -
-
{index + 1}
-
); } }); return order; @@ -891,15 +880,16 @@ export class PresBox extends ViewBoxBaseComponent */ @computed get paths() { let pathPoints = ""; + const presCollection = Cast(this.rootDoc.presCollection, Doc, null); this.childDocs.forEach((doc, index) => { const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); const srcContext = Cast(tagDoc?.context, Doc, null); - if (tagDoc && this.rootDoc.presCollection === srcContext) { + if (tagDoc && presCollection === srcContext) { const n1x = NumCast(tagDoc.x) + (NumCast(tagDoc._width) / 2); const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._height) / 2); if (index = 0) pathPoints = n1x + "," + n1y; else pathPoints = pathPoints + " " + n1x + "," + n1y; - } else if (doc.presPinView) { + } else if (doc.presPinView && presCollection === tagDoc) { const n1x = NumCast(doc.presPinViewX); const n1y = NumCast(doc.presPinViewY); if (index = 0) pathPoints = n1x + "," + n1y; @@ -2040,7 +2030,10 @@ export class PresBox extends ViewBoxBaseComponent
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
{ this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
-
250 ? "inline-flex" : "none" }}> +
this.gotoDocument(0)} + style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}> Slide {this.itemIndex + 1} / {this.childDocs.length} {this.playButtonFrames}
@@ -2074,7 +2067,7 @@ export class PresBox extends ViewBoxBaseComponent
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
{ this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
-
+
this.gotoDocument(0)}> Slide {this.itemIndex + 1} / {this.childDocs.length} {this.playButtonFrames}
-- cgit v1.2.3-70-g09d2 From 35de050c423edba2be6833492438a5e02f45f938 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 1 Nov 2020 10:31:31 -0500 Subject: minor cleanup --- .../collectionFreeForm/CollectionFreeFormView.tsx | 37 ++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index eb278681d..fdcfb00d8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1665,25 +1665,22 @@ class CollectionFreeFormViewPannableContents extends React.Component -
{ - const target = e.target as any; - if (getComputedStyle(target)?.overflow === "visible") { // if collection is visible, then scrolling will mess things up since there are no scroll bars - target.scrollTop = target.scrollLeft = 0; - } - }} - style={{ - transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`, - transition: this.props.transition, - //willChange: "transform" - }}> - {this.props.children()} - {this.presPaths} - {this.progressivize} - {this.zoomProgressivize} -
- ); + return
{ + const target = e.target as any; + if (getComputedStyle(target)?.overflow === "visible") { // if collection is visible, then scrolling will mess things up since there are no scroll bars + target.scrollTop = target.scrollLeft = 0; + } + }} + style={{ + transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`, + transition: this.props.transition, + //willChange: "transform" + }}> + {this.props.children()} + {this.presPaths} + {this.progressivize} + {this.zoomProgressivize} +
; } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 0ddd75da0f0b42cf3e1692e1cb1761c0e70ed551 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 2 Nov 2020 14:11:25 -0500 Subject: fixed up dropping documents into a collection that doesn't have an activeFrame set so that they can be resized --- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index fdcfb00d8..58a9c4974 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -169,14 +169,23 @@ export class CollectionFreeFormView extends CollectionSubView Date: Tue, 3 Nov 2020 14:26:19 -0500 Subject: added undo's for icon/deiconifying pile docs and icon docs. added a zoom hack to focus on stacking documents. stopped autoscroll on nested collections. --- src/client/views/collections/CollectionPileView.tsx | 14 ++++++++------ src/client/views/collections/CollectionStackingView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 5b4730848..2636b98e5 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -6,7 +6,7 @@ import { emptyFunction, setupMoveUpEvents } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; -import { UndoManager } from "../../util/UndoManager"; +import { UndoManager, undoBatch } from "../../util/UndoManager"; import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView"; import "./CollectionPileView.scss"; import { CollectionSubView } from "./CollectionSubView"; @@ -34,14 +34,14 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { const draggingSelf = this.props.isSelected(); return
{ + addDocument={undoBatch((doc: Doc | Doc[]) => { (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); return this.props.addDocument(doc); - }} - moveDocument={(doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { - (doc instanceof Doc ? [doc] : doc).map((d) => Doc.deiconifyView(d)); + })} + moveDocument={undoBatch((doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { + (doc instanceof Doc ? [doc] : doc).map(undoBatch((d) => Doc.deiconifyView(d))); return this.props.moveDocument(doc, targetCollection, addDoc); - }} /> + })} />
; } @@ -107,6 +107,8 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { } // onClick for toggling the pileup view + @undoBatch + @action onClick = (e: React.MouseEvent) => { if (e.button === 0) { SelectionManager.DeselectAll(); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 4880d342c..7a3257525 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -172,7 +172,7 @@ export class CollectionStackingView extends CollectionSubView boolean) => { Doc.BrushDoc(doc); - this.props.focus(doc); + this.props.focus(this.props.Document, true); // bcz: HACK ARgh.. need to update all focus() functions to take parameters about how to focus. in this case, we want to zoom so we pass true and hope an ancestor is a collection view Doc.linkFollowHighlight(doc); const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName("documentView-node")).find((node: any) => node.id === doc[Id]); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 58a9c4974..703776e72 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1218,7 +1218,7 @@ export class CollectionFreeFormView extends CollectionSubView(Docu thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey }, console.log); - func(); + undoBatch(func)(); } else if (!Doc.IsSystem(this.props.Document)) { if (this.props.Document.type === DocumentType.INK) { InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true); -- cgit v1.2.3-70-g09d2 From 14132f488b29641302fe10711a938b1bbdecc4fa Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Wed, 4 Nov 2020 21:56:23 +0800 Subject: select item in trail after marquee select --- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index efbe85f1a..7040b5e56 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -407,6 +407,10 @@ export class MarqueeView extends React.Component Date: Sun, 8 Nov 2020 21:35:16 -0500 Subject: added an optional background grid for collections. --- src/client/views/MainView.tsx | 4 +-- src/client/views/collections/CollectionMenu.tsx | 13 ++++++-- .../collectionFreeForm/CollectionFreeFormView.scss | 7 ++++ .../collectionFreeForm/CollectionFreeFormView.tsx | 37 +++++++++++++++++++++- src/client/views/nodes/PresBox.tsx | 4 +-- 5 files changed, 57 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 3a3dbc68f..452ce61ff 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -133,7 +133,7 @@ export class MainView extends React.Component { } library.add(fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar, - fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, + fa.faSquare, far.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointLeft, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard, fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleLeft, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight, fa.faCaretSquareDown, fa.faCaretSquareRight, fa.faArrowsAltH, fa.faPlus, fa.faMinus, fa.faTerminal, fa.faToggleOn, fa.faFile, fa.faLocationArrow, @@ -151,7 +151,7 @@ export class MainView extends React.Component { fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, faBuffer, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl, fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faTextHeight, fa.faClosedCaptioning, fa.faInfoCircle, fa.faTag, fa.faSyncAlt, fa.faPhotoVideo, fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical, - fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, + fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll, fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines); this.initAuthenticationRouters(); } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index cf94a93d3..b2b23115f 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -489,13 +489,19 @@ export class CollectionViewBaseChrome extends React.Component{"Show Lightbox of Images"}
} placement="top"> - ; } - - + @computed get gridbackgroundButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) : {"Toggle background grid"}
} placement="top"> + + ; + } render() { return ( @@ -513,6 +519,7 @@ export class CollectionViewBaseChrome extends React.Component } {this.notACollection ? (null) : this.lightboxButton} + {this.notACollection ? (null) : this.gridbackgroundButton} {this.aliasButton} {/* {this.pinButton} */} {this.pinWithViewButton} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index e92100c50..a50b41198 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -12,6 +12,13 @@ border-radius: inherit; } +.collectionfreeformview-grid { + transform-origin: top left; + position: absolute; + top: 0; + left: 0; +} + .collectionfreeformview-viewdef { >.collectionFreeFormDocumentView-container { pointer-events: none; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 703776e72..8a4ce826f 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1434,6 +1434,38 @@ export class CollectionFreeFormView extends CollectionSubView { + const ctx = el?.getContext('2d'); + if (ctx) { + const Cx = (cx / this.zoomScaling()) % gridSpace - 0; + const Cy = (cy / this.zoomScaling()) % gridSpace - 0; + ctx.clearRect(0, 0, w, h); + if (ctx) { + ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; + ctx.lineWidth = Math.min(1, Math.max(0.5, 0.5 / this.zoomScaling())); + ctx.beginPath(); + for (let x = Cx; x <= -Cx + w; x += gridSpace) { + ctx.moveTo(x, Cy - h); + ctx.lineTo(x, Cy + h); + } + for (let y = Cy; y <= -Cy + h; y += gridSpace) { + ctx.moveTo(Cx - w, y); + ctx.lineTo(Cx + w, y); + } + ctx.stroke(); + } + } + }} />; + } @computed get marqueeView() { return
+ {this.layoutDoc["_backgroundGrid-show"] ? this.grid : (null)} ; } + @computed get contentScaling() { if (this.props.annotationsKey && !this.props.forceScaling) return 0; const nw = returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); @@ -1635,7 +1669,7 @@ class CollectionFreeFormViewPannableContents extends React.Component; } + render() { // trace(); const freeformclass = "collectionfreeformview" + (this.props.viewDefDivClick ? "-viewDef" : "-none"); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 52e09a469..683cb938a 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -426,7 +426,7 @@ export class PresBox extends ViewBoxBaseComponent if (tagDoc) tagDoc.opacity = 1; const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc); const curInd: number = itemIndexes.indexOf(index); - if (tagDoc === this.layoutDoc.presCollection) { tagDoc.opacity = 1 } + if (tagDoc === this.layoutDoc.presCollection) { tagDoc.opacity = 1; } else { if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { } else if (curDoc.presHideBefore) { @@ -1210,7 +1210,7 @@ export class PresBox extends ViewBoxBaseComponent const targetDoc: Doc = this.targetDoc; this.updateMovement(activeItem.presMovement, true); this.updateEffect(targetDoc.presEffect, true); - this.updateEffectDirection(targetDoc.presEffectDirection, true) + this.updateEffectDirection(targetDoc.presEffectDirection, true); array.forEach((doc) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); -- cgit v1.2.3-70-g09d2 From ce5512a3fdd451ad47263f896a9e855229133eaf Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 9 Nov 2020 15:04:28 -0500 Subject: added fullScreen alias option for opening documents so that opened document can have different scale than original. fixed pushpins to not toggle target if something must be panned/zoomed to show the target. fixed drag drop to ignore the document being dragged properly when dropping (which prevented a document over a collection from being dropped on the colelction when move slightly). --- src/client/util/DocumentManager.ts | 10 ++--- src/client/util/DragManager.ts | 18 +++++---- src/client/views/DocumentDecorations.tsx | 10 ++--- .../views/collections/CollectionStackingView.tsx | 5 ++- src/client/views/collections/TabDocView.tsx | 6 +-- .../collectionFreeForm/CollectionFreeFormView.tsx | 45 ++++++++++++++-------- src/client/views/nodes/DocumentView.tsx | 13 +++---- src/client/views/nodes/FieldView.tsx | 3 +- src/fields/documentSchemas.ts | 1 + 9 files changed, 62 insertions(+), 49 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 14aaeaec0..a6816c7f9 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -163,21 +163,19 @@ export class DocumentManager { if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight? const sameContext = annotatedDoc && annotatedDoc === originatingDoc?.context; if (originatingDoc?.isPushpin) { - const hide = !docView.props.Document.hidden; - docView.props.focus(docView.props.Document, willZoom, undefined, (notfocused: boolean) => { // bcz: Argh! TODO: Need to add a notFocused argument to the after finish callback function that indicates whether the window had to scroll to show the target - if (notfocused || docView.props.Document.hidden) { + docView.props.focus(docView.props.Document, willZoom, undefined, (didFocus: boolean) => { + if (!didFocus || docView.props.Document.hidden) { docView.props.Document.hidden = !docView.props.Document.hidden; } return focusAndFinish(); - // @ts-ignore bcz: Argh TODO: Need to add a parameter to focus() everywhere for whether focus should center the target's container in the view or not. // here we don't want to focus the container if the source and target are in the same container - }, sameContext); + }, sameContext, false);// don't want to focus the container if the source and target are in the same container, so pass 'sameContext' for dontCenter parameter //finished?.(); } else { docView.select(false); docView.props.Document.hidden && (docView.props.Document.hidden = undefined); // @ts-ignore - docView.props.focus(docView.props.Document, willZoom, undefined, focusAndFinish, sameContext); + docView.props.focus(docView.props.Document, willZoom, undefined, focusAndFinish, sameContext, false); } highlight(); } else { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 9e91b4f55..86e2d339e 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -416,7 +416,13 @@ export namespace DragManager { }); const hideSource = options?.hideSource ? true : false; - eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.parentElement.hidden = hideSource) : (ele.hidden = hideSource)); + eles.forEach(ele => { + if (ele.parentElement && ele.parentElement?.className === dragData.dragDivName) { + ele.parentElement.hidden = hideSource; + } else { + ele.hidden = hideSource; + } + }); SnappingManager.SetIsDragging(true); let lastX = downX; @@ -514,27 +520,25 @@ export namespace DragManager { const hideDragShowOriginalElements = () => { dragLabel.style.display = "none"; dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); - eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.parentElement.hidden = false) : (ele.hidden = false)); + eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.hidden = ele.parentElement.hidden = false) : (ele.hidden = false)); }; const endDrag = action(() => { + hideDragShowOriginalElements(); document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); + SnappingManager.SetIsDragging(false); SnappingManager.clearSnapLines(); batch.end(); }); AbortDrag = () => { - hideDragShowOriginalElements(); - SnappingManager.SetIsDragging(false); options?.dragComplete?.(new DragCompleteEvent(true, dragData)); endDrag(); }; const upHandler = (e: PointerEvent) => { - hideDragShowOriginalElements(); dispatchDrag(eles, e, dragData, xFromLeft, yFromTop, xFromRight, yFromBottom, options, finishDrag); - SnappingManager.SetIsDragging(false); - endDrag(); options?.dragComplete?.(new DragCompleteEvent(false, dragData)); + endDrag(); }; document.addEventListener("pointermove", moveHandler, true); document.addEventListener("pointerup", upHandler); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 4dcae8e60..63b99cd85 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -177,19 +177,17 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const selectedDocs = SelectionManager.SelectedDocuments(); if (selectedDocs.length) { if (e.ctrlKey) { // open an alias in a new tab with Ctrl Key - const alias = Doc.MakeAlias(selectedDocs[0].props.Document); - alias.context = undefined; - //CollectionDockingView.Instance?.OpenFullScreen(selectedDocs[0]); - CollectionDockingView.AddSplit(alias, "right"); + selectedDocs[0].props.Document._fullScreenView = Doc.MakeAlias(selectedDocs[0].props.Document); + (selectedDocs[0].props.Document._fullScreenView as Doc).context = undefined; + CollectionDockingView.AddSplit(selectedDocs[0].props.Document._fullScreenView as Doc, "right"); } else if (e.shiftKey) { // open centered in a new workspace with Shift Key const alias = Doc.MakeAlias(selectedDocs[0].props.Document); alias.context = undefined; alias.x = -alias[WidthSym]() / 2; alias.y = -alias[HeightSym]() / 2; - //CollectionDockingView.Instance?.OpenFullScreen(selectedDocs[0]); CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([alias], { title: "Tab for " + alias.title }), "right"); } else { // open same document in new tab - CollectionDockingView.ToggleSplit(selectedDocs[0].props.Document, "right"); + CollectionDockingView.ToggleSplit(Cast(selectedDocs[0].props.Document._fullScreenView, Doc, null) || selectedDocs[0].props.Document, "right"); } } } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 2285bcb8f..62f733058 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -28,6 +28,7 @@ import { CollectionViewType } from "./CollectionView"; import { SnappingManager } from "../../util/SnappingManager"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocUtils } from "../../documents/Documents"; +import { DocAfterFocusFunc } from "../nodes/DocumentView"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -170,9 +171,9 @@ export class CollectionStackingView extends CollectionSubView boolean) => { + focusDocument = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, didFocus?: boolean) => { Doc.BrushDoc(doc); - this.props.focus(this.props.Document, true); // bcz: HACK ARgh.. need to update all focus() functions to take parameters about how to focus. in this case, we want to zoom so we pass true and hope an ancestor is a collection view + this.props.focus(this.props.Document, true); // bcz: want our containing collection to zoom Doc.linkFollowHighlight(doc); const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName("documentView-node")).find((node: any) => node.id === doc[Id]); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 38b9b399d..530595cd0 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -21,7 +21,7 @@ import { SelectionManager } from '../../util/SelectionManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { DocumentView } from "../nodes/DocumentView"; +import { DocumentView, DocAfterFocusFunc } from "../nodes/DocumentView"; import { PresBox, PresMovement } from '../nodes/PresBox'; import { CollectionDockingView } from './CollectionDockingView'; import { CollectionDockingViewMenu } from './CollectionDockingViewMenu'; @@ -343,11 +343,11 @@ export class TabDocView extends React.Component { ; } - focusFunc = (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: () => void) => { + focusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, notFocused?: boolean) => { if (!this.tab.header.parent._activeContentItem || this.tab.header.parent._activeContentItem !== this.tab.contentItem) { this.tab.header.parent.setActiveContentItem(this.tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost) } - afterFocus?.(); + afterFocus?.(false); } setView = action((view: DocumentView) => this._view = view); active = () => this._isActive; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 8a4ce826f..4541716f3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -33,7 +33,7 @@ import { ContextMenu } from "../../ContextMenu"; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkingStroke"; import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentLinksButton } from "../../nodes/DocumentLinksButton"; -import { DocumentViewProps } from "../../nodes/DocumentView"; +import { DocumentViewProps, DocAfterFocusFunc } from "../../nodes/DocumentView"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { pageSchema } from "../../nodes/ImageBox"; import { PresBox } from "../../nodes/PresBox"; @@ -887,7 +887,7 @@ export class CollectionFreeFormView extends CollectionSubView boolean, dontCenter?: boolean) => { + focusDocument = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, didFocus?: boolean) => { const state = HistoryUtil.getState(); // TODO This technically isn't correct if type !== "doc", as @@ -927,7 +927,7 @@ export class CollectionFreeFormView extends CollectionSubView { - // @ts-ignore - if (afterFocus?.(notFocused)) { // bcz: TODO Aragh -- need to add a parameter to afterFocus() functions to indicate whether the focus function didn't need to scroll - this.Document._panX = savedState.px; - this.Document._panY = savedState.py; - this.Document[this.scaleFieldKey] = savedState.s; - this.Document._viewTransition = savedState.pt; - } - }, notFocused ? 0 : 500); + const newDidFocus = didFocus || (newPanX !== savedState.px || newPanY !== savedState.py); + + const newAfterFocus = (didFocus: boolean) => { + afterFocus && setTimeout(() => { + // @ts-ignore + if (afterFocus?.(didFocus || (newPanX !== savedState.px || newPanY !== savedState.py))) { + this.Document._panX = savedState.px; + this.Document._panY = savedState.py; + this.Document[this.scaleFieldKey] = savedState.s; + this.Document._viewTransition = savedState.pt; + } + }, newPanX !== savedState.px || newPanY !== savedState.py ? 500 : 0); + return false; + }; + this.props.focus(this.props.Document, undefined, undefined, newAfterFocus, undefined, newDidFocus); + Doc.linkFollowHighlight(doc); } } @@ -1434,8 +1438,15 @@ export class CollectionFreeFormView extends CollectionSubView { + const w = this.props.PanelWidth() / this.zoomScaling() + 3 * start; + if (w / start > 60) return this.chooseGridSpace(start * 10); + return start; + } + @computed get grid() { - const gridSpace = NumCast(this.layoutDoc["_backgroundGrid-space"], 50); + const gridSpace = this.chooseGridSpace(NumCast(this.layoutDoc["_backgroundGrid-space"], 50)); const shiftX = this.props.isAnnotationOverlay ? 0 : -(this.panX()) % gridSpace - gridSpace; const shiftY = this.props.isAnnotationOverlay ? 0 : -(this.panY()) % gridSpace - gridSpace; const cx = this.centeringShiftX(); @@ -1448,6 +1459,8 @@ export class CollectionFreeFormView extends CollectionSubView 50 ? 3 : 1); + ctx.setLineDash(gridSpace > 50 ? [3, 3] : [1, 5]); ctx.clearRect(0, 0, w, h); if (ctx) { ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4efa5d67f..77f63b457 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -42,7 +42,8 @@ import { RadialMenu } from './RadialMenu'; import { TaskCompletionBox } from './TaskCompletedBox'; import React = require("react"); -export type DocFocusFunc = () => boolean; +export type DocAfterFocusFunc = (notFocused: boolean) => boolean; +export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; export interface DocumentViewProps { ContainingCollectionView: Opt; @@ -82,7 +83,7 @@ export interface DocumentViewProps { PanelHeight: () => number; pointerEvents?: string; contentsPointerEvents?: string; - focus: (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: DocFocusFunc) => void; + focus: DocFocusFunc; parentActive: (outsideReaction: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; bringToFront: (doc: Doc, sendToBack?: boolean) => void; @@ -331,11 +332,7 @@ export class DocumentView extends DocComponent(Docu InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true); } else { UndoManager.RunInBatch(() => { - let fullScreenDoc = this.props.Document; - if (StrCast(this.props.Document.layoutKey) !== "layout_fullScreen" && this.props.Document.layout_fullScreen) { - fullScreenDoc = Doc.MakeAlias(this.props.Document); - fullScreenDoc.layoutKey = "layout_fullScreen"; - } + const fullScreenDoc = Cast(this.props.Document._fullScreenView, Doc, null) || this.props.Document; this.props.addDocTab(fullScreenDoc, "add"); }, "double tap"); SelectionManager.DeselectAll(); @@ -385,7 +382,7 @@ export class DocumentView extends DocComponent(Docu // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place // depending on the followLinkLocation property of the source (or the link itself as a fallback); public static followLinkClick = async (linkDoc: Opt, sourceDoc: Doc, docView: { - focus: (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: DocFocusFunc) => void, + focus: DocFocusFunc, addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean, ContainingCollectionDoc?: Doc }, shiftKey: boolean, altKey: boolean) => { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 3a5b27b21..79947c023 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -11,6 +11,7 @@ import { CollectionView } from "../collections/CollectionView"; import { AudioBox } from "./AudioBox"; import { VideoBox } from "./VideoBox"; import { dropActionType } from "../../util/DragManager"; +import { DocAfterFocusFunc, DocFocusFunc } from "./DocumentView"; // // these properties get assigned through the render() method of the DocumentView when it creates this node. @@ -47,7 +48,7 @@ export interface FieldViewProps { whenActiveChanged: (isActive: boolean) => void; LayoutTemplateString?: string; dontRegisterView?: boolean; - focus: (doc: Doc) => void; + focus: DocFocusFunc; presMultiSelect?: (doc: Doc) => void; //added for selecting multiple documents in a presentation ignoreAutoHeight?: boolean; PanelWidth: () => number; diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 311aaa769..6e58f7f13 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -15,6 +15,7 @@ export const documentSchema = createSchema({ // "Location" properties in a very general sense _curPage: "number", // current page of a page based document _currentFrame: "number", // current frame of a frame based collection (e.g., a progressive slide) + _fullScreenView: Doc, // alias to display when double-clicking to open document in a full-screen view lastFrame: "number", // last frame of a frame based collection (e.g., a progressive slide) activeFrame: "number", // the active frame of a frame based animated document _currentTimecode: "number", // current play back time of a temporal document (video / audio) -- cgit v1.2.3-70-g09d2 From 83d3756537cfcd8a2248c4b8a2a6f75f77154602 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 9 Nov 2020 21:40:59 -0500 Subject: fixed autoHeight for formattedTextSidebars when the text document has been scaled. cleaned up link groups. fixed pushpins that don't focus on target (e.g., a si m ple pushpin on a PDF). --- src/client/util/LinkManager.ts | 9 +---- .../views/collections/CollectionStackingView.tsx | 10 +++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 +- src/client/views/linking/LinkMenu.tsx | 29 ++++++--------- src/client/views/linking/LinkMenuGroup.tsx | 43 +++------------------- src/client/views/nodes/LinkDocPreview.tsx | 17 ++++----- .../views/nodes/formattedText/FormattedTextBox.tsx | 20 +++++----- 7 files changed, 42 insertions(+), 89 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 3a0c0e3eb..802b8ae7b 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -35,7 +35,7 @@ export class LinkManager { allLinks = computedFn(function allLinks(this: any): Doc[] { const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); - SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc))); + SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).forEach(doc => lset.add(doc))); return Array.from(lset); }, true); @@ -69,13 +69,6 @@ export class LinkManager { return anchorGroups; } - // returns a list of all metadata docs associated with the given group type - public getAllMetadataDocsInGroup(groupType: string): Array { - const md: Doc[] = []; - LinkManager.Instance.allLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); - return md; - } - // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { return -1 !== LinkManager.Instance.allLinks().findIndex(linkDoc => diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 62f733058..97eacaeab 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -352,8 +352,12 @@ export class CollectionStackingView extends CollectionSubView { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { - const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); - Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"])); + const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => NumCast(Doc.Layout(doc)._viewScale, 1) * Number(getComputedStyle(r).height.replace("px", ""))))); + if (this.props.annotationsKey) { + doc[this.props.annotationsKey + "-height"] = height; + } else { + Doc.Layout(doc)._height = height * NumCast(Doc.Layout(doc)._viewScale, 1); + } } })); this.observer.observe(ref); @@ -406,7 +410,7 @@ export class CollectionStackingView extends CollectionSubView { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { const height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); - Doc.Layout(doc)._height = Math.max(height, NumCast(doc[this.props.fieldKey + "-height"])); + Doc.Layout(doc)._height = Math.max(height * NumCast(doc[this.props.fieldKey + "-height"]), NumCast(doc[this.props.fieldKey + "-height"])); } })); this.observer.observe(ref); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4541716f3..21e653e02 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -926,8 +926,7 @@ export class CollectionFreeFormView extends CollectionSubView { } renderAllGroups = (groups: Map>): Array => { - const linkItems: Array = []; - groups.forEach((group, groupType) => { - linkItems.push( - this._editingLink = linkDoc)} - addDocTab={this.props.addDocTab} /> - ); - }); - - // if source doc has no links push message - if (linkItems.length === 0) linkItems.push(

No links have been created yet. Drag the linking button onto another document to create a link.

); - - return linkItems; + const linkItems = Array.from(groups.entries()).map(group => + this._editingLink = linkDoc)} + addDocTab={this.props.addDocTab} />); + + return linkItems.length ? linkItems : [

No links have been created yet. Drag the linking button onto another document to create a link.

]; } @computed diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index e76227ccf..e53655fd3 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -1,17 +1,12 @@ -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; -import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; -import { Docs } from "../../documents/Documents"; -import { DragManager, SetupDrag } from "../../util/DragManager"; +import { Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; import { DocumentView } from "../nodes/DocumentView"; import './LinkMenu.scss'; -import { LinkMenuItem, StartLinkTargetsDrag } from "./LinkMenuItem"; +import { LinkMenuItem } from "./LinkMenuItem"; import React = require("react"); -import { Cast } from "../../../fields/Types"; interface LinkMenuGroupProps { sourceDoc: Doc; @@ -26,34 +21,8 @@ interface LinkMenuGroupProps { export class LinkMenuGroup extends React.Component { private _drag = React.createRef(); - private _table = React.createRef(); private _menuRef = React.createRef(); - onLinkButtonDown = (e: React.PointerEvent): void => { - e.stopPropagation(); - document.removeEventListener("pointermove", this.onLinkButtonMoved); - document.addEventListener("pointermove", this.onLinkButtonMoved); - document.removeEventListener("pointerup", this.onLinkButtonUp); - document.addEventListener("pointerup", this.onLinkButtonUp); - } - - onLinkButtonUp = (e: PointerEvent): void => { - document.removeEventListener("pointermove", this.onLinkButtonMoved); - document.removeEventListener("pointerup", this.onLinkButtonUp); - e.stopPropagation(); - } - - onLinkButtonMoved = async (e: PointerEvent) => { - if (this._drag.current && (e.movementX > 1 || e.movementY > 1)) { - document.removeEventListener("pointermove", this.onLinkButtonMoved); - document.removeEventListener("pointerup", this.onLinkButtonUp); - - const targets = this.props.group.map(l => LinkManager.getOppositeAnchor(l, this.props.sourceDoc)).filter(d => d) as Doc[]; - StartLinkTargetsDrag(this._drag.current, this.props.docView, e.x, e.y, this.props.sourceDoc, targets); - } - e.stopPropagation(); - } - render() { const set = new Set(this.props.group); const groupItems = Array.from(set.keys()).map(linkDoc => { @@ -75,11 +44,9 @@ export class LinkMenuGroup extends React.Component { return (
- {/*
-

{this.props.groupType}:

- {this.props.groupType === "*" || this.props.groupType === "" ? <> : this.viewGroupAsTable(this.props.groupType)} -
*/} +
+

{this.props.groupType}:

+
{groupItems} diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 867be9735..d47942bd9 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -77,19 +77,16 @@ export class LinkDocPreview extends React.Component { this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { _fitWidth: true, title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right"); } } - width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)) - 16; - height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225)) - 16; + width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)); + height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225)); @computed get targetDocView() { return !this._targetDoc ? -
+
{this._toolTipText}
-
: - +
+ : { ContainingCollectionDoc={undefined} ContainingCollectionView={undefined} renderDepth={-1} - PanelWidth={this.width} //Math.min(350, NumCast(target._width, 350))} - PanelHeight={this.height} //Math.min(250, NumCast(target._height, 250))} + PanelWidth={this.width} + PanelHeight={this.height} focus={emptyFunction} whenActiveChanged={returnFalse} bringToFront={returnFalse} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index bc9e8e99d..fe38939c5 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -812,6 +812,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } componentDidMount() { this._cachedLinks = DocListCast(this.Document.links); + this._disposers.sidebarheight = reaction( + () => ({ annoHeight: NumCast(this.rootDoc[this.annotationKey + "-height"]), textHeight: NumCast(this.rootDoc[this.fieldKey + "-height"]) }), + ({ annoHeight, textHeight }) => { + this.layoutDoc._autoHeight && (this.rootDoc._height = Math.max(annoHeight, textHeight)); + }); this._disposers.links = reaction(() => DocListCast(this.Document.links), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks newLinks => { this._cachedLinks.forEach(l => !newLinks.includes(l) && this.RemoveLinkFromDoc(l)); @@ -1540,18 +1545,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, 10); } else { try { - const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); + const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")) * NumCast(this.Document._viewScale, 1); const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); - const finalHeight = newHeight + Math.max(0, outer); - const maxsidebar = !this.sidebarWidth() ? 0 : Array.from(this._boxRef.current!.getElementsByClassName("collectionStackingViewFieldColumn")).reduce((prev, ele) => Math.max(prev, Number(getComputedStyle(ele).height.replace("px", ""))), 0); - if (this.rootDoc._height !== finalHeight && finalHeight > maxsidebar) { - this.rootDoc._height = finalHeight; - this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; - } - this.rootDoc[this.fieldKey + "-height"] = finalHeight; + this.rootDoc[this.fieldKey + "-height"] = newHeight + Math.max(0, outer); } catch (e) { console.log("Error in tryUpdateHeight"); } } - } else this.rootDoc[this.fieldKey + "-height"] = 0; + } //else this.rootDoc[this.fieldKey + "-height"] = 0; } @computed get audioHandle() { @@ -1609,7 +1608,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); - sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0); + sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1)); @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } render() { TraceMobx(); @@ -1631,6 +1630,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp transformOrigin: "top left", width: `${100 / scale}%`, height: `calc(${100 / scale}% - ${this.props.ChromeHeight?.() || 0}px)`, + overflowY: this.layoutDoc._autoHeight ? "hidden" : undefined, ...this.styleFromLayoutString(scale) // this converts any expressions in the format string to style props. e.g., }}>
Date: Tue, 10 Nov 2020 12:51:48 -0500 Subject: fixed performance issues with background grid by avoiding making really big canvases. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 33 ++++++++++------------ src/fields/documentSchemas.ts | 1 + 2 files changed, 16 insertions(+), 18 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 21e653e02..1033050b9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1438,38 +1438,35 @@ export class CollectionFreeFormView extends CollectionSubView { - const w = this.props.PanelWidth() / this.zoomScaling() + 3 * start; - if (w / start > 60) return this.chooseGridSpace(start * 10); - return start; + chooseGridSpace = (gridSpace: number): number => { + const divisions = this.props.PanelWidth() / this.zoomScaling() / gridSpace + 3; + return divisions < 60 ? gridSpace : this.chooseGridSpace(gridSpace * 10); } @computed get grid() { - const gridSpace = this.chooseGridSpace(NumCast(this.layoutDoc["_backgroundGrid-space"], 50)); - const shiftX = this.props.isAnnotationOverlay ? 0 : -(this.panX()) % gridSpace - gridSpace; - const shiftY = this.props.isAnnotationOverlay ? 0 : -(this.panY()) % gridSpace - gridSpace; - const cx = this.centeringShiftX(); - const cy = this.centeringShiftY(); - const w = this.props.PanelWidth() / this.zoomScaling() + 3 * gridSpace; - const h = this.props.PanelHeight() / this.zoomScaling() + 3 * gridSpace; - return { const ctx = el?.getContext('2d'); if (ctx) { - const Cx = (cx / this.zoomScaling()) % gridSpace - 0; - const Cy = (cy / this.zoomScaling()) % gridSpace - 0; - ctx.lineWidth = Math.min(1, Math.max(0.5, 0.5 / this.zoomScaling())) * (gridSpace > 50 ? 3 : 1); + const Cx = this.centeringShiftX() % renderGridSpace; + const Cy = this.centeringShiftY() % renderGridSpace; + ctx.lineWidth = Math.min(1, Math.max(0.5, this.zoomScaling())); ctx.setLineDash(gridSpace > 50 ? [3, 3] : [1, 5]); ctx.clearRect(0, 0, w, h); if (ctx) { ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; - ctx.lineWidth = Math.min(1, Math.max(0.5, 0.5 / this.zoomScaling())); ctx.beginPath(); - for (let x = Cx; x <= -Cx + w; x += gridSpace) { + for (let x = Cx - renderGridSpace; x <= w - Cx; x += renderGridSpace) { ctx.moveTo(x, Cy - h); ctx.lineTo(x, Cy + h); } - for (let y = Cy; y <= -Cy + h; y += gridSpace) { + for (let y = Cy - renderGridSpace; y <= h - Cy; y += renderGridSpace) { ctx.moveTo(Cx - w, y); ctx.lineTo(Cx + w, y); } diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 6e58f7f13..e0404d9d3 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -34,6 +34,7 @@ export const documentSchema = createSchema({ _scrollLeft: "number", // scroll position of a scrollable document (pdf, text, web) // appearance properties on the layout + "_backgroundGrid-spacing": "number", // the size of the grid for collection views _autoHeight: "boolean", // whether the height of the document should be computed automatically based on its contents _nativeWidth: "number", // native width of document which determines how much document contents are scaled when the document's width is set _nativeHeight: "number", // " -- cgit v1.2.3-70-g09d2