diff options
| author | bobzel <zzzman@gmail.com> | 2022-10-25 11:10:12 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2022-10-25 11:10:12 -0400 |
| commit | ba73479fe6c0594ebe37eed6cf295e5adc49c8e1 (patch) | |
| tree | b708266a43d1e2eb0594cf6ae5b402d0e3da9323 /src/client/views/collections | |
| parent | c06e87b8128acb9ed2570536fc500a2bb670abf4 (diff) | |
various tweaks: show border highlights in tree views, uniform treatment of embedding using title bar, even for free form views, choose bestAlias when dragging from files menu, text boxes honor document moves, show title for timeline annotations, fix dragoffset for stacks with buttons/description headers,
Diffstat (limited to 'src/client/views/collections')
4 files changed, 32 insertions, 33 deletions
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 30759b766..7bc273d7d 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -218,12 +218,7 @@ export function CollectionSubView<X>(moreProps?: X) { const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d); const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d); if (movedDocs.length) { - const canAdd = - this.props.Document._viewType === CollectionViewType.Pile || - de.embedKey || - !this.props.isAnnotationOverlay || - this.props.Document.allowOverlayDrop || - Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document); + const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey || this.props.Document.allowOverlayDrop || Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document); added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.addDocument : returnFalse); } else { ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData }); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index fe5dc17f5..1169f692a 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -147,6 +147,8 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree } }; + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this._headerHeight); + @action remove = (doc: Doc | Doc[]): boolean => { const docs = doc instanceof Doc ? [doc] : doc; @@ -275,7 +277,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree dropAction, this.props.addDocTab, this.props.styleProvider, - this.props.ScreenToLocalTransform, + this.screenToLocalTransform, this.isContentActive, this.panelWidth, this.props.renderDepth, @@ -377,6 +379,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => this.props.CollectionView?.moveDocument(doc, targetCollection, addDocument, `${this.props.fieldKey}-annotations`) || false; + @observable _headerHeight = 0; contentFunc = () => { const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor); const pointerEvents = () => (!this.props.isContentActive() && !SnappingManager.GetIsDragging() ? 'none' : undefined); @@ -384,7 +387,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree return [ <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}> {!this.buttonMenu && !this.noviceExplainer ? null : ( - <div className="documentButtonMenu"> + <div className="documentButtonMenu" ref={action((r: HTMLDivElement | null) => r && (this._headerHeight = Number(getComputedStyle(r).height.replace(/px/, ''))))}> {this.buttonMenu} {this.noviceExplainer} </div> diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 409b615f4..b9f86fa6b 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -10,11 +10,12 @@ 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, returnOne, returnTrue, simulateMouseClick, Utils } from '../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, simulateMouseClick, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from '../../util/DragManager'; +import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SelectionManager } from '../../util/SelectionManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; @@ -31,7 +32,6 @@ import { CollectionTreeView, TreeViewType } from './CollectionTreeView'; import { CollectionView } from './CollectionView'; import './TreeView.scss'; import React = require('react'); -import { ScriptingGlobals } from '../../util/ScriptingGlobals'; export interface TreeViewProps { treeView: CollectionTreeView; @@ -792,12 +792,14 @@ export class TreeView extends React.Component<TreeViewProps> { titleStyleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, 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 + // 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.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.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 : ( <div className="treeView-label" @@ -805,13 +807,13 @@ export class TreeView extends React.Component<TreeViewProps> { // just render a title for a tree view label (identified by treeViewDoc being set in 'props') maxWidth: props?.PanelWidth() || undefined, background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor), + outline: `solid ${highlightColor} ${highlightIndex}px`, }}> {StrCast(doc?.title)} </div> ); - default: - return this.props?.treeView?.props.styleProvider?.(doc, props, property); } + return this.props?.treeView?.props.styleProvider?.(doc, props, property); }; embeddedStyleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string): any => { if (property.startsWith(StyleProp.Decorations)) return null; @@ -1011,6 +1013,7 @@ export class TreeView extends React.Component<TreeViewProps> { pinToPres={this.props.treeView.props.pinToPres} disableDocBrushing={this.props.treeView.props.disableDocBrushing} bringToFront={returnFalse} + scriptContext={this} /> ); }; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 88422cbd4..eca95e1e0 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -113,7 +113,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @observable _clusterSets: Doc[][] = []; @observable _deleteList: DocumentView[] = []; @observable _timelineRef = React.createRef<Timeline>(); - @observable _marqueeRef = React.createRef<HTMLDivElement>(); + @observable _marqueeRef: HTMLDivElement | null = null; @observable _marqueeViewRef = React.createRef<MarqueeView>(); @observable ChildDrag: DocumentView | undefined; // child document view being dragged. needed to update drop areas of groups when a group item is dragged. @observable _brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 }; // highlighted region of freeform canvas used by presentations to indicate a region @@ -1011,22 +1011,22 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection switch (Doc.UserDoc().freeformScrollMode) { case freeformScrollMode.Pan: // if shift is selected then zoom - if(e.ctrlKey) { + if (e.ctrlKey) { if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming } else if (this.props.isContentActive(true) && !this.Document._isGroup) { !this.props.isAnnotationOverlayScrollable && this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc? } - // otherwise pan + // otherwise pan } else if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming } else if (this.props.isContentActive(true) && !this.Document._isGroup) { const dx = e.deltaX; const dy = e.deltaY; if (e.shiftKey) { - !this.props.isAnnotationOverlayScrollable && this.scrollPan({ deltaX: dy, deltaY: 0 }); + !this.props.isAnnotationOverlayScrollable && this.scrollPan({ deltaX: dy, deltaY: 0 }); } else { - !this.props.isAnnotationOverlayScrollable && this.scrollPan({ deltaX: dx, deltaY: dy }); + !this.props.isAnnotationOverlayScrollable && this.scrollPan({ deltaX: dx, deltaY: dy }); } } break; @@ -1548,9 +1548,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection setTimeout( action(() => { this._firstRender = false; - - this._marqueeRef.current?.addEventListener('dashDragAutoScroll', this.onDragAutoScroll as any); - this._disposers.groupBounds = reaction( () => { if (this.props.Document._isGroup && this.childDocs.length === this.childDocList?.length) { @@ -1668,7 +1665,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection componentWillUnmount() { Object.values(this._disposers).forEach(disposer => disposer?.()); - this._marqueeRef.current?.removeEventListener('dashDragAutoScroll', this.onDragAutoScroll as any); + this._marqueeRef?.removeEventListener('dashDragAutoScroll', this.onDragAutoScroll as any); } @action @@ -1681,10 +1678,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection if ((e as any).handlePan || this.props.isAnnotationOverlay) return; (e as any).handlePan = true; - if (!this.layoutDoc._noAutoscroll && !this.props.renderDepth && this._marqueeRef?.current) { + if (!this.layoutDoc._noAutoscroll && !this.props.renderDepth && this._marqueeRef) { const dragX = e.detail.clientX; const dragY = e.detail.clientY; - const bounds = this._marqueeRef.current?.getBoundingClientRect(); + const bounds = this._marqueeRef?.getBoundingClientRect(); const deltaX = dragX - bounds.left < 25 ? -(25 + (bounds.left - dragX)) : bounds.right - dragX < 25 ? 25 - (bounds.right - dragX) : 0; const deltaY = dragY - bounds.top < 25 ? -(25 + (bounds.top - dragY)) : bounds.bottom - dragY < 25 ? 25 - (bounds.bottom - dragY) : 0; @@ -1842,10 +1839,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection DragManager.SetSnapLines(horizLines, vertLines); }; - onPointerOver = (e: React.PointerEvent) => { - e.stopPropagation(); - }; - incrementalRender = action(() => { if (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath())) { const unrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id])); @@ -1889,7 +1882,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}> - <div className="marqueeView-div" ref={this._marqueeRef} style={{ opacity: this.props.dontRenderDocuments ? 0.7 : undefined }}> + <div + className="marqueeView-div" + ref={r => { + this._marqueeRef = r; + r?.addEventListener('dashDragAutoScroll', this.onDragAutoScroll as any); + }} + style={{ opacity: this.props.dontRenderDocuments ? 0.7 : undefined }}> {this.layoutDoc._backgroundGridShow ? ( <div> <CollectionFreeFormBackgroundGrid // bcz : UGHH don't know why, but if we don't wrap in a div, then PDF's don't render whenn taking snapshot of a dashboard and the background grid is on!!? @@ -1965,7 +1964,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection <div className={'collectionfreeformview-container'} ref={this.createDashEventsTarget} - onPointerOver={this.onPointerOver} onWheel={this.onPointerWheel} onClick={this.onClick} onPointerDown={this.onPointerDown} |
