From 9ec7503370229c17cf8a0d3cf77571010db04a9b Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 14 Apr 2022 17:40:10 -0400 Subject: presesntation groups --- src/client/views/nodes/trails/PresElementBox.tsx | 86 ++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 5 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index a4ec559f5..1da7a596a 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -2,9 +2,9 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, Opt } from "../../../../fields/Doc"; +import { DataSym, Doc, DocListCast, Opt } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; -import { Cast, NumCast, StrCast } from "../../../../fields/Types"; +import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types"; import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../../Utils"; import { DocUtils } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; @@ -106,6 +106,38 @@ export class PresElementBox extends ViewBoxBaseComponent() { ; } + @computed get renderGroupSlides() { + const childDocs = DocListCast(this.targetDoc.data); + const groupSlides = childDocs.map((doc: Doc, ind: number) => +
{ + console.log("Clicked on slide with index: ", ind); + e.stopPropagation(); + e.preventDefault(); + PresBox.Instance.modifierSelect(doc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); + }}> +
+ {`${ind + 1}.`} +
+ {/* style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105, cursor: isSelected ? 'text' : 'grab' }} */} +
+ StrCast(doc.title)} + SetValue={(value: string) => { + doc.title = !value.trim().length ? "-untitled-" : value; + return true; + }} + /> +
+
+ ); + return ( + groupSlides + ); + } @computed get duration() { let durationInS: number; if (this.rootDoc.type === DocumentType.AUDIO || this.rootDoc.type === DocumentType.VID) { durationInS = NumCast(this.rootDoc.presEndTime) - NumCast(this.rootDoc.presStartTime); durationInS = Math.round(durationInS * 10) / 10; } @@ -284,6 +316,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { const presColorBool: boolean = presBoxColor ? (presBoxColor !== Colors.WHITE && presBoxColor !== "transparent") : false; const targetDoc: Doc = this.targetDoc; const activeItem: Doc = this.rootDoc; + const isGroup: boolean = BoolCast(targetDoc._isGroup); return (
() { PresBox.Instance.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); }} onDoubleClick={action(e => { - this.toggleProperties(); - PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true); + if (isGroup) { + this.rootDoc.presExpandGroup = !this.rootDoc.presExpandGroup; + } else { + this.toggleProperties(); + PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true); + } })} onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} @@ -316,7 +353,46 @@ export class PresElementBox extends ViewBoxBaseComponent() {
{`${this.indexInPres + 1}.`}
} - {miniView ? (null) :
+
+ StrCast(activeItem.title)} + SetValue={this.onSetValue} + /> +
+
+
{"Remove from presentation"}
}>
+ e.stopPropagation()} /> +
+
+
+
+ {this.rootDoc.presExpandGroup ? this.renderGroupSlides : (null)} +
+
{activeItem.presPinView ? (<>View of {targetDoc.title}) : targetDoc.title}
+
{ + if (isGroup) { + this.rootDoc.presExpandGroup = !this.rootDoc.presExpandGroup; + } + }} + > + +
+
+ : (null)} + {miniView || isGroup ? (null) :
Date: Thu, 14 Apr 2022 18:16:01 -0400 Subject: expand children --- src/client/views/nodes/trails/PresElementBox.tsx | 26 +++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 1da7a596a..326c6bd8e 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -114,6 +114,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { e.stopPropagation(); e.preventDefault(); PresBox.Instance.modifierSelect(doc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); + this.presExpandDocumentClick(); }}>
{`${ind + 1}.`} @@ -353,7 +354,7 @@ export class PresElementBox extends ViewBoxBaseComponent() {
{`${this.indexInPres + 1}.`}
} - {isGroup ? + {isGroup ?
() { />
+
{"Update view"}
}> +
this.updateView(targetDoc, activeItem)} + style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
+
+ {this.indexInPres === 0 ? (null) :
{activeItem.groupWithUp ? "Ungroup" : "Group with up"}
}> +
activeItem.groupWithUp = !activeItem.groupWithUp} + style={{ + zIndex: 1000 - this.indexInPres, + fontWeight: 700, + backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : Colors.MEDIUM_BLUE : undefined, + height: activeItem.groupWithUp ? 53 : 18, + transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined + }}> +
+ e.stopPropagation()} /> +
+
+
} +
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> + e.stopPropagation()} /> +
{"Remove from presentation"}
}>
-- cgit v1.2.3-70-g09d2 From 32d9fcec5f3714186ca86872d085063c11f6f13d Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 6 Jun 2022 19:18:58 -0400 Subject: fixed dragging pres elements when presbox is not selected to not display drag element covering entire screen. --- src/client/views/nodes/trails/PresBox.tsx | 4 ++-- src/client/views/nodes/trails/PresElementBox.scss | 4 ++-- src/client/views/nodes/trails/PresElementBox.tsx | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index aa89b8b6c..71e424f72 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -801,13 +801,13 @@ export class PresBox extends ViewBoxBaseComponent() { //regular click @action - regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean) => { + regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, selectPres = true) => { this._selectedArray.clear(); this._selectedArray.set(doc, undefined); this._eleArray.splice(0, this._eleArray.length, ref); this._dragArray.splice(0, this._dragArray.length, drag); focus && this.selectElement(doc); - this.selectPres(); + selectPres && this.selectPres(); } modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean) => { diff --git a/src/client/views/nodes/trails/PresElementBox.scss b/src/client/views/nodes/trails/PresElementBox.scss index 789a6d9f3..19644dd78 100644 --- a/src/client/views/nodes/trails/PresElementBox.scss +++ b/src/client/views/nodes/trails/PresElementBox.scss @@ -192,7 +192,7 @@ $slide-active: #5B9FDD; // } .presItem-slide.active { - box-shadow: 0 0 0px 1.5px $dark-blue; + box-shadow: 0 0 0px 2.5px $dark-blue; } .presItem-slide.group { @@ -201,7 +201,7 @@ $slide-active: #5B9FDD; .presItem-slide.activeGroup { border-radius: 5px; - box-shadow: 0 0 0px 1.5px $dark-blue; + box-shadow: 0 0 0px 2.5px $dark-blue; } .presItem-groupSlideContainer { diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index bbabcb2de..96f79d442 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -167,11 +167,11 @@ export class PresElementBox extends ViewBoxBaseComponent() { e.preventDefault(); if (element && !(e.ctrlKey || e.metaKey)) { if (PresBox.Instance._selectedArray.has(this.rootDoc)) { - PresBox.Instance._selectedArray.size === 1 && PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false); + PresBox.Instance._selectedArray.size === 1 && PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false, false); setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction); } else { setupMoveUpEvents(this, e, ((e: PointerEvent) => { - PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false); + PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false, false); return this.startDrag(e); }), emptyFunction, emptyFunction); } @@ -197,7 +197,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { dragData.moveDocument = this.props.docViewPath().lastElement()?.props.moveDocument; const dragItem: HTMLElement[] = []; if (dragArray.length === 1) { - const doc = dragArray[0]; + const doc = this._itemRef.current || dragArray[0]; doc.className = miniView ? "presItem-miniSlide" : "presItem-slide"; dragItem.push(doc); } else if (dragArray.length >= 1) { @@ -328,7 +328,6 @@ export class PresElementBox extends ViewBoxBaseComponent() { key={this.props.Document[Id] + this.indexInPres} ref={this._itemRef} style={{ - backgroundColor: presColorBool ? isSelected ? "rgba(250,250,250,0.3)" : "transparent" : isSelected ? Colors.LIGHT_BLUE : "transparent", opacity: this._dragging ? 0.3 : 1 }} onClick={e => { -- cgit v1.2.3-70-g09d2 From 1d48114a43de38a95fa40fbc71a3c64c20d9d398 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 6 Jun 2022 21:12:27 -0400 Subject: fixed updateView for audio/video presbox elements. --- src/client/views/DocumentButtonBar.tsx | 1 - src/client/views/PropertiesButtons.tsx | 12 ++++----- src/client/views/collections/CollectionMenu.tsx | 3 +-- src/client/views/nodes/trails/PresElementBox.tsx | 34 +++++++++++++----------- 4 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index b2f4b82a4..c0645f0ab 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -227,7 +227,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV activeDoc.presPinView = true; activeDoc.presStartTime = targetDoc._currentTimecode; activeDoc.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1; - activeDoc.presPinTimecode = targetDoc._currentTimecode; } else if (pannable) { const x = targetDoc._panX; const y = targetDoc._panY; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 24857d8ee..f24ff09db 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -3,25 +3,23 @@ import { Tooltip } from '@material-ui/core'; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc, Opt } from "../../fields/Doc"; +import { Id } from "../../fields/FieldSymbols"; import { InkField } from '../../fields/InkField'; import { RichTextField } from '../../fields/RichTextField'; import { BoolCast, StrCast } from "../../fields/Types"; +import { ImageField } from "../../fields/URLField"; import { DocUtils } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; import { SelectionManager } from '../util/SelectionManager'; import { undoBatch } from '../util/UndoManager'; import { CollectionViewType } from './collections/CollectionView'; +import { Colors } from "./global/globalEnums"; import { InkingStroke } from './InkingStroke'; import { DocumentView } from './nodes/DocumentView'; +import { VideoBox } from "./nodes/VideoBox"; +import { pasteImageBitmap } from "./nodes/WebBoxRenderer"; import './PropertiesButtons.scss'; import React = require("react"); -import { Colors } from "./global/globalEnums"; -import { CollectionFreeFormView } from "./collections/collectionFreeForm"; -import { DocumentManager } from "../util/DocumentManager"; -import { pasteImageBitmap } from "./nodes/WebBoxRenderer"; -import { VideoBox } from "./nodes/VideoBox"; -import { Id } from "../../fields/FieldSymbols"; -import { ImageField } from "../../fields/URLField"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 23fd4206c..01e77f342 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -457,7 +457,7 @@ export class CollectionViewBaseChrome extends React.Component{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
} placement="top">
; @@ -507,7 +507,6 @@ export class CollectionViewBaseChrome extends React.Component() { @undoBatch @action updateView = (targetDoc: Doc, activeItem: Doc) => { - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { - const scroll = targetDoc._scrollTop; - activeItem.presPinViewScroll = scroll; - } else if (targetDoc.type === DocumentType.VID) { - activeItem.presPinTimecode = targetDoc._currentTimecode; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const clipWidth = targetDoc._clipWidth; - activeItem.presPinClipWidth = clipWidth; - } else { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; + switch (targetDoc.type) { + case DocumentType.PDF: case DocumentType.WEB: case DocumentType.RTF : + const scroll = targetDoc._scrollTop; + activeItem.presPinViewScroll = scroll; + break; + case DocumentType.VID: case DocumentType.AUDIO: + activeItem.presStartTime = targetDoc._currentTimecode; + break; + case DocumentType.COMPARISON : + const clipWidth = targetDoc._clipWidth; + activeItem.presPinClipWidth = clipWidth; + break; + default: + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; } } -- cgit v1.2.3-70-g09d2 From 69fbc57e813b55963911629dba552f633928d10b Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 7 Jun 2022 10:08:25 -0400 Subject: simplified interaction between PresElementBox and PresBox for sharing presBox data. fixed problem with miniView getting the wrong slide count. --- src/client/views/DocComponent.tsx | 3 -- .../collections/collectionFreeForm/MarqueeView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/trails/PresBox.tsx | 52 +++++++++------------- src/client/views/nodes/trails/PresElementBox.tsx | 10 ++--- 5 files changed, 25 insertions(+), 43 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 9c176a4fd..67f8c8585 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -60,12 +60,9 @@ export function ViewBoxBaseComponent

() { @computed get layoutDoc() { return Doc.Layout(this.props.Document); } // This is the data part of a document -- ie, the data that is constant across all views of the document @computed get dataDoc() { return this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : this.props.Document[DataSym]; } - // key where data is stored @computed get fieldKey() { return this.props.fieldKey; } - lookupField = (field: string) => ScriptCast(this.layoutDoc.lookupField)?.script.run({ self: this.layoutDoc, data: this.rootDoc, field: field, container: this.props.DocumentView?.().props.treeViewDoc ?? this.props.ContainingCollectionDoc }).result; - isContentActive = (outsideReaction?: boolean) => ( this.props.isContentActive?.() === false ? false : (CurrentUserUtils.SelectedTool !== InkTool.None || diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index efdcfd48e..3fac3350a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -404,7 +404,6 @@ export class MarqueeView extends React.Component { - console.log("pinWithView"); const scale = Math.min(this.props.PanelWidth() / this.Bounds.width, this.props.PanelHeight() / this.Bounds.height); const doc = this.props.Document; const viewOptions:PinViewProps = { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 073f734c0..59a402e01 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -956,7 +956,7 @@ export class DocumentViewInternal extends DocComponent !d.hidden); return filtered.map((link, i) =>

diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index b6ce3e77a..980bdf4d6 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -10,17 +10,16 @@ import { InkTool } from "../../../../fields/InkField"; import { List } from "../../../../fields/List"; import { PrefetchProxy } from "../../../../fields/Proxy"; import { listSpec } from "../../../../fields/Schema"; -import { ScriptField } from "../../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types"; import { emptyFunction, returnFalse, returnOne, returnTrue, setupMoveUpEvents } from '../../../../Utils'; import { Docs } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; import { DocumentManager } from "../../../util/DocumentManager"; -import { ScriptingGlobals } from "../../../util/ScriptingGlobals"; import { SelectionManager } from "../../../util/SelectionManager"; import { undoBatch, UndoManager } from "../../../util/UndoManager"; import { CollectionDockingView } from "../../collections/CollectionDockingView"; +import { MarqueeViewBounds } from "../../collections/collectionFreeForm"; import { CollectionView, CollectionViewType } from "../../collections/CollectionView"; import { TabDocView } from "../../collections/TabDocView"; import { ViewBoxBaseComponent } from "../../DocComponent"; @@ -30,7 +29,6 @@ import { CollectionFreeFormDocumentView } from "../CollectionFreeFormDocumentVie import { FieldView, FieldViewProps } from '../FieldView'; import "./PresBox.scss"; import { PresEffect, PresMovement, PresStatus } from "./PresEnums"; -import { MarqueeViewBounds } from "../../collections/collectionFreeForm"; export interface PinProps { audioRange?: boolean; @@ -44,7 +42,6 @@ export interface PinViewProps { scale: number; } - @observer export class PresBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); } @@ -105,11 +102,10 @@ export class PresBox extends ViewBoxBaseComponent() { @observable private openMovementDropdown: boolean = false; @observable private openEffectDropdown: boolean = false; @observable private presentTools: boolean = false; - // @computed get childDocs() { return DocListCast(this.rootDoc[this.fieldKey]); } - // TODO: [AL] add childDocs() and treeMap fields - // @computed get childDocs() { return DocListCast(this.rootDoc.presentationaLinearizedDocuments); } - //_treeViewMap:Map - @computed get childDocs() { return this.layoutDoc._viewType === CollectionViewType.Tree ? DocListCast(this.rootDoc.presentationLinearizedDocuments) : DocListCast(this.rootDoc[this.fieldKey]); } + @computed get isTreeOrStack() {return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._viewType) as any) } + @computed get isTree() { return this.layoutDoc._viewType === CollectionViewType.Tree;} + @computed get presFieldKey() { return StrCast(this.dataDoc.presFieldKey); } + @computed get childDocs() { return DocListCast(this.rootDoc[this.presFieldKey]); } @observable _treeViewMap: Map = new Map(); @computed get tagDocs() { @@ -139,12 +135,6 @@ export class PresBox extends ViewBoxBaseComponent() { Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({ title: "pres element template", type: DocumentType.PRESELEMENT, _fitWidth: true, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data" })); - // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement - // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent - // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data - // stored on each pres element. - (this.presElement as Doc).lookupField = ScriptField.MakeFunction("lookupPresBoxField(container, field, data)", - { field: "string", data: Doc.name, container: Doc.name }); } this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox @@ -164,8 +154,10 @@ export class PresBox extends ViewBoxBaseComponent() { } @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } + _unmounting = false; @action componentWillUnmount() { + this._unmounting = true; document.removeEventListener("keydown", PresBox.keyEventsWrapper, true); this._presKeyEventsActive = false; this.resetPresentation(); @@ -176,7 +168,7 @@ export class PresBox extends ViewBoxBaseComponent() { @action componentDidMount() { - this.rootDoc.presBox = this.rootDoc; + this._unmounting = false; this.rootDoc._forceRenderEngine = "timeline"; this.layoutDoc.presStatus = PresStatus.Edit; this.layoutDoc._gridGap = 0; @@ -640,7 +632,10 @@ export class PresBox extends ViewBoxBaseComponent() { // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here [CollectionViewType.Tree || CollectionViewType.Stacking].includes(viewType) && (this.rootDoc._pivotField = undefined); this.rootDoc._viewType = viewType; - if ([CollectionViewType.Tree || CollectionViewType.Stacking].includes(viewType)) this.layoutDoc._gridGap = 0; + if (this.isTreeOrStack) { + this.layoutDoc.presFieldKey = this.fieldKey+(this.isTree ?"-linearized":""); + this.layoutDoc._gridGap = 0; + } }); /** @@ -714,7 +709,7 @@ export class PresBox extends ViewBoxBaseComponent() { }); return true; } - childLayoutTemplate = () => ![CollectionViewType.Stacking, CollectionViewType.Tree].includes(this.rootDoc._viewType as any) ? undefined : this.presElement; + childLayoutTemplate = () => !this.isTreeOrStack ? undefined : this.presElement; removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.rootDoc, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; @@ -2468,14 +2463,16 @@ export class PresBox extends ViewBoxBaseComponent() { } if (this._treeViewMap.get(treeViewDoc) !== indexNum) { this._treeViewMap.set(treeViewDoc, indexNum); - this.props.Document.presentationLinearizedDocuments = new List(this.sort(this._treeViewMap)); // this is a flat array of Docs + this.dataDoc[this.presFieldKey] = new List(this.sort(this._treeViewMap)); // this is a flat array of Docs } return this.childDocs; } RemFromMap = (treeViewDoc: Doc, index: number[]): Doc[] => { - this._treeViewMap.delete(treeViewDoc); - this.props.Document.presentationLinearizedDocuments = new List(this.sort(this._treeViewMap)); + if (!this._unmounting && this.isTree) { + this._treeViewMap.delete(treeViewDoc); + this.dataDoc[this.presFieldKey] = new List(this.sort(this._treeViewMap)); + } return this.childDocs; } @@ -2536,8 +2533,8 @@ export class PresBox extends ViewBoxBaseComponent() { removeDocument={returnFalse} dontRegisterView={true} focus={this.selectElement} + scriptContext={this} ScreenToLocalTransform={this.getTransform} - // TODO: [AL] implement AddToMap, RemFromMap functions (outside this) AddToMap={this.AddToMap} RemFromMap={this.RemFromMap} hierarchyIndex={[]} @@ -2555,13 +2552,4 @@ export class PresBox extends ViewBoxBaseComponent() {
; } -} -// this func communicates with PresBoxElement to send information of the doc -ScriptingGlobals.add(function lookupPresBoxField(presBoxDoc: Doc, field: string, presEleDoc: Doc) { - if (field === 'indexInPres') return DocListCast(presBoxDoc._viewType === CollectionViewType.Tree ? presBoxDoc.presentationLinearizedDocuments : presBoxDoc[StrCast(presBoxDoc.presentationFieldKey)]).indexOf(presEleDoc); - if (field === 'presCollapsedHeight') return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(presBoxDoc._viewType as any) ? 35 : 31; - if (field === 'presStatus') return presBoxDoc.presStatus; - if (field === '_itemIndex') return presBoxDoc._itemIndex; - if (field === 'presBox') return presBoxDoc; - return undefined; -}); \ No newline at end of file +} \ No newline at end of file diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 19435d22c..b9951eaae 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -34,12 +34,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { _heightDisposer: IReactionDisposer | undefined; @observable _dragging = false; - // these fields are conditionally computed fields on the layout document that take this document as a parameter - @computed get indexInPres() { return Number(this.lookupField("indexInPres")); } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements) - @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up - @computed get presStatus() { return StrCast(this.lookupField("presStatus")); } - @computed get itemIndex() { return NumCast(this.lookupField("_itemIndex")); } - @computed get presBox() { return Cast(this.lookupField("presBox"), Doc, null); } + @computed get indexInPres() { return DocListCast(this.presBox[StrCast(this.presBox.presFieldKey, "data")]).indexOf(this.rootDoc); } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements) + @computed get collapsedHeight() { return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(this.presBox._viewType as any) ? 35 : 31; } // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up + @computed get presStatus() { return this.presBox.presStatus; } + @computed get presBox() { return (this.props.DocumentView?.().props.treeViewDoc ?? this.props.ContainingCollectionDoc)!; } @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; } componentDidMount() { -- cgit v1.2.3-70-g09d2 From 7c24d7bb4a24c5224b89585c940db070b82e89fc Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 8 Jun 2022 20:03:04 -0400 Subject: fixes from merge --- src/client/Network.ts | 1 - src/client/util/DragManager.ts | 4 ---- src/client/views/GestureOverlay.tsx | 4 +++- src/client/views/nodes/AudioBox.tsx | 2 -- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/Network.ts b/src/client/Network.ts index 1255e5ce0..3597e7b2b 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -19,7 +19,6 @@ export namespace Networking { } export async function UploadFilesToServer(files: File | File[]): Promise[]> { - console.log(files) const formData = new FormData(); if (Array.isArray(files)) { if (!files.length) { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index f438a8c11..9f8c49081 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -210,10 +210,6 @@ export namespace DragManager { options?: DragOptions, dropEvent?: () => any ) { - // stop an 'accidental' on-click drag that may have occured if the user is in presenting mode - // note: dragData.dropAction is only undefined when the element itself being dragged without being selected - if (Doc.UserDoc()?.presentationMode === 'recording' && dragData.dropAction === undefined) return false; - const addAudioTag = (dropDoc: any) => { dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField); dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 30982bfae..317f5f5d7 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -645,7 +645,9 @@ export class GestureOverlay extends Touchable { (controlPoints[0].Y - controlPoints.lastElement().Y) * (controlPoints[0].Y - controlPoints.lastElement().Y)); if (controlPoints.length > 4 && dist < 10) controlPoints[controlPoints.length - 1] = controlPoints[0]; this._points = controlPoints; - this.dispatchGesture(GestureUtils.Gestures.Stroke); + this.dispatchGesture(GestureUtils.Gestures.Stroke); + // TODO: nda - check inks to group here + checkInksToGroup(); } this._points = []; } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 70d730ad1..7ff3196da 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -4,8 +4,6 @@ import { action, computed, IReactionDisposer, observable, runInAction } from "mo import { observer } from "mobx-react"; import { DateField } from "../../../fields/DateField"; import { Doc, DocListCast } from "../../../fields/Doc"; -import { documentSchema } from "../../../fields/documentSchemas"; -import { makeInterface } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, DateCast, NumCast } from "../../../fields/Types"; import { AudioField, nullAudio } from "../../../fields/URLField"; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 39c9478bf..8e53abdba 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -197,7 +197,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { dragData.moveDocument = this.props.docViewPath().lastElement()?.props.moveDocument; const dragItem: HTMLElement[] = []; if (dragArray.length === 1) { - const doc = dragArray[0]; + const doc = this._itemRef.current || dragArray[0]; doc.className = miniView ? "presItem-miniSlide" : "presItem-slide"; dragItem.push(doc); } else if (dragArray.length >= 1) { -- cgit v1.2.3-70-g09d2 From ec2e780141fb41d3f70aa86b0312211e0b30257c Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 9 Jun 2022 10:39:14 -0400 Subject: fixed issues with pinWithView so that thumnails show the pinned area and navigating to the view shows the entire pinned area regardless of panel size. --- src/client/views/DocumentButtonBar.tsx | 29 +------------------ src/client/views/collections/TabDocView.tsx | 33 ++++++++++++++++++++++ .../collectionFreeForm/CollectionFreeFormView.tsx | 10 +++++-- src/client/views/nodes/DocumentView.tsx | 1 + src/client/views/nodes/trails/PresBox.tsx | 20 +++++++++++-- src/client/views/nodes/trails/PresElementBox.tsx | 8 +++--- 6 files changed, 64 insertions(+), 37 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 103734b9b..41224b1c5 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -212,34 +212,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @undoBatch @action - pinWithView = (targetDoc: Doc) => { - const activeDoc = targetDoc && TabDocView.PinDoc(targetDoc); - if (activeDoc) { - const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || 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 ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) { - activeDoc.presPinView = true; - activeDoc.presStartTime = targetDoc._currentTimecode; - activeDoc.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1; - } else if (pannable) { - 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; - } - } - } + pinWithView = (targetDoc: Doc) => targetDoc && TabDocView.PinDoc(targetDoc, {pinDocView: true}); @computed get pinWithViewButton() { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 34fe572e3..f6a75e2db 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -227,6 +227,39 @@ export class TabDocView extends React.Component { pinDoc.presPinViewX = viewProps.bounds.left + viewProps.bounds.width / 2; pinDoc.presPinViewY = viewProps.bounds.top + viewProps.bounds.height / 2; pinDoc.presPinViewScale = viewProps.scale; + pinDoc.contentBounds = new List([viewProps.bounds.left, viewProps.bounds.top, viewProps.bounds.left+viewProps.bounds.width, viewProps.bounds.top+viewProps.bounds.height]); + } + if (pinProps?.pinDocView) { + const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(pinDoc.type as any) || pinDoc._viewType === CollectionViewType.Stacking; + const pannable: boolean = ((pinDoc.type === DocumentType.COL && doc._viewType === CollectionViewType.Freeform) || doc.type === DocumentType.IMG); + if (scrollable) { + const scroll = doc._scrollTop; + pinDoc.presPinView = true; + pinDoc.presPinViewScroll = scroll; + } else if ([DocumentType.AUDIO, DocumentType.VID].includes(doc.type as any)) { + pinDoc.presPinView = true; + pinDoc.presStartTime = doc._currentTimecode; + pinDoc.presEndTime = NumCast(doc._currentTimecode) + 0.1; + } else if (pannable) { + pinDoc.presPinView = true; + pinDoc.presPinViewX = pinDoc._panX; + pinDoc.presPinViewY = pinDoc._panY; + pinDoc.presPinViewScale = pinDoc._viewScale; + const pw = NumCast(pinProps.panelWidth); + const ph = NumCast(pinProps.panelHeight); + const ps = NumCast(pinDoc._viewScale); + if (pw && ph && ps) { + pinDoc.contentBounds = new List([ + NumCast(pinDoc.panX)-pw/2/ps, + NumCast(pinDoc.panY)-ph/2/ps, + NumCast(pinDoc.panX)+pw/2/ps, + NumCast(pinDoc.panY)+ph/2/ps]); + } + } else if (doc.type === DocumentType.COMPARISON) { + const width = doc._clipWidth; + pinDoc.presPinClipWidth = width; + pinDoc.presPinView = true; + } } Doc.AddDocToList(curPres, "data", pinDoc, presSelected); if (!pinProps?.audioRange && duration !== undefined) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5f927a2a9..b70e6ff98 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -56,6 +56,7 @@ import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { FieldView, FieldViewProps } from "../../nodes/FieldView"; +import { TabDocView } from "../TabDocView"; export const panZoomSchema = createSchema({ _panX: "number", @@ -138,7 +139,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 contentBounds() { + const cb = Cast(this.rootDoc.contentBounds, listSpec("number")); + return cb ? {x:cb[0], y:cb[1], r:cb[2], b: cb[3]} : + this.props.contentBounds?.() ?? aggregateBounds(this._layoutElements.filter(e => 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 : Doc.NativeWidth(this.Document); } @computed get nativeHeight() { return this.fitToContent ? 0 : Doc.NativeHeight(this.Document); } @computed get cachedCenteringShiftX(): number { @@ -1612,7 +1617,8 @@ export class CollectionFreeFormView extends CollectionSubView { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" }); !Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); - appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" }); + appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, {pinDocView:true, panelWidth: this.props.PanelWidth(), panelHeight:this.props.PanelHeight()}), icon: "map-pin" }); + //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" }); this.props.ContainingCollectionView && appearanceItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 59a402e01..26dec3bd5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -112,6 +112,7 @@ export interface DocumentViewSharedProps { renderDepth: number; Document: Doc; DataDoc?: Doc; + contentBounds?: () => (undefined|{x:number, y:number, r:number, b:number}); fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 591480023..6de04bd31 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -35,6 +35,9 @@ export interface PinProps { setPosition?: boolean; hidePresBox?: boolean; pinWithView?: PinViewProps; + pinDocView?: boolean; + panelWidth?: number; + panelHeight?: number } export interface PinViewProps { @@ -339,10 +342,21 @@ export class PresBox extends ViewBoxBaseComponent() { } else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) { bestTarget._currentTimecode = activeItem.presStartTime; } else { + const contentBounds= Cast(activeItem.contentBounds, listSpec("number")); bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; - bestTarget._panX = activeItem.presPinViewX; - bestTarget._panY = activeItem.presPinViewY; - bestTarget._viewScale = activeItem.presPinViewScale; + if (contentBounds) { + bestTarget._panX = (contentBounds[0] + contentBounds[2])/2; + bestTarget._panY = (contentBounds[1] + contentBounds[3])/2; + const dv = DocumentManager.Instance.getDocumentView(bestTarget); + if (dv) { + bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]), + dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0])); + }; + } else { + bestTarget._panX = activeItem.presPinViewX; + bestTarget._panY = activeItem.presPinViewY; + bestTarget._viewScale = activeItem.presPinViewScale; + } } this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510); }); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index b9951eaae..5eff47a86 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, DocListCast, Opt } from "../../../../fields/Doc"; +import { Doc, DocListCast, Opt } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types"; import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../../Utils"; @@ -13,6 +13,7 @@ import { DocumentManager } from "../../../util/DocumentManager"; import { DragManager } from "../../../util/DragManager"; import { Transform } from "../../../util/Transform"; import { undoBatch } from "../../../util/UndoManager"; +import { CollectionViewType } from "../../collections/CollectionView"; import { ViewBoxBaseComponent } from '../../DocComponent'; import { EditableView } from "../../EditableView"; import { Colors } from "../../global/globalEnums"; @@ -23,7 +24,6 @@ import { PresBox } from "./PresBox"; import "./PresElementBox.scss"; import { PresMovement } from "./PresEnums"; import React = require("react"); -import { CollectionViewType } from "../../collections/CollectionView"; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. @@ -75,8 +75,8 @@ export class PresElementBox extends ViewBoxBaseComponent() { return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
Date: Thu, 9 Jun 2022 11:07:34 -0400 Subject: renamed fitToBox to fitContentsToBox. fixed pinning multiple documents at same time to not bring up presBox multiple times. --- src/client/documents/Documents.ts | 3 +- src/client/views/DocumentButtonBar.tsx | 21 ++---------- src/client/views/LightboxView.tsx | 2 -- src/client/views/MainView.tsx | 2 +- src/client/views/PropertiesButtons.tsx | 2 +- src/client/views/PropertiesView.tsx | 2 +- src/client/views/collections/CollectionMenu.tsx | 4 +-- .../views/collections/CollectionTimeView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 25 +++++++-------- src/client/views/collections/TreeView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 37 +++++++--------------- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 2 +- .../CollectionMultirowView.tsx | 2 +- .../collectionSchema/CollectionSchemaView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 4 +-- src/client/views/nodes/MapBox/MapBox.tsx | 6 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 6 ++-- src/client/views/nodes/trails/PresBox.tsx | 14 ++++---- src/client/views/nodes/trails/PresElementBox.tsx | 2 +- src/fields/documentSchemas.ts | 6 ++-- src/mobile/AudioUpload.tsx | 4 +-- 22 files changed, 60 insertions(+), 92 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index acc1e341a..144a3d9cf 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -113,7 +113,8 @@ export class DocumentOptions { _dimMagnitude?: NUMt = new NumInfo("magnitude of collectionMulti{row,col} element's width or height", true); _dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units", true); _fitWidth?: BOOLt = new BoolInfo("whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)", true); - _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents + _fitContentsToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents + _contentBounds?: List; // the (forced) bounds of the document to display. format is: [left, top, right, bottom] _lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed _isPushpin?: boolean; // whether document, when clicked, toggles display of its link target diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 41224b1c5..0bbe473d7 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -204,27 +204,13 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{SelectionManager.Views().length > 1 ? "Pin multiple documents to presentation" : "Pin to presentation"}
}>
this.props.views().map(view => view && this.pinWithView(view.props.Document)))}> + onClick={(e => TabDocView.PinDoc(this.props.views().filter(v => v).map(dv => dv!.rootDoc), {pinDocView: true}))} + >
; } - @undoBatch - @action - pinWithView = (targetDoc: Doc) => targetDoc && TabDocView.PinDoc(targetDoc, {pinDocView: true}); - - @computed - get pinWithViewButton() { - const presPinWithViewIcon = ; - const targetDoc = this.view0?.props.Document; - return !targetDoc ? (null) :
{"Pin with current view"}
}> -
this.pinWithView(targetDoc)}> - {presPinWithViewIcon} -
-
; - } - @computed get shareButton() { const targetDoc = this.view0?.props.Document; @@ -349,9 +335,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{this.pinButton}
- {/*
- {this.pinWithViewButton} -
*/} {!Doc.UserDoc()["documentLinksButton-fullMenu"] ? (null) :
{this.shareButton}
} diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index f67f37bfb..fcc4aea13 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -207,7 +207,6 @@ export class LightboxView extends React.Component { future = () => LightboxView._future; tourMap = () => LightboxView._tourMap; - fitToBox = () => LightboxView._docTarget === LightboxView.LightboxDoc; render() { let downx = 0, downy = 0; return !LightboxView.LightboxDoc ? (null) : @@ -241,7 +240,6 @@ export class LightboxView extends React.Component { DataDoc={undefined} LayoutTemplate={LightboxView.LightboxDocTemplate} addDocument={undefined} - // fitContentsToDoc={this.fitToBox} // bcz: why do we want this? when we initially open a colletion, we shrinkwrap it which allows for user navigation. if we later encounter a collection, it's not clear to me that we want to make it either shrinkwrap or fitContents... isDocumentActive={returnFalse} isContentActive={returnTrue} addDocTab={this.addDocTab} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 641178cd9..84a131a57 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -287,7 +287,7 @@ export class MainView extends React.Component { styleProvider={DefaultStyleProvider} rootSelected={returnTrue} removeDocument={returnFalse} - fitContentsToDoc={returnTrue} + fitContentsToBox={returnTrue} isDocumentActive={returnTrue} // headerBar is always documentActive (ie, the docView gets pointer events) isContentActive={returnTrue} // headerBar is awlays contentActive which means its items are always documentActive ScreenToLocalTransform={this.headerBarScreenXf} diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index f24ff09db..74055f057 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -71,7 +71,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { return this.propertyToggleBtn("Lock\xA0View", "_lockedTransform", on => `${on ? "Unlock" : "Lock"} panning of view`, on => "lock"); } @computed get fitContentButton() { - return this.propertyToggleBtn("View All", "_fitToBox", on => `${on ? "Don't" : "Do"} fit content to container visible area`, on => "eye"); + return this.propertyToggleBtn("View All", "_fitContentsToBox", on => `${on ? "Don't" : "Do"} fit content to container visible area`, on => "eye"); } @computed get fitWidthButton() { return this.propertyToggleBtn("Fit\xA0Width", "_fitWidth", on => `${on ? "Don't" : "Do"} fit content to width of container`, on => "arrows-alt-h"); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index bcfd2dd56..16eb95cf4 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -300,7 +300,7 @@ export class PropertiesView extends React.Component { Document={layoutDoc} DataDoc={this.dataDoc} renderDepth={1} - fitContentsToDoc={returnTrue} + fitContentsToBox={returnTrue} rootSelected={returnFalse} styleProvider={DefaultStyleProvider} docViewPath={returnEmptyDoclist} diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 01e77f342..39f6466d6 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -252,8 +252,8 @@ export class CollectionViewBaseChrome extends React.Component this.target._fitToBox = !this.target._fitToBox), + script: "self.target._fitContentsToBox = !self.target._fitContentsToBox;", + immediate: undoBatch((source: Doc[]) => this.target._fitContentsToBox = !this.target._fitContentsToBox), initialize: emptyFunction }; _fitContentCommand = { diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 4f6f45d2f..7573b938a 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -135,7 +135,7 @@ export class CollectionTimeView extends CollectionSubView() { onClick={this.contentsDown}> { * Adds a document to the presentation view **/ @action - public static PinDoc(doc: Doc, pinProps?: PinProps) { - //add this new doc to props.Document + public static PinDoc(docs: Doc|Doc[], pinProps?: PinProps) { + const docList = ((docs instanceof Doc) ? [docs]: docs); + const batch = UndoManager.StartBatch("pinning doc"); // all docs will be added to the ActivePresentation as stored on CurrentUserUtils const curPres = CurrentUserUtils.ActivePresentation; - if (curPres) { + curPres && docList.forEach(doc => { // Edge Case 1: Cannot pin document to itself 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"; @@ -279,17 +279,16 @@ export class TabDocView extends React.Component { pinDoc.presMovement = PresMovement.None; } if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true; - if (!Array.from(CollectionDockingView.Instance.tabMap).map(d => d.DashDoc).includes(curPres)) { - const docs = Cast(Cast(Doc.UserDoc().myOverlayDocs, Doc, null).data, listSpec(Doc), []); - if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1); - CollectionDockingView.AddSplit(curPres, "right"); - setTimeout(() => DocumentManager.Instance.jumpToDocument(doc, false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things - } PresBox.Instance?._selectedArray.clear(); pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array - setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs - return pinDoc; + }); + if (!Array.from(CollectionDockingView.Instance.tabMap).map(d => d.DashDoc).includes(curPres)) { + const docs = Cast(Cast(Doc.UserDoc().myOverlayDocs, Doc, null).data, listSpec(Doc), []); + if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1); + CollectionDockingView.AddSplit(curPres, "right"); + setTimeout(() => DocumentManager.Instance.jumpToDocument(docList.lastElement(), false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things } + setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs } componentDidMount() { @@ -572,7 +571,7 @@ export class TabMinimapView extends React.Component { docFilters={CollectionDockingView.Instance.childDocFilters} docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters} searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs} - fitContentsToDoc={returnTrue} + fitContentsToBox={returnTrue} />
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 09f05f69a..8824750a3 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -796,7 +796,7 @@ export class TreeView extends React.Component { isDocumentActive={isActive} styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} hideTitle={asText} - fitContentsToDoc={returnTrue} + fitContentsToBox={returnTrue} hideDecorationTitle={this.props.treeView.outlineMode} hideResizeHandles={this.props.treeView.outlineMode} onClick={this.onChildClick} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b70e6ff98..ec3cf1fe8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -9,7 +9,7 @@ import { InkData, InkField, InkTool, PointData, Segment } from "../../../../fiel import { List } from "../../../../fields/List"; import { ObjectField } from "../../../../fields/ObjectField"; import { RichTextField } from "../../../../fields/RichTextField"; -import { createSchema, listSpec } from "../../../../fields/Schema"; +import { listSpec } from "../../../../fields/Schema"; import { ScriptField } from "../../../../fields/ScriptField"; import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types"; import { ImageField } from "../../../../fields/URLField"; @@ -41,6 +41,7 @@ import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveIn import { LightboxView } from "../../LightboxView"; import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView"; +import { FieldViewProps } from "../../nodes/FieldView"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { PresBox } from "../../nodes/trails/PresBox"; import { VideoBox } from "../../nodes/VideoBox"; @@ -50,27 +51,13 @@ import { CollectionDockingView } from "../CollectionDockingView"; import { CollectionSubView } from "../CollectionSubView"; import { TreeViewType } from "../CollectionTreeView"; import { CollectionViewType } from "../CollectionView"; +import { TabDocView } from "../TabDocView"; import { computePivotLayout, computerPassLayout, computerStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from "./CollectionFreeFormLayoutEngines"; import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors"; import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); -import { FieldView, FieldViewProps } from "../../nodes/FieldView"; -import { TabDocView } from "../TabDocView"; -export const panZoomSchema = createSchema({ - _panX: "number", - _panY: "number", - _currentTimecode: "number", - _timecodeToShow: "number", - _currentFrame: "number", - _useClusters: "boolean", - _viewTransition: "string", - _xPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set - _yPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set - _fitToBox: "boolean", - scrollHeight: "number" // this will be set when the collection is an annotation overlay for a PDF/Webpage -}); export type collectionFreeformViewProps = { annotationLayerHostsContent?: boolean; // whether to force scaling of content (needed by ImageBox) @@ -138,20 +125,20 @@ 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 : Doc.NativeWidth(this.Document); } - @computed get nativeHeight() { return this.fitToContent ? 0 : Doc.NativeHeight(this.Document); } + @computed get nativeWidth() { return this.fitContentsToBox ? 0 : Doc.NativeWidth(this.Document); } + @computed get nativeHeight() { return this.fitContentsToBox ? 0 : Doc.NativeHeight(this.Document); } @computed get cachedCenteringShiftX(): number { - const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling; + const scaling = this.fitContentsToBox || !this.contentScaling ? 1 : this.contentScaling; return this.props.isAnnotationOverlay ? 0 : this.props.PanelWidth() / 2 / scaling; // shift so pan position is at center of window for non-overlay collections } @computed get cachedCenteringShiftY(): number { - const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling; + const scaling = this.fitContentsToBox || !this.contentScaling ? 1 : this.contentScaling; return this.props.isAnnotationOverlay ? 0 : this.props.PanelHeight() / 2 / scaling;// shift so pan position is at center of window for non-overlay collections } @computed get cachedGetLocalTransform(): Transform { @@ -176,8 +163,8 @@ export class CollectionFreeFormView extends CollectionSubView !this._firstRender && (this.fitToContent || force) ? this.fitToContentVals : undefined; - reverseNativeScaling = () => this.fitToContent ? true : false; + freeformData = (force?: boolean) => !this._firstRender && (this.fitContentsToBox || force) ? this.fitToContentVals : undefined; + reverseNativeScaling = () => this.fitContentsToBox ? true : false; panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document._panX); panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document._panY); zoomScaling = () => (this.freeformData()?.scale ?? NumCast(this.Document[this.scaleFieldKey], 1)); @@ -1272,7 +1259,7 @@ export class CollectionFreeFormView extends CollectionSubView; } addDocTab = action((doc: Doc, where: string) => { @@ -1616,7 +1603,7 @@ export class CollectionFreeFormView extends CollectionSubView { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" }); !Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); - appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); + appearanceItems.push({ description: `${this.fitContentsToBox ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitContentsToBox = !this.fitContentsToBox, icon: !this.fitContentsToBox ? "expand-arrows-alt" : "compress-arrows-alt" }); appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, {pinDocView:true, panelWidth: this.props.PanelWidth(), panelHeight:this.props.PanelHeight()}), icon: "map-pin" }); //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" }); this.props.ContainingCollectionView && diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 3fac3350a..6df2bb102 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -516,7 +516,7 @@ export class MarqueeView extends React.Component Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box) scrollFocus?: (doc: Doc, smooth: boolean) => Opt; // returns the duration of the focus setViewSpec?: (anchor: Doc, preview: boolean) => void; // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document - reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height. However, some content views (e.g., FreeFormView w/ fitToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling. + reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height. However, some content views (e.g., FreeFormView w/ fitContentsToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling. shrinkWrap?: () => void; // requests a document to display all of its contents with no white space. currently only implemented (needed?) for freeform views menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected. isAnyChildContentActive?: () => boolean; // is any child content of the document active @@ -113,7 +113,7 @@ export interface DocumentViewSharedProps { Document: Doc; DataDoc?: Doc; contentBounds?: () => (undefined|{x:number, y:number, r:number, b:number}); - fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document + fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitContentsToBox property on a Document ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; suppressSetHeight?: boolean; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 9f1c019fe..5f4c17ee6 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -259,7 +259,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { if (this._loadPending && this._map.getBounds()) { this._loadPending = false; - this.layoutDoc.fitToBox && this.fitBounds(this._map); + this.layoutDoc.fitContentsToBox && this.fitBounds(this._map); } this.dataDoc.mapLat = this._map.getCenter()?.lat(); this.dataDoc.mapLng = this._map.getCenter()?.lng(); @@ -284,7 +284,7 @@ export class MapBox extends ViewBoxAnnotatableComponent { if (this._loadPending && this._map.getBounds()) { this._loadPending = false; - this.layoutDoc.fitToBox && this.fitBounds(this._map); + this.layoutDoc.fitContentsToBox && this.fitBounds(this._map); } this.dataDoc.mapZoom = this._map.getZoom(); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 7d0302b26..4e431e7bd 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -495,7 +495,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp // embed document when dragg marked as embed } else if (de.embedKey) { const target = dragData.droppedDocuments[0]; - target._fitToBox = true; + target._fitContentsToBox = true; const node = schema.nodes.dashDoc.create({ width: target[WidthSym](), height: target[HeightSym](), @@ -1557,7 +1557,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } } - fitToBox = () => this.props.Document._fitToBox; + fitContentsToBox = () => this.props.Document._fitContentsToBox; sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => { if (!this.layoutDoc._showSidebar) this.toggleSidebar(); @@ -1632,7 +1632,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp ScreenToLocalTransform={this.sidebarScreenToLocal} renderDepth={this.props.renderDepth + 1} setHeight={this.setSidebarHeight} - fitContentsToDoc={this.fitToBox} + fitContentsToBox={this.fitContentsToBox} noSidebar={true} fieldKey={this.layoutDoc.sidebarViewType === "translation" ? `${this.fieldKey}-translation` : `${this.fieldKey}-annotations`} />; }; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 6de04bd31..cebf9487a 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -35,8 +35,8 @@ export interface PinProps { setPosition?: boolean; hidePresBox?: boolean; pinWithView?: PinViewProps; - pinDocView?: boolean; - panelWidth?: number; + pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document + panelWidth?: number; // panel width and height of the document (used to compute the bounds of the pinned view area) panelHeight?: number } @@ -997,7 +997,7 @@ export class PresBox extends ViewBoxBaseComponent() { /** * Method called for viewing paths which adds a single line with * points at the center of each document added. - * Design choice: When this is called it sets _fitToBox as true so the + * Design choice: When this is called it sets _fitContentsToBox as true so the * user can have an overview of all of the documents in the collection. * (Design needed for when documents in presentation trail are in another * collection) @@ -1800,16 +1800,16 @@ export class PresBox extends ViewBoxBaseComponent() { doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y }); break; case 'title': - doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; case 'header': - doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; case 'content': - doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; case 'twoColumns': - doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); + doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y }); break; default: break; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 5eff47a86..ba0193e4b 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -85,7 +85,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { isContentActive={this.props.isContentActive} addDocTab={returnFalse} pinToPres={returnFalse} - fitContentsToDoc={returnTrue} + fitContentsToBox={returnTrue} PanelWidth={this.embedWidth} PanelHeight={this.embedHeight} ScreenToLocalTransform={Transform.Identity} diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index e532becb5..be39e0709 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -36,8 +36,8 @@ export const documentSchema = createSchema({ _nativeHeight: "number", // " _width: "number", // width of document in its container's coordinate system _height: "number", // " - _xPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set - _yPadding: "number", // pixels of padding on top/bottom of collectionfreeformview contents when fitToBox is set + _xPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitContentsToBox is set + _yPadding: "number", // pixels of padding on top/bottom of collectionfreeformview contents when fitContentsToBox is set _xMargin: "number", // margin added on left/right of most documents to add separation from their container _yMargin: "number", // margin added on top/bottom of most documents to add separation from their container _overflow: "string", // sets overflow behvavior for CollectionFreeForm views @@ -59,7 +59,7 @@ export const documentSchema = createSchema({ borderRounding: "string", // border radius rounding of document boxShadow: "string", // the amount of shadow around the perimeter of a document color: "string", // foreground color of document - fitToBox: "boolean", // whether freeform view contents should be zoomed/panned to fill the area of the document view + fitContentsToBox: "boolean",// whether freeform view contents should be zoomed/panned to fill the area of the document view box fontSize: "string", hidden: "boolean", // whether a document should not be displayed isInkMask: "boolean", // is the document a mask (ie, sits on top of other documents, has an unbounded width/height that is dark, and content uses 'hard-light' mix-blend-mode to let other documents pop through) diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx index 418464f0e..64baa351c 100644 --- a/src/mobile/AudioUpload.tsx +++ b/src/mobile/AudioUpload.tsx @@ -19,7 +19,7 @@ import React = require('react'); @observer export class AudioUpload extends React.Component { - @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc; + @observable public _audioCol: Doc = FieldValue(Cast(Docs.Create.FreeformDocument([Cast(Docs.Create.AudioDocument(nullAudio, { title: "mobile audio", _width: 500, _height: 100 }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitContentsToBox: true, boxShadow: "0 0" }), Doc)) as Doc; /** * Handles the onclick functionality for the 'Restart' button @@ -36,7 +36,7 @@ export class AudioUpload extends React.Component { title: "mobile audio", _width: 500, _height: 100 - }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitToBox: true, boxShadow: "0 0" }), Doc)) as Doc; + }), Doc) as Doc], { title: "mobile audio", _width: 300, _height: 300, _fitContentsToBox: true, boxShadow: "0 0" }), Doc)) as Doc; } /** -- cgit v1.2.3-70-g09d2 From 53bc43a9817f6a80b9dc4e0adad11b555c4236b6 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 9 Jun 2022 11:20:14 -0400 Subject: pinned docs now have click func to navigate to target. restored embedded views within presBox --- src/client/views/collections/TabDocView.tsx | 2 ++ src/client/views/nodes/trails/PresElementBox.tsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 5cc92a305..5883f0496 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -36,6 +36,7 @@ import { CollectionView, CollectionViewType } from './CollectionView'; import "./TabDocView.scss"; import React = require("react"); import { listSpec } from '../../../fields/Schema'; +import { ScriptField } from '../../../fields/ScriptField'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -260,6 +261,7 @@ export class TabDocView extends React.Component { pinDoc.presPinClipWidth = width; pinDoc.presPinView = true; } + pinDoc.onClick = ScriptField.MakeFunction("DocFocusOrOpen(self.presentationTargetDoc)"); } Doc.AddDocToList(curPres, "data", pinDoc, presSelected); if (!pinProps?.audioRange && duration !== undefined) { diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index ef70f8e36..41a583580 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -582,9 +582,9 @@ export class PresElementBox extends ViewBoxBaseComponent() {
} - {/*
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> +
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> e.stopPropagation()} /> -
*/} +
{"Remove from presentation"}
}>
-- cgit v1.2.3-70-g09d2 From 012a4681c824baaef60370de5904e9cc35b03f13 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 9 Jun 2022 11:32:01 -0400 Subject: fixed pin doc navigation when not in presBox (eg. headerBar) --- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/nodes/trails/PresBox.tsx | 61 +-- src/client/views/nodes/trails/PresElementBox.tsx | 490 +++++++++-------------- 3 files changed, 219 insertions(+), 334 deletions(-) (limited to 'src/client/views/nodes/trails/PresElementBox.tsx') diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 5883f0496..142013d1a 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -261,8 +261,8 @@ export class TabDocView extends React.Component { pinDoc.presPinClipWidth = width; pinDoc.presPinView = true; } - pinDoc.onClick = ScriptField.MakeFunction("DocFocusOrOpen(self.presentationTargetDoc)"); } + pinDoc.onClick = ScriptField.MakeFunction("navigateToDoc(self.presentationTargetDoc, self)"); Doc.AddDocToList(curPres, "data", pinDoc, presSelected); if (!pinProps?.audioRange && duration !== undefined) { pinDoc.mediaStart = "manual"; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index cebf9487a..db2f58be7 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -29,6 +29,7 @@ import { CollectionFreeFormDocumentView } from "../CollectionFreeFormDocumentVie import { FieldView, FieldViewProps } from '../FieldView'; import "./PresBox.scss"; import { PresEffect, PresMovement, PresStatus } from "./PresEnums"; +import { ScriptingGlobals } from "../../../util/ScriptingGlobals"; export interface PinProps { audioRange?: boolean; @@ -332,34 +333,36 @@ export class PresBox extends ViewBoxBaseComponent() { const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document; if (bestTarget) console.log(bestTarget.title, bestTarget.type); else console.log("no best target"); - bestTarget && runInAction(() => { - console.log(bestTarget.title, bestTarget.type); - 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._scrollTop = activeItem.presPinViewScroll; - } else if (bestTarget.type === DocumentType.COMPARISON) { - bestTarget._clipWidth = activeItem.presPinClipWidth; - } else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) { - bestTarget._currentTimecode = activeItem.presStartTime; + if (bestTarget) this._navTimer = PresBox.navigateToDoc(bestTarget, activeItem); + } + + @action + static navigateToDoc(bestTarget:Doc, activeItem:Doc) { + 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._scrollTop = activeItem.presPinViewScroll; + } else if (bestTarget.type === DocumentType.COMPARISON) { + bestTarget._clipWidth = activeItem.presPinClipWidth; + } else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) { + bestTarget._currentTimecode = activeItem.presStartTime; + } else { + const contentBounds= Cast(activeItem.contentBounds, listSpec("number")); + bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; + if (contentBounds) { + bestTarget._panX = (contentBounds[0] + contentBounds[2])/2; + bestTarget._panY = (contentBounds[1] + contentBounds[3])/2; + const dv = DocumentManager.Instance.getDocumentView(bestTarget); + if (dv) { + bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]), + dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0])); + }; } else { - const contentBounds= Cast(activeItem.contentBounds, listSpec("number")); - bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s'; - if (contentBounds) { - bestTarget._panX = (contentBounds[0] + contentBounds[2])/2; - bestTarget._panY = (contentBounds[1] + contentBounds[3])/2; - const dv = DocumentManager.Instance.getDocumentView(bestTarget); - if (dv) { - bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]), - dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0])); - }; - } else { - bestTarget._panX = activeItem.presPinViewX; - bestTarget._panY = activeItem.presPinViewY; - bestTarget._viewScale = activeItem.presPinViewScale; - } + bestTarget._panX = activeItem.presPinViewX; + bestTarget._panY = activeItem.presPinViewY; + bestTarget._viewScale = activeItem.presPinViewScale; } - this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510); - }); + } + return setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510); } /** @@ -2570,4 +2573,8 @@ export class PresBox extends ViewBoxBaseComponent() {
; } -} \ No newline at end of file +} + +ScriptingGlobals.add(function navigateToDoc(bestTarget:Doc, activeItem:Doc) { + PresBox.navigateToDoc(bestTarget, activeItem); +}); \ No newline at end of file diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 41a583580..ba0193e4b 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -4,10 +4,9 @@ import { action, computed, IReactionDisposer, observable, reaction } from "mobx" import { observer } from "mobx-react"; import { Doc, DocListCast, Opt } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; -import { List } from "../../../../fields/List"; -import { Cast, NumCast, StrCast } from "../../../../fields/Types"; +import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types"; import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../../Utils"; -import { Docs, DocUtils } from "../../../documents/Documents"; +import { DocUtils } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; import { DocumentManager } from "../../../util/DocumentManager"; @@ -31,8 +30,8 @@ import React = require("react"); */ @observer export class PresElementBox extends ViewBoxBaseComponent() { - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); } - _heightDisposer: IReactionDisposer | undefined; + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); } + _heightDisposer: IReactionDisposer | undefined; @observable _dragging = false; @computed get indexInPres() { return DocListCast(this.presBox[StrCast(this.presBox.presFieldKey, "data")]).indexOf(this.rootDoc); } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements) @@ -182,11 +181,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { e.preventDefault(); } - - /** - * Function to drag and drop the pres element to a diferent location - */ - startDrag = (e: PointerEvent) => { + /** + * Function to drag and drop the pres element to a diferent location + */ + startDrag = (e: PointerEvent) => { const miniView: boolean = this.toolbarWidth <= 100; const activeItem = this.rootDoc; const dragArray = PresBox.Instance._dragArray; @@ -197,32 +195,27 @@ export class PresElementBox extends ViewBoxBaseComponent() { dragData.moveDocument = this.props.docViewPath().lastElement()?.props.moveDocument; const dragItem: HTMLElement[] = []; if (dragArray.length === 1) { - const doc = this._itemRef.current || dragArray[0]; - doc.className = miniView ? "presItem-miniSlide" : "presItem-slide"; - dragItem.push(doc); + const doc = this._itemRef.current || dragArray[0]; + doc.className = miniView ? "presItem-miniSlide" : "presItem-slide"; + dragItem.push(doc); } else if (dragArray.length >= 1) { - const doc = document.createElement('div'); - doc.className = "presItem-multiDrag"; - doc.innerText = "Move " + PresBox.Instance._selectedArray.size + " slides"; - doc.style.position = 'absolute'; - doc.style.top = (e.clientY) + 'px'; - doc.style.left = (e.clientX - 50) + 'px'; - dragItem.push(doc); + const doc = document.createElement('div'); + doc.className = "presItem-multiDrag"; + doc.innerText = "Move " + PresBox.Instance._selectedArray.size + " slides"; + doc.style.position = 'absolute'; + doc.style.top = (e.clientY) + 'px'; + doc.style.left = (e.clientX - 50) + 'px'; + dragItem.push(doc); } // const dropEvent = () => runInAction(() => this._dragging = false); if (activeItem) { - DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY, undefined); - // runInAction(() => this._dragging = true); - return true; + DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY, undefined); + // runInAction(() => this._dragging = true); + return true; } return false; - } - - /** - * Returns a local transformed coordinate array for given coordinates. - */ - ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord]; + } onPointerOver = (e: any) => { document.removeEventListener("pointermove", this.onPointerMove); @@ -321,283 +314,168 @@ export class PresElementBox extends ViewBoxBaseComponent() { return width; } - onPointerOver = (e: any) => { - document.removeEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointermove", this.onPointerMove); - } - - onPointerMove = (e: PointerEvent) => { - const slide = this._itemRef.current!; - 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; - const halfLine = height / 2; - if (y <= halfLine) { - slide.style.borderTop = `solid 2px ${Colors.MEDIUM_BLUE}`; - slide.style.borderBottom = "0px"; - } else if (y > halfLine) { - slide.style.borderTop = "0px"; - slide.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`; - } - } - document.removeEventListener("pointermove", this.onPointerMove); - } - - onPointerLeave = (e: any) => { - this._itemRef.current!.style.borderTop = "0px"; - this._itemRef.current!.style.borderBottom = "0px"; - document.removeEventListener("pointermove", this.onPointerMove); - } - - @action - toggleProperties = () => { - if (CurrentUserUtils.propertiesWidth < 5) { - action(() => (CurrentUserUtils.propertiesWidth = 250)); - } - } - - @undoBatch - removeItem = action((e: React.MouseEvent) => { - this.props.removeDocument?.(this.rootDoc); - if (PresBox.Instance._selectedArray.has(this.rootDoc)) { - PresBox.Instance._selectedArray.delete(this.rootDoc); - } - this.hideRecording(); - e.stopPropagation(); - }); - - // set the value/title of the individual pres element - @undoBatch - @action - onSetValue = (value: string) => { - this.rootDoc.title = !value.trim().length ? "-untitled-" : value; - return true; - } - - /** - * Method called for updating the view of the currently selected document - * - * @param targetDoc - * @param activeItem - */ - @undoBatch - @action - updateView = (targetDoc: Doc, activeItem: Doc) => { - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { - const scroll = targetDoc._scrollTop; - activeItem.presPinViewScroll = scroll; - } else if (targetDoc.type === DocumentType.VID) { - activeItem.presPinTimecode = targetDoc._currentTimecode; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const clipWidth = targetDoc._clipWidth; - activeItem.presPinClipWidth = clipWidth; - } else { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } - } - - @computed get recordingIsInOverlay() { - let isInOverlay = false - DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => { - if (doc.slides === this.rootDoc) { - isInOverlay = true - return - } - }) - return isInOverlay - } - - @undoBatch - @action - hideRecording = () => { - DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => { - if (doc.slides === this.rootDoc) { - Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); - } - }) - } - - @undoBatch - @action - showRecording = (activeItem: Doc) => { - // Remove every recording that already exists in overlay view - DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => { - if (doc.slides !== null) { - Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); - } - }) - if (activeItem.recording) { - // if we already have an existing recording - Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, Cast(activeItem.recording, Doc, null)); - - } - } - - @undoBatch - @action - startRecording = (activeItem: Doc) => { - // Remove every recording that already exists in overlay view - DocListCast((Doc.UserDoc().myOverlayDocs as Doc).data).forEach((doc) => { - if (doc.slides !== null) { - Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); - } - }) - - if (activeItem.recording) { - // if we already have an existing recording - Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, Cast(activeItem.recording, Doc, null)); - - } else { - // if we dont have any recording - const recording = Docs.Create.WebCamDocument("", { _width: 400, _height: 200, title: "recording", cloneFieldFilter: new List(["system"]) }); - - // attach the recording to the slide, and attach the slide to the recording - recording.slides = activeItem - activeItem.recording = recording - - // TODO: Figure out exactly where we want the video to appear - const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - recording.x = pt[0]; - recording.y = pt[1]; - Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, recording); - } - } - - @computed - get toolbarWidth(): number { - const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox); - let width: number = NumCast(this.presBox._width); - if (presBoxDocView) width = presBoxDocView.props.PanelWidth(); - if (width === 0) width = 300; - return width; - } - - @computed get mainItem() { - const isSelected: boolean = PresBox.Instance?._selectedArray.has(this.rootDoc); - const toolbarWidth: number = this.toolbarWidth; - const showMore: boolean = this.toolbarWidth >= 300; - const miniView: boolean = this.toolbarWidth <= 110; - const presBox: Doc = this.presBox; //presBox - const presBoxColor: string = StrCast(presBox._backgroundColor); - const presColorBool: boolean = presBoxColor ? (presBoxColor !== Colors.WHITE && presBoxColor !== "transparent") : false; - const targetDoc: Doc = this.targetDoc; - const activeItem: Doc = this.rootDoc; - return ( -
= 300; + const miniView: boolean = this.toolbarWidth <= 110; + const presBox: Doc = this.presBox; //presBox + const presBoxColor: string = StrCast(presBox._backgroundColor); + const presColorBool: boolean = presBoxColor ? (presBoxColor !== Colors.WHITE && presBoxColor !== "transparent") : false; + const targetDoc: Doc = this.targetDoc; + const activeItem: Doc = this.rootDoc; + const isGroup: boolean = BoolCast(targetDoc._isGroup); + return ( +
{ + e.stopPropagation(); + e.preventDefault(); + PresBox.Instance.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); + }} + onDoubleClick={action(e => { + if (isGroup) { + this.rootDoc.presExpandGroup = !this.rootDoc.presExpandGroup; + } else { + this.toggleProperties(); + PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true); + } + })} + onPointerOver={this.onPointerOver} + onPointerLeave={this.onPointerLeave} + onPointerDown={this.headerDown} + onPointerUp={this.headerUp} + > + {miniView ? + // when width is LESS than 110 px +
+ {`${this.indexInPres + 1}.`} +
+ : + // when width is MORE than 110 px +
+ {`${this.indexInPres + 1}.`} +
} + {isGroup ? +
{ - e.stopPropagation(); - e.preventDefault(); - PresBox.Instance.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); - this.showRecording(activeItem); - }} - onDoubleClick={action(e => { - this.toggleProperties(); - PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true); - })} - onPointerOver={this.onPointerOver} - onPointerLeave={this.onPointerLeave} - onPointerDown={this.headerDown} - onPointerUp={this.headerUp} - > - {miniView ? - // when width is LESS than 110 px -
- {`${this.indexInPres + 1}.`} -
- : - // when width is MORE than 110 px -
- {`${this.indexInPres + 1}.`} -
} - {miniView ? (null) :
-
- StrCast(activeItem.title)} - SetValue={this.onSetValue} - /> -
-
{"Movement speed"}
}>
{this.transition}
-
{"Duration"}
}>
{this.duration}
-
-
{"Update view"}
}> -
this.updateView(targetDoc, activeItem)} - style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
-
- - {this.recordingIsInOverlay ? -
{"Hide Recording"}
}> -
- e.stopPropagation()} /> -
-
: -
{"Start recording"}
}> -
this.startRecording(activeItem)} - style={{ fontWeight: 700 }}> - e.stopPropagation()} /> -
-
- } - - - {this.indexInPres === 0 ? (null) :
{activeItem.groupWithUp ? "Ungroup" : "Group with up"}
}> -
activeItem.groupWithUp = !activeItem.groupWithUp} - style={{ - zIndex: 1000 - this.indexInPres, - fontWeight: 700, - backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : Colors.MEDIUM_BLUE : undefined, - height: activeItem.groupWithUp ? 53 : 18, - transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined - }}> -
- e.stopPropagation()} /> -
-
-
} -
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> - e.stopPropagation()} /> -
-
{"Remove from presentation"}
}>
- e.stopPropagation()} /> -
-
-
{activeItem.presPinView ? (<>View of {targetDoc.title}) : targetDoc.title}
- {this.renderEmbeddedInline} -
} -
); - } + backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor), + boxShadow: presBoxColor && presBoxColor !== "white" && presBoxColor !== "transparent" ? isSelected ? "0 0 0px 1.5px" + presBoxColor : undefined : undefined + }}> +
+ StrCast(activeItem.title)} + SetValue={this.onSetValue} + /> +
+
+
{"Update view"}
}> +
this.updateView(targetDoc, activeItem)} + style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
+
+ {this.indexInPres === 0 ? (null) :
{activeItem.groupWithUp ? "Ungroup" : "Group with up"}
}> +
activeItem.groupWithUp = !activeItem.groupWithUp} + style={{ + zIndex: 1000 - this.indexInPres, + fontWeight: 700, + backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : Colors.MEDIUM_BLUE : undefined, + height: activeItem.groupWithUp ? 53 : 18, + transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined + }}> +
+ e.stopPropagation()} /> +
+
+
} +
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> + e.stopPropagation()} /> +
+
{"Remove from presentation"}
}>
+ e.stopPropagation()} /> +
+
+
+
+ {this.rootDoc.presExpandGroup ? this.renderGroupSlides : (null)} +
+
{activeItem.presPinView ? (<>View of {targetDoc.title}) : targetDoc.title}
+
{ + if (isGroup) { + this.rootDoc.presExpandGroup = !this.rootDoc.presExpandGroup; + } + }} + > + +
+
+ : (null)} + {miniView || isGroup ? (null) :
+
+ StrCast(activeItem.title)} + SetValue={this.onSetValue} + /> +
+
{"Movement speed"}
}>
{this.transition}
+
{"Duration"}
}>
{this.duration}
+
+
{"Update view"}
}> +
this.updateView(targetDoc, activeItem)} + style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
+
+ {this.indexInPres === 0 ? (null) :
{activeItem.groupWithUp ? "Ungroup" : "Group with up"}
}> +
activeItem.groupWithUp = !activeItem.groupWithUp} + style={{ + zIndex: 1000 - this.indexInPres, + fontWeight: 700, + backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : Colors.MEDIUM_BLUE : undefined, + height: activeItem.groupWithUp ? 53 : 18, + transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined + }}> +
+ e.stopPropagation()} /> +
+
+
} +
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> + e.stopPropagation()} /> +
+
{"Remove from presentation"}
}>
+ e.stopPropagation()} /> +
+
+
{activeItem.presPinView ? (<>View of {targetDoc.title}) : targetDoc.title}
+ {this.renderEmbeddedInline} +
} +
); + } - render() { - return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : this.mainItem; - } + render() { + return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : this.mainItem; + } } \ No newline at end of file -- cgit v1.2.3-70-g09d2