From dd5cfe5302279d708bd8fbc7b9cad7ea082758c4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 13 Oct 2022 10:39:33 -0400 Subject: some basic error checking. avoid querying background for non-toggle buttons --- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a48906372..04c7b96e3 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -222,7 +222,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.sizeProvider?.width || this.props.PanelWidth?.(); panelHeight = () => this.sizeProvider?.height || this.props.PanelHeight?.(); screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y); - focusDoc = (doc: Doc) => this.props.focus(doc); + focusDoc = (doc: Doc) => this.props.focus(doc, {}); returnThis = () => this; render() { TraceMobx(); -- cgit v1.2.3-70-g09d2 From 2fc88a931cb2fc3408297b000208990633445585 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 27 Oct 2022 15:57:09 -0400 Subject: cleaned up treeViews to work across PresBox/ppt slides/collections/ - modified DocumentView rendering to remove pres box refs. fixed mainView width. --- src/client/documents/Documents.ts | 4 +- src/client/util/CurrentUserUtils.ts | 8 +- src/client/views/DocumentDecorations.tsx | 18 +- src/client/views/LightboxView.tsx | 26 +-- src/client/views/MainView.tsx | 1 + src/client/views/StyleProvider.tsx | 5 +- .../views/collections/CollectionStackingView.tsx | 2 + .../views/collections/CollectionTreeView.scss | 2 - .../views/collections/CollectionTreeView.tsx | 62 ++++--- src/client/views/collections/CollectionView.tsx | 2 + src/client/views/collections/TabDocView.tsx | 1 - src/client/views/collections/TreeView.scss | 3 +- src/client/views/collections/TreeView.tsx | 179 +++++++++---------- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 6 +- src/client/views/nodes/DocumentView.tsx | 37 ++-- src/client/views/nodes/FieldView.tsx | 2 - src/client/views/nodes/VideoBox.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 8 +- src/client/views/nodes/trails/PresBox.tsx | 7 +- src/client/views/nodes/trails/PresElementBox.scss | 14 +- src/client/views/nodes/trails/PresElementBox.tsx | 197 ++++++++++++--------- src/fields/Doc.ts | 3 + 23 files changed, 301 insertions(+), 290 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 2d82ffdf9..bbb896d6e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -335,7 +335,6 @@ export class DocumentOptions { treeViewHideHeaderIfTemplate?: boolean; // whether to hide the header for a document in a tree view only if a childLayoutTemplate is provided (presBox) treeViewHideHeader?: boolean; // whether to hide the header for a document in a tree view treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items. - treeViewGrowsHorizontally?: boolean; // whether an embedded tree view of the document can grow horizontally without growing vertically treeViewChildDoubleClick?: ScriptField; // // Action Button buttonMenu?: boolean; // whether a action button should be displayed @@ -395,7 +394,6 @@ export namespace Docs { _xMargin: 10, _yMargin: 10, nativeDimModifiable: true, - treeViewGrowsHorizontally: true, nativeHeightUnfrozen: true, forceReflow: true, links: '@links(self)', @@ -570,7 +568,7 @@ export namespace Docs { DocumentType.SLIDER, { layout: { view: SliderBox, dataField: defaultDataKey }, - options: { links: '@links(self)', treeViewGrowsHorizontally: true }, + options: { links: '@links(self)' }, }, ], [ diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2bc464127..a2974177e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -480,7 +480,7 @@ export class CurrentUserUtils { const childContextMenuIcons = ["chalkboard", "tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { title: "My Dashboards", childHideLinkButton: true, freezeChildren: "remove|add", treeViewHideTitle: true, boxShadow: "0 0", childDontRegisterViews: true, - targetDropAction: "same", treeViewType: TreeViewType.fileSystem, isFolder: true, system: true, treeViewTruncateTitleWidth: 150, ignoreClick: true, + targetDropAction: "same", treeViewType: TreeViewType.fileSystem, isFolder: true, system: true, treeViewTruncateTitleWidth: 350, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newDashboardButton, childDropAction: "alias", _showTitle: "title", _height: 400, _gridGap: 5, _forceActive: true, _lockedPosition: true, contextMenuLabels:new List(contextMenuLabels), @@ -518,7 +518,7 @@ export class CurrentUserUtils { const reqdOpts:DocumentOptions = { _showTitle: "title", _height: 100, _gridGap: 5, _forceActive: true, _lockedPosition: true, title: "My Documents", buttonMenu: true, buttonMenuDoc: newFolderButton, treeViewHideTitle: true, targetDropAction: "proto", system: true, isFolder: true, treeViewType: TreeViewType.fileSystem, childHideLinkButton: true, boxShadow: "0 0", childDontRegisterViews: true, - treeViewTruncateTitleWidth: 150, ignoreClick: true, childDropAction: "alias", + treeViewTruncateTitleWidth: 350, ignoreClick: true, childDropAction: "alias", childContextMenuLabels: new List(["Create new folder"]), childContextMenuIcons: new List(["plus"]), explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard." @@ -535,7 +535,7 @@ export class CurrentUserUtils { static setupRecentlyClosed(doc: Doc, field:string) { const reqdOpts:DocumentOptions = { _showTitle: "title", _lockedPosition: true, _gridGap: 5, _forceActive: true, title: "My Recently Closed", buttonMenu: true, childHideLinkButton: true, treeViewHideTitle: true, childDropAction: "alias", system: true, - treeViewTruncateTitleWidth: 150, ignoreClick: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", + treeViewTruncateTitleWidth: 350, ignoreClick: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", contextMenuLabels: new List(["Empty recently closed"]), contextMenuIcons:new List(["trash"]), explainer: "Recently closed documents appear in this menu. They will only be deleted if you explicity empty this list." @@ -561,7 +561,7 @@ export class CurrentUserUtils { const reqdOpts:DocumentOptions = { _lockedPosition: true, _gridGap: 5, _forceActive: true, title: Doc.CurrentUserEmail +"-view", boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", ignoreClick: true, system: true, - treeViewHideTitle: true, treeViewTruncateTitleWidth: 150 + treeViewHideTitle: true, treeViewTruncateTitleWidth: 350 }; if (!doc[field]) DocUtils.AssignOpts(doc, {treeViewOpen: true, treeViewExpandedView: "fields" }); return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.TreeDocument(items??[], opts), reqdOpts, [doc]); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 10517d829..06eb6c6d7 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -112,7 +112,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } } //@ts-ignore - const titleField = +this._accumulatedTitle === this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle; + const titleField = +this._accumulatedTitle == this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle; Doc.SetInPlace(d.rootDoc, titleFieldKey, titleField, true); if (d.rootDoc.syncLayoutFieldWithTitle) { @@ -345,7 +345,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => { const newloccentern = seldocview.props.ScreenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]); const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2]; - const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.rootDoc._jitterRotation) / 180) * Math.PI); + const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.rootDoc._rotation) / 180) * Math.PI); seldocview.rootDoc.rotateCenterX = final.x / NumCast(seldocview.layoutDoc._width); seldocview.rootDoc.rotateCenterY = final.y / NumCast(seldocview.layoutDoc._height); }; @@ -381,7 +381,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const infos = new Map(); const seldocview = SelectionManager.Views()[0]; SelectionManager.Views().forEach(dv => { - const accumRot = (NumCast(dv.rootDoc._jitterRotation) / 180) * Math.PI; + const accumRot = (NumCast(dv.rootDoc._rotation) / 180) * Math.PI; const localRotCtr = dv.props.ScreenToLocalTransform().transformPoint(rcScreen.X, rcScreen.Y); const localRotCtrOffset = [localRotCtr[0] - NumCast(dv.rootDoc.width) / 2, localRotCtr[1] - NumCast(dv.rootDoc.height) / 2]; const startRotCtr = Utils.rotPt(localRotCtrOffset[0], localRotCtrOffset[1], -accumRot); @@ -396,7 +396,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P infos.set(dv.rootDoc, { unrotatedDocPos, startRotCtr, accumRot: isAbs ? angle : accumRot + angle }); dv.rootDoc.x = infos.get(dv.rootDoc)!.unrotatedDocPos.x - (endRotCtr.x - startRotCtr.x); dv.rootDoc.y = infos.get(dv.rootDoc)!.unrotatedDocPos.y - (endRotCtr.y - startRotCtr.y); - dv.rootDoc._jitterRotation = ((isAbs ? 0 : NumCast(dv.rootDoc._jitterRotation)) + (angle * 180) / Math.PI) % 360; // Rotation between -360 and 360 + dv.rootDoc._rotation = ((isAbs ? 0 : NumCast(dv.rootDoc._rotation)) + (angle * 180) / Math.PI) % 360; // Rotation between -360 and 360 }) ); }; @@ -416,7 +416,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P return false; }, // moveEvent action(() => { - const oldRotation = NumCast(seldocview.rootDoc._jitterRotation); + const oldRotation = NumCast(seldocview.rootDoc._rotation); const diff = oldRotation - Math.round(oldRotation / 45) * 45; if (Math.abs(diff) < 5) { if (selectedInk.length) { @@ -611,7 +611,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } } else { const rotCtr = [NumCast(doc._width) / 2, NumCast(doc._height) / 2]; - const tlRotated = Utils.rotPt(-rotCtr[0], -rotCtr[1], (NumCast(doc._jitterRotation) / 180) * Math.PI); + const tlRotated = Utils.rotPt(-rotCtr[0], -rotCtr[1], (NumCast(doc._rotation) / 180) * Math.PI); const maxHeight = doc.nativHeightUnfrozen || !nheight ? 0 : Math.max(nheight, NumCast(doc.scrollHeight, NumCast(doc[docView.LayoutFieldKey + '-scrollHeight']))) * docView.NativeDimScaling(); dH && (doc._height = actualdH > maxHeight && maxHeight ? maxHeight : actualdH); @@ -619,7 +619,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P dH && (doc._autoHeight = false); const rotCtr2 = [NumCast(doc._width) / 2, NumCast(doc._height) / 2]; - const tlRotated2 = Utils.rotPt(-rotCtr2[0], -rotCtr2[1], (NumCast(doc._jitterRotation) / 180) * Math.PI); + const tlRotated2 = Utils.rotPt(-rotCtr2[0], -rotCtr2[1], (NumCast(doc._rotation) / 180) * Math.PI); doc.x = NumCast(doc.x) + tlRotated.x + rotCtr[0] - (tlRotated2.x + rotCtr2[0]); // doc shifts by amount topleft moves because rotation is about center of doc doc.y = NumCast(doc.y) + tlRotated.y + rotCtr[1] - (tlRotated2.y + rotCtr2[1]); } @@ -695,7 +695,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const loccenter = Utils.rotPt( NumCast(seldocview.rootDoc.rotateCenterX) * NumCast(seldocview.layoutDoc._width), NumCast(seldocview.rootDoc.rotateCenterY) * NumCast(seldocview.layoutDoc._height), - (NumCast(seldocview.rootDoc._jitterRotation) / 180) * Math.PI + (NumCast(seldocview.rootDoc._rotation) / 180) * Math.PI ); return seldocview.props .ScreenToLocalTransform() @@ -783,7 +783,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight)); const useRotation = seldocview.rootDoc.type !== DocumentType.EQUATION; // when do we want an object to not rotate? - const rotation = NumCast(seldocview.rootDoc._jitterRotation); + const rotation = NumCast(seldocview.rootDoc._rotation); const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : ''; diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index bd6cea28a..22b0380a2 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -289,29 +289,29 @@ export class LightboxView extends React.Component { })} Document={LightboxView.LightboxDoc} DataDoc={undefined} + PanelWidth={this.lightboxWidth} + PanelHeight={this.lightboxHeight} LayoutTemplate={LightboxView.LightboxDocTemplate} - addDocument={undefined} isDocumentActive={returnFalse} isContentActive={returnTrue} - addDocTab={this.addDocTab} - pinToPres={TabDocView.PinDoc} - onBrowseClick={MainView.Instance.exploreMode} + styleProvider={DefaultStyleProvider} + ScreenToLocalTransform={this.lightboxScreenToLocal} + renderDepth={0} rootSelected={returnTrue} docViewPath={returnEmptyDoclist} docFilters={this.docFilters} - removeDocument={undefined} - styleProvider={DefaultStyleProvider} - ScreenToLocalTransform={this.lightboxScreenToLocal} - PanelWidth={this.lightboxWidth} - PanelHeight={this.lightboxHeight} - focus={DocUtils.DefaultFocus} - whenChildContentsActiveChanged={emptyFunction} - bringToFront={emptyFunction} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} - renderDepth={0} + addDocument={undefined} + removeDocument={undefined} + whenChildContentsActiveChanged={emptyFunction} + addDocTab={this.addDocTab} + pinToPres={TabDocView.PinDoc} + bringToFront={emptyFunction} + onBrowseClick={MainView.Instance.exploreMode} + focus={DocUtils.DefaultFocus} /> diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 03c0642ed..4dc1ebd99 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -647,6 +647,7 @@ export class MainView extends React.Component { e.preventDefault(); }} style={{ + width: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`, minWidth: `calc(100% - ${this._leftMenuFlyoutWidth + this.leftMenuWidth() + this.propertiesWidth()}px)`, transform: LightboxView.LightboxDoc ? 'scale(0.0001)' : undefined, }}> diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 2eb3dd532..bc8bd7b7f 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -85,7 +85,6 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic'; const isBackground = () => doc && BoolCast(doc._lockedPosition); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); @@ -167,11 +166,11 @@ export function DefaultStyleProvider(doc: Opt, props: Opt (props?.PanelHeight() || 0) ? 5 : 10) : 0; + return Doc.IsComicStyle(doc) ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) || (doc?.type === DocumentType.RTF && !showTitle()?.includes('noMargin')) || diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index ba29b1d6f..77b47ed82 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -350,6 +350,8 @@ export class CollectionStackingView extends CollectionSubView = new Set(); // list of tree view items to monitor for height changes private observer: any; // observer for monitoring tree view items. - private static expandViewLabelSize = 20; @computed get doc() { return this.props.Document; @@ -100,7 +99,10 @@ export class CollectionTreeView extends CollectionSubView disposer?.()); } + shrinkWrap = () => {}; // placeholder to allow setContentView to work + componentDidMount() { + //this.props.setContentView?.(this); this._disposers.autoheight = reaction( () => this.rootDoc.autoHeight, auto => auto && this.computeHeight(), @@ -197,9 +199,7 @@ export class CollectionTreeView extends CollectionSubView void) => this.onExternalDrop(e, {}, addDocs); @undoBatch - makeTextCollection = (childDocs: Doc[]) => { - this.addDoc(TreeView.makeTextBullet(), childDocs.length ? childDocs[0] : undefined, true); - }; + makeTextCollection = (childDocs: Doc[]) => this.addDoc(TreeView.makeTextBullet(), childDocs.length ? childDocs[0] : undefined, true); get editableTitle() { return ( @@ -258,6 +258,7 @@ export class CollectionTreeView extends CollectionSubView ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label })); }; + headerFields = () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields); @computed get treeViewElements() { TraceMobx(); const dropAction = StrCast(this.doc.childDropAction) as dropActionType; @@ -281,7 +282,7 @@ export class CollectionTreeView extends CollectionSubView this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), + this.headerFields, [], this.props.onCheckedClick, this.onChildClick, @@ -304,7 +305,7 @@ export class CollectionTreeView extends CollectionSubView (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.props.ScreenToLocalTransform().Scale))} key={this.doc[Id]} - style={!this.outlineMode ? { paddingLeft: this.marginX(), paddingTop: this.marginTop() } : {}}> + style={!this.outlineMode ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}}> {this.outlineMode ? this.documentTitle : this.editableTitle} ); @@ -372,7 +373,7 @@ export class CollectionTreeView extends CollectionSubView (this.layoutDoc?.[HeightSym]() || 0) - NumCast(this.layoutDoc.autoHeightMargins); truncateTitleWidth = () => this.treeViewtruncateTitleWidth; onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); - panelWidth = () => Math.max(0, this.props.PanelWidth() - this.marginX() - CollectionTreeView.expandViewLabelSize) * (this.props.NativeDimScaling?.() || 1); + panelWidth = () => Math.max(0, this.props.PanelWidth() - 2 * this.marginX() * (this.props.NativeDimScaling?.() || 1)); addAnnotationDocument = (doc: Doc | Doc[]) => this.props.CollectionView?.addDocument(doc, `${this.props.fieldKey}-annotations`) || false; remAnnotationDocument = (doc: Doc | Doc[]) => this.props.CollectionView?.removeDocument(doc, `${this.props.fieldKey}-annotations`) || false; @@ -396,7 +397,7 @@ export class CollectionTreeView extends CollectionSubView @@ -432,24 +431,29 @@ export class CollectionTreeView extends CollectionSubView - {this.contentFunc} - - ) : ( - this.contentFunc() + const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1) || 1; + return ( +
+ {!(this.doc instanceof Doc) || !this.treeChildren ? null : this.doc.treeViewHasOverlay ? ( + + {this.contentFunc} + + ) : ( + this.contentFunc() + )} +
); } } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index dcaad5632..9f63a11aa 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -54,6 +54,8 @@ interface CollectionViewProps_ extends FieldViewProps { childHideDecorationTitle?: () => boolean; childHideResizeHandles?: () => boolean; childLayoutTemplate?: () => Doc | undefined; // specify a layout Doc template to use for children of the collection + childXPadding?: number; + childYPadding?: number; childLayoutString?: string; childIgnoreNativeSize?: boolean; childClickScript?: ScriptField; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index a6cfbd6b2..cde5132a3 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -256,7 +256,6 @@ export class TabDocView extends React.Component { pinDoc.treeViewChildrenOnRoot = true; // tree view will look for hierarchical children on the root doc, not the data doc. pinDoc.treeViewFieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field pinDoc.treeViewExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view - pinDoc.treeViewGrowsHorizontally = true; // the document expands horizontally when displayed as a tree view header pinDoc.treeViewHideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header const presArray: Doc[] = PresBox.Instance?.sortArray(); const size: number = PresBox.Instance?.selectedArray.size; diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 57bb5274d..83fee013a 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -24,6 +24,7 @@ // width: $TREE_BULLET_WIDTH; width: 100%; height: 100%; + position: absolute; .treeView-expandIcon { display: none; @@ -118,7 +119,7 @@ display: flex; // needed for PresBox's treeView border: transparent 1px solid; align-items: center; - width: 100%; + width: max-content; border-radius: 5px; &:hover { diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index b9f86fa6b..1e97eee37 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -10,7 +10,7 @@ import { listSpec } from '../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, simulateMouseClick, Utils } from '../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; @@ -321,6 +321,7 @@ export class TreeView extends React.Component { _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, + _fitWidth: true, treeViewType: TreeViewType.outline, x: 0, y: 0, @@ -398,29 +399,22 @@ export class TreeView extends React.Component { }; docTransform = () => this.refTransform(this._dref?.ContentRef?.current); getTransform = () => this.refTransform(this._tref.current); - docWidth = () => { - const layoutDoc = this.layoutDoc; - const aspect = Doc.NativeAspect(layoutDoc); - if (layoutDoc._fitWidth) return Math.min(this.props.panelWidth() - treeBulletWidth(), layoutDoc[WidthSym]()); - if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.panelWidth() - treeBulletWidth())); - return Math.min((this.props.panelWidth() - treeBulletWidth()) / (this.props.treeView.props.NativeDimScaling?.() || 1), Doc.NativeWidth(layoutDoc) ? layoutDoc[WidthSym]() : this.layoutDoc[WidthSym]()); - }; - docHeight = () => { - const layoutDoc = this.layoutDoc; - return Math.max( - 70, - Math.min( - this.MAX_EMBED_HEIGHT, - (() => { - const aspect = Doc.NativeAspect(layoutDoc); - if (aspect) return this.docWidth() / (aspect || 1); - return layoutDoc._fitWidth - ? !Doc.NativeHeight(this.doc) - ? NumCast(this.props.containerCollection._height) - : Math.min((this.docWidth() * NumCast(layoutDoc.scrollHeight, Doc.NativeHeight(layoutDoc))) / (Doc.NativeWidth(layoutDoc) || NumCast(this.props.containerCollection._height))) - : layoutDoc[HeightSym]() || 50; - })() - ) + embeddedPanelWidth = () => this.props.panelWidth() / (this.props.treeView.props.NativeDimScaling?.() || 1); + embeddedPanelHeight = () => { + console.log(this.props.treeView.rootDoc.title); + const layoutDoc = (temp => temp && Doc.expandTemplateLayout(temp, this.props.document, ''))(this.props.treeView.props.childLayoutTemplate?.()) || this.layoutDoc; + return Math.min( + layoutDoc[HeightSym](), + this.MAX_EMBED_HEIGHT, + (() => { + const aspect = Doc.NativeAspect(layoutDoc); + if (aspect) return this.embeddedPanelWidth() / (aspect || 1); + return layoutDoc._fitWidth + ? !Doc.NativeHeight(layoutDoc) + ? NumCast(layoutDoc._height) //this.props.containerCollection._height) + : Math.min((this.embeddedPanelWidth() * NumCast(layoutDoc.scrollHeight, Doc.NativeHeight(layoutDoc))) / (Doc.NativeWidth(layoutDoc) || NumCast(this.props.containerCollection._height))) + : (this.embeddedPanelWidth() * layoutDoc[HeightSym]()) / layoutDoc[WidthSym](); + })() ); }; @@ -512,28 +506,6 @@ export class TreeView extends React.Component { return rows; } - rtfWidth = () => { - const layout = (temp => temp && Doc.expandTemplateLayout(temp, this.props.document, ''))(this.props.treeView.props.childLayoutTemplate?.()) || this.layoutDoc; - return Math.min(layout[WidthSym](), this.props.panelWidth() - treeBulletWidth()) / (this.props.treeView.props.NativeDimScaling?.() || 1); - }; - rtfHeight = () => { - const layout = (temp => temp && Doc.expandTemplateLayout(temp, this.props.document, ''))(this.props.treeView.props.childLayoutTemplate?.()) || this.layoutDoc; - return this.rtfWidth() <= layout[WidthSym]() ? Math.min(layout[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT; - }; - rtfOutlineHeight = () => Math.max(this.layoutDoc?.[HeightSym](), treeBulletWidth()); - expandPanelHeight = () => { - if (this.layoutDoc._fitWidth) return this.docHeight(); - const aspect = this.layoutDoc[WidthSym]() / this.layoutDoc[HeightSym](); - const docAspect = this.docWidth() / this.docHeight(); - return docAspect < aspect ? this.docWidth() / aspect : this.docHeight(); - }; - expandPanelWidth = () => { - if (this.layoutDoc._fitWidth) return this.docWidth(); - const aspect = this.layoutDoc[WidthSym]() / this.layoutDoc[HeightSym](); - const docAspect = this.docWidth() / this.docHeight(); - return docAspect > aspect ? this.docHeight() * aspect : this.docWidth(); - }; - @computed get renderContent() { TraceMobx(); const expandKey = this.treeViewExpandedView; @@ -792,15 +764,18 @@ export class TreeView extends React.Component { titleStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (!doc || doc !== this.doc) return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView + const treeView = this.props.treeView; // prettier-ignore switch (property.split(':')[0]) { case StyleProp.Opacity: return this.props.treeView.outlineMode ? undefined : 1; case StyleProp.BackgroundColor: return this.selected ? '#7089bb' : StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); case StyleProp.Highlighting: if (this.props.treeView.outlineMode) return undefined; + case StyleProp.Hidden: return false; + case StyleProp.BoxShadow: return undefined; case StyleProp.DocContents: const highlightIndex = this.props.treeView.outlineMode ? Doc.DocBrushStatus.unbrushed : Doc.isBrushedHighlightedDegree(doc); const highlightColor = ['transparent', 'rgb(68, 118, 247)', 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex]; - return this.props.treeView.outlineMode ? null : ( + return treeView.outlineMode ? null : (
{ maxWidth: props?.PanelWidth() || undefined, background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor), outline: `solid ${highlightColor} ${highlightIndex}px`, + paddingLeft: NumCast(treeView.rootDoc.childXPadding, NumCast(treeView.props.childXPadding, Doc.IsComicStyle(doc)?20:0)), + paddingRight: NumCast(treeView.rootDoc.childXPadding, NumCast(treeView.props.childXPadding, Doc.IsComicStyle(doc)?20:0)), + paddingTop: treeView.props.childYPadding, + paddingBottom: treeView.props.childYPadding, }}> {StrCast(doc?.title)}
); } - return this.props?.treeView?.props.styleProvider?.(doc, props, property); + return treeView.props.styleProvider?.(doc, props, property); }; embeddedStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (property.startsWith(StyleProp.Decorations)) return null; + if (property.startsWith(StyleProp.Hidden)) return false; return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView }; onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => { @@ -843,7 +823,7 @@ export class TreeView extends React.Component { } return false; }; - titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - 2 * treeBulletWidth())); + titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth())) / (this.props.treeView.props.NativeDimScaling?.() || 1) - 3 * treeBulletWidth(); return18 = () => 18; /** @@ -851,6 +831,7 @@ export class TreeView extends React.Component { */ @computed get renderTitle() { + // TraceMobx(); const view = this._editTitle ? ( { } })} Document={this.doc} + fitWidth={(doc: Doc) => true} DataDoc={undefined} scriptContext={this} hideDecorationTitle={this.props.treeView.outlineMode} @@ -905,7 +887,7 @@ export class TreeView extends React.Component { removeDocument={this.props.removeDoc} ScreenToLocalTransform={this.getTransform} NativeHeight={this.return18} - NativeWidth={this.titleWidth} + NativeWidth={returnZero} PanelWidth={this.titleWidth} PanelHeight={this.return18} contextMenuItems={this.contextMenuItems} @@ -918,10 +900,12 @@ export class TreeView extends React.Component { disableDocBrushing={this.props.treeView.props.disableDocBrushing} hideLinkButton={BoolCast(this.props.treeView.props.Document.childHideLinkButton)} dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews, this.props.dontRegisterView)} + xPadding={NumCast(this.props.treeView.props.Document.childXPadding, this.props.treeView.props.childXPadding)} + yPadding={NumCast(this.props.treeView.props.Document.childYPadding, this.props.treeView.props.childYPadding)} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} - ContainingCollectionView={undefined} + ContainingCollectionView={this.props.treeView.props.CollectionView} ContainingCollectionDoc={this.props.treeView.props.Document} /> ); @@ -968,53 +952,52 @@ export class TreeView extends React.Component { }; renderEmbeddedDocument = (asText: boolean, isActive: () => boolean | undefined) => { - const isExpandable = this.doc._treeViewGrowsHorizontally; - const panelWidth = asText || isExpandable ? this.rtfWidth : this.expandPanelWidth; - const panelHeight = asText ? this.rtfOutlineHeight : isExpandable ? this.rtfHeight : this.expandPanelHeight; return ( - (this._dref = r))} - Document={this.doc} - DataDoc={undefined} - PanelWidth={panelWidth} - PanelHeight={panelHeight} - NativeWidth={!asText && (this.layoutDoc.type === DocumentType.RTF || this.layoutDoc.type === DocumentType.SLIDER) ? this.rtfWidth : undefined} - NativeHeight={!asText && (this.layoutDoc.type === DocumentType.RTF || this.layoutDoc.type === DocumentType.SLIDER) ? this.rtfHeight : undefined} - LayoutTemplateString={asText ? FormattedTextBox.LayoutString('text') : undefined} - LayoutTemplate={this.props.treeView.props.childLayoutTemplate} - isContentActive={isActive} - isDocumentActive={isActive} - styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} - hideTitle={asText} - fitContentsToBox={returnTrue} - hideDecorationTitle={this.props.treeView.outlineMode} - hideResizeHandles={this.props.treeView.outlineMode} - onClick={this.onChildClick} - focus={this.refocus} - onKey={this.onKeyDown} - hideLinkButton={BoolCast(this.props.treeView.props.Document.childHideLinkButton)} - dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews, this.props.dontRegisterView)} - ScreenToLocalTransform={this.docTransform} - renderDepth={this.props.renderDepth + 1} - treeViewDoc={this.props.treeView?.props.Document} - rootSelected={returnTrue} - docViewPath={this.props.treeView.props.docViewPath} - docFilters={returnEmptyFilter} - docRangeFilters={returnEmptyFilter} - searchFilterDocs={returnEmptyDoclist} - ContainingCollectionDoc={this.props.containerCollection} - ContainingCollectionView={undefined} - addDocument={this.props.addDocument} - moveDocument={this.move} - removeDocument={this.props.removeDoc} - whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} - addDocTab={this.props.addDocTab} - pinToPres={this.props.treeView.props.pinToPres} - disableDocBrushing={this.props.treeView.props.disableDocBrushing} - bringToFront={returnFalse} - scriptContext={this} - /> +
+ (this._dref = r))} + Document={this.doc} + DataDoc={undefined} + PanelWidth={this.embeddedPanelWidth} + PanelHeight={this.embeddedPanelHeight} + LayoutTemplateString={asText ? FormattedTextBox.LayoutString('text') : undefined} + LayoutTemplate={this.props.treeView.props.childLayoutTemplate} + isContentActive={isActive} + isDocumentActive={isActive} + styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} + hideTitle={asText} + //fitContentsToBox={returnTrue} + hideDecorationTitle={this.props.treeView.outlineMode} + hideResizeHandles={this.props.treeView.outlineMode} + onClick={this.onChildClick} + focus={this.refocus} + onKey={this.onKeyDown} + hideLinkButton={BoolCast(this.props.treeView.props.Document.childHideLinkButton)} + dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews, this.props.dontRegisterView)} + ScreenToLocalTransform={this.docTransform} + renderDepth={this.props.renderDepth + 1} + treeViewDoc={this.props.treeView?.props.Document} + rootSelected={returnTrue} + docViewPath={this.props.treeView.props.docViewPath} + docFilters={returnEmptyFilter} + docRangeFilters={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} + ContainingCollectionDoc={this.props.containerCollection} + ContainingCollectionView={undefined} + addDocument={this.props.addDocument} + moveDocument={this.move} + removeDocument={this.props.removeDoc} + whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged} + xPadding={NumCast(this.props.treeView.props.Document.childXPadding, this.props.treeView.props.childXPadding)} + yPadding={NumCast(this.props.treeView.props.Document.childYPadding, this.props.treeView.props.childYPadding)} + addDocTab={this.props.addDocTab} + pinToPres={this.props.treeView.props.pinToPres} + disableDocBrushing={this.props.treeView.props.disableDocBrushing} + bringToFront={returnFalse} + scriptContext={this} + /> +
); }; @@ -1148,7 +1131,7 @@ export class TreeView extends React.Component { } const docs = TreeView.sortDocs(childDocs, StrCast(containerCollection.treeViewSortCriterion, TreeSort.None)); - const rowWidth = () => panelWidth() - treeBulletWidth(); + const rowWidth = () => panelWidth() - treeBulletWidth() * (treeView.props.NativeDimScaling?.() || 1); const treeViewRefs = new Map(); return docs .filter(child => child instanceof Doc) diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 559951efc..2f246e74f 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1317,7 +1317,7 @@ export class CollectionFreeFormView extends CollectionSubView ); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 04c7b96e3..260c98816 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -25,7 +25,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { renderCutoffProvider: (doc: Doc) => boolean; zIndex?: number; highlight?: boolean; - jitterRotation: number; + rotation: number; dataTransition?: string; replica: string; CollectionFreeFormView: CollectionFreeFormView; @@ -38,7 +38,7 @@ export class CollectionFreeFormDocumentView extends DocComponent void; ScreenToLocalTransform: () => Transform; bringToFront: (doc: Doc, sendToBack?: boolean) => void; + xPadding?: number; + yPadding?: number; dropAction?: dropActionType; dontRegisterView?: boolean; hideLinkButton?: boolean; @@ -1349,17 +1352,10 @@ export class DocumentViewInternal extends DocComponent - {!this.headerMargin ? ( - <> - {' '} - {this.contents} {titleView}{' '} - - ) : ( - <> - {' '} - {titleView} {this.contents}{' '} - - )} + {' '} + {!this.headerMargin ? this.contents : titleView} + {!this.headerMargin ? titleView : this.contents} + {' ' /* */} {captionView} ); @@ -1372,7 +1368,7 @@ export class DocumentViewInternal extends DocComponent {animRenderDoc}
- +
@@ -1552,7 +1548,7 @@ export class DocumentView extends React.Component { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, !this.fitWidth)); } @computed get shouldNotScale() { - return (this.fitWidth && !this.nativeWidth) || this.props.dontScaleFilter?.(this.Document) || this.props.treeViewDoc || [CollectionViewType.Docking].includes(this.Document._viewType as any); + return (this.fitWidth && !this.nativeWidth) || this.props.dontScaleFilter?.(this.Document) || [CollectionViewType.Docking].includes(this.Document._viewType as any); } @computed get effectiveNativeWidth() { return this.shouldNotScale ? 0 : this.nativeWidth || NumCast(this.layoutDoc.width); @@ -1597,7 +1593,7 @@ export class DocumentView extends React.Component { toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.NativeDimScaling, this.props.PanelWidth(), this.props.PanelHeight()); focus = (doc: Doc, options: DocFocusOptions) => this.docView?.focus(doc, options); getBounds = () => { - if (!this.docView || !this.docView.ContentDiv || this.props.Document.presBox || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { + if (!this.docView || !this.docView.ContentDiv || this.props.Document.presBox || this.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { return undefined; } const xf = this.docView?.props.ScreenToLocalTransform().scale(this.nativeScaling).inverse(); @@ -1687,10 +1683,9 @@ export class DocumentView extends React.Component { render() { TraceMobx(); - const xshift = () => (Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined); - const yshift = () => (Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined); - const isPresTreeElement: boolean = this.props.treeViewDoc?.type === DocumentType.PRES; - const isButton: boolean = this.props.Document.type === DocumentType.FONTICON || this.props.Document._viewType === CollectionViewType.Linear; + const xshift = Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined; + const yshift = Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined; + const isButton = this.props.Document.type === DocumentType.FONTICON || this.props.Document._viewType === CollectionViewType.Linear; return (
{!this.props.Document || !this.props.PanelWidth() ? null : ( @@ -1700,11 +1695,11 @@ export class DocumentView extends React.Component { style={{ transition: this.props.dataTransition, transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`, - width: isButton || isPresTreeElement ? '100%' : xshift() ?? `${(100 * (this.props.PanelWidth() - this.Xshift * 2)) / this.props.PanelWidth()}%`, + width: isButton ? '100%' : xshift ?? `${(100 * (this.props.PanelWidth() - this.Xshift * 2)) / this.props.PanelWidth()}%`, height: isButton || this.props.forceAutoHeight ? undefined - : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : `${(((100 * this.effectiveNativeHeight) / this.effectiveNativeWidth) * this.props.PanelWidth()) / this.props.PanelHeight()}%`), + : yshift ?? (this.fitWidth ? `${this.panelHeight}px` : `${(((100 * this.effectiveNativeHeight) / this.effectiveNativeWidth) * this.props.PanelWidth()) / this.props.PanelHeight()}%`), }}> this.autoHeight, autoHeight => autoHeight && this.tryUpdateScrollHeight() ); + this._disposers.width = reaction( + () => this.props.PanelWidth(), + width => this.tryUpdateScrollHeight() + ); this._disposers.scrollHeight = reaction( () => ({ scrollHeight: this.scrollHeight, autoHeight: this.autoHeight, width: NumCast(this.layoutDoc._width) }), - ({ width, scrollHeight, autoHeight }) => { - width && autoHeight && this.resetNativeHeight(scrollHeight); - }, + ({ width, scrollHeight, autoHeight }) => width && autoHeight && this.resetNativeHeight(scrollHeight), { fireImmediately: true } ); this._disposers.componentHeights = reaction( diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 258dad39c..4e8aed8a6 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -429,7 +429,7 @@ export class PresBox extends ViewBoxBaseComponent() { pinDoc.presPinLayout = true; pinDoc.presX = NumCast(targetDoc.x); pinDoc.presY = NumCast(targetDoc.y); - pinDoc.presRot = NumCast(targetDoc.jitterRotation); + pinDoc.presRot = NumCast(targetDoc.rotation); pinDoc.presWidth = NumCast(targetDoc.width); pinDoc.presHeight = NumCast(targetDoc.height); } @@ -521,7 +521,7 @@ export class PresBox extends ViewBoxBaseComponent() { targetDoc._dataTransition = presTransitionTime; targetDoc.x = NumCast(activeItem.presX, NumCast(targetDoc.x)); targetDoc.y = NumCast(activeItem.presY, NumCast(targetDoc.y)); - targetDoc.jitterRotation = NumCast(activeItem.presRot, NumCast(targetDoc.jitterRotation)); + targetDoc.rotation = NumCast(activeItem.presRot, NumCast(targetDoc.rotation)); targetDoc.width = NumCast(activeItem.presWidth, NumCast(targetDoc.width)); targetDoc.height = NumCast(activeItem.presHeight, NumCast(targetDoc.height)); setTimeout(() => (targetDoc._dataTransition = undefined), transTime + 10); @@ -2652,9 +2652,10 @@ export class PresBox extends ViewBoxBaseComponent() { PanelHeight={this.panelHeight} childIgnoreNativeSize={true} moveDocument={returnFalse} - childFitWidth={returnTrue} + //childFitWidth={returnTrue} childOpacity={returnOne} childLayoutTemplate={this.childLayoutTemplate} + childXPadding={Doc.IsComicStyle(this.rootDoc) ? 20 : undefined} filterAddDocument={this.addDocumentFilter} removeDocument={returnFalse} dontRegisterView={true} diff --git a/src/client/views/nodes/trails/PresElementBox.scss b/src/client/views/nodes/trails/PresElementBox.scss index 8a6c2a6dc..415253af1 100644 --- a/src/client/views/nodes/trails/PresElementBox.scss +++ b/src/client/views/nodes/trails/PresElementBox.scss @@ -42,10 +42,7 @@ $slide-active: #5b9fdd; width: 100%; border-bottom: 0.5px solid grey; display: flex; - justify-content: space-between; align-items: center; - grid-template-rows: 16px 10px auto; - grid-template-columns: max-content max-content max-content max-content auto; .presItem-name { display: flex; @@ -102,13 +99,7 @@ $slide-active: #5b9fdd; grid-row: 3; grid-column: 1/8; position: relative; - display: flex; - width: auto; - justify-content: center; - margin: auto; - margin-bottom: 2px; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; + display: inline-block; } .presItem-embeddedMask { @@ -124,8 +115,7 @@ $slide-active: #5b9fdd; .presItem-slideButtons { display: flex; - grid-column: 7; - grid-row: 1/3; + position: absolute; width: max-content; justify-self: right; justify-content: flex-end; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index f4ab845f3..5d14a0e9a 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -4,7 +4,9 @@ import { action, computed, IReactionDisposer, observable, reaction } from 'mobx' import { observer } from 'mobx-react'; import { Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../../fields/Doc'; import { Copy, Id } from '../../../../fields/FieldSymbols'; +import { InkField } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; +import { RichTextField } from '../../../../fields/RichTextField'; import { Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils'; import { Docs, DocUtils } from '../../../documents/Documents'; @@ -14,6 +16,7 @@ import { DragManager } from '../../../util/DragManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; +import { MarqueeView } from '../../collections/collectionFreeForm'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; @@ -24,9 +27,6 @@ import { PresBox } from './PresBox'; import './PresElementBox.scss'; import { PresMovement } from './PresEnums'; import React = require('react'); -import { InkField } from '../../../../fields/InkField'; -import { RichTextField } from '../../../../fields/RichTextField'; -import { MarqueeView } from '../../collections/collectionFreeForm'; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. @@ -44,8 +44,11 @@ export class PresElementBox extends ViewBoxBaseComponent() { @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 expandViewHeight() { + return 100; + } @computed get collapsedHeight() { - return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(this.presBox._viewType as any) ? 35 : 31; + return 35; } // 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; @@ -58,7 +61,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { return vpath.length > 1 ? (vpath[vpath.length - 2].ComponentView as PresBox) : undefined; } @computed get presBox() { - return (this.props.DocumentView?.().props.treeViewDoc ?? this.props.ContainingCollectionDoc)!; + return this.props.ContainingCollectionDoc!; } @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; @@ -67,8 +70,8 @@ export class PresElementBox extends ViewBoxBaseComponent() { componentDidMount() { this.layoutDoc.hideLinkButton = true; this._heightDisposer = reaction( - () => [this.rootDoc.presExpandInlineButton, this.collapsedHeight], - params => (this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0)), + () => ({ expand: this.rootDoc.presExpandInlineButton, height: this.collapsedHeight }), + ({ expand, height }) => (this.layoutDoc._height = height + (expand ? this.expandViewHeight : 0)), { fireImmediately: true } ); } @@ -84,10 +87,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { @action presExpandDocumentClick = () => (this.rootDoc.presExpandInlineButton = !this.rootDoc.presExpandInlineButton); - embedHeight = (): number => 97; + embedHeight = (): number => this.collapsedHeight + this.expandViewHeight; // embedWidth = () => this.props.PanelWidth(); // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); - embedWidth = (): number => this.props.PanelWidth() - 35; + embedWidth = (): number => this.props.PanelWidth() / 2; styleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { if (property === StyleProp.Opacity) return 1; return this.props.styleProvider?.(doc, props, property); @@ -98,35 +101,35 @@ export class PresElementBox extends ViewBoxBaseComponent() { */ @computed get renderEmbeddedInline() { return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? null : ( -
+
-
+ {/*
*/}
); } @@ -206,8 +209,8 @@ export class PresElementBox extends ViewBoxBaseComponent() { const dragData = new DragManager.DocumentDragData(this.presBoxView?.sortArray() ?? []); if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.rootDoc); dragData.dropAction = 'move'; - dragData.treeViewDoc = this.props.docViewPath().lastElement()?.props.treeViewDoc; - dragData.moveDocument = this.props.docViewPath().lastElement()?.props.moveDocument; + dragData.treeViewDoc = this.presBox._viewType === CollectionViewType.Tree ? this.props.ContainingCollectionDoc : undefined; // this.props.DocumentView?.()?.props.treeViewDoc; + dragData.moveDocument = this.props.moveDocument; const dragItem: HTMLElement[] = []; if (dragArray.length === 1) { const doc = this._itemRef.current || dragArray[0]; @@ -307,7 +310,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { updateCapturedContainerLayout = (targetDoc: Doc, activeItem: Doc) => { activeItem.presX = NumCast(targetDoc.x); activeItem.presY = NumCast(targetDoc.y); - activeItem.presRot = NumCast(targetDoc.jitterRotation); + activeItem.presRot = NumCast(targetDoc.rotation); activeItem.presWidth = NumCast(targetDoc.width); activeItem.presHeight = NumCast(targetDoc.height); }; @@ -464,16 +467,90 @@ export class PresElementBox extends ViewBoxBaseComponent() { return width; } + @computed get presButtons() { + 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 items: JSX.Element[] = []; + if (activeItem.presPinLayout) { + items.push( + Update captured doc layout
}> +
this.updateCapturedContainerLayout(targetDoc, activeItem)} style={{ fontWeight: 700, display: 'flex' }}> + L +
+ + ); + } + if (activeItem.presPinData || activeItem.presPinView) { + items.push( + Update captured doc content
}> +
this.updateCapturedViewContents(targetDoc, activeItem)} style={{ fontWeight: 700, display: 'flex' }}> + C +
+ + ); + } + if (!Doc.noviceMode) { + items.push( + {this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}
}> +
(this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> + e.stopPropagation()} /> +
+ + ); + } + if (this.indexInPres === 0) { + items.push( + {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()} /> +
+
+ + ); + } + items.push( + {this.rootDoc.presExpandInlineButton ? 'Minimize' : 'Expand'}}> +
{ + e.stopPropagation(); + this.presExpandDocumentClick(); + }}> + e.stopPropagation()} /> +
+
+ ); + items.push( + Remove from presentation}> +
+ e.stopPropagation()} /> +
+
+ ); + return items; + } + @computed get mainItem() { const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false; const isCurrent: boolean = this.presBox._itemIndex === this.indexInPres; - 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 ( @@ -484,6 +561,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { style={{ backgroundColor: presColorBool ? (isSelected ? 'rgba(250,250,250,0.3)' : 'transparent') : isSelected ? Colors.LIGHT_BLUE : 'transparent', opacity: this._dragging ? 0.3 : 1, + paddingLeft: NumCast(this.layoutDoc._xPadding, this.props.xPadding), + paddingRight: NumCast(this.layoutDoc._xPadding, this.props.xPadding), + paddingTop: NumCast(this.layoutDoc._yPadding, this.props.yPadding), + paddingBottom: NumCast(this.layoutDoc._yPadding, this.props.yPadding), }} onClick={e => { e.stopPropagation(); @@ -507,6 +588,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { ref={this._dragRef} className={`presItem-slide ${isCurrent ? 'active' : ''}`} style={{ + display: 'infline-block', backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor), //boxShadow: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? '0 0 0px 1.5px' + presBoxColor : undefined) : undefined, border: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? presBoxColor + ' solid 2.5px' : undefined) : undefined, @@ -514,8 +596,9 @@ export class PresElementBox extends ViewBoxBaseComponent() {
{`${this.indexInPres + 1}. `}
@@ -523,56 +606,8 @@ export class PresElementBox extends ViewBoxBaseComponent() {
{/*
{"Movement speed"}
}>
{this.transition}
*/} {/*
{"Duration"}
}>
{this.duration}
*/} -
- Update captured doc layout
}> -
this.updateCapturedContainerLayout(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinLayout ? 'flex' : 'none' }}> - L -
- - Update captured doc content}> -
this.updateCapturedViewContents(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinData || activeItem.presPinView ? 'flex' : 'none' }}> - C -
-
- {!Doc.noviceMode && ( - {this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}}> -
(this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> - e.stopPropagation()} /> -
-
- )} - {activeItem.groupWithUp ? 'Ungroup' : 'Group with up'}}> -
(activeItem.groupWithUp = !activeItem.groupWithUp)} - style={{ - display: this.indexInPres === 0 ? 'none' : '', - 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.presButtons}
{this.renderEmbeddedInline} diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 466b43287..fc43325fe 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -238,6 +238,9 @@ export class Doc extends RefField { Doc.UserDoc().activePage = val; DocServer.UPDATE_SERVER_CACHE(); } + public static IsComicStyle(doc?: Doc) { + return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic'; + } public static get ActiveDashboard() { return DocCast(Doc.UserDoc().activeDashboard); } -- cgit v1.2.3-70-g09d2