diff options
author | bob <bcz@cs.brown.edu> | 2019-11-21 11:59:07 -0500 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-11-21 11:59:07 -0500 |
commit | b1fadd1137f35fe64b9dc8df42a3160882f4cccd (patch) | |
tree | 6ce76cd9b24d70146a4e3102a91d65ccd0794a20 | |
parent | 66e44646eafc8f66c4683e768b39f179950679d8 (diff) |
more fixes to layout stuff
5 files changed, 45 insertions, 34 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 210fa40dc..66f47147f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -463,7 +463,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> break; } - SelectionManager.SelectedDocuments().forEach(element => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { let doc = PositionDocument(element.props.Document); let layoutDoc = PositionDocument(Doc.Layout(element.props.Document)); @@ -509,7 +509,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> dH && layoutDoc.autoHeight && (layoutDoc.autoHeight = false); } } - }); + })); } @action diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index 48d330674..e1d23ddcb 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -6,6 +6,8 @@ import { ScriptField } from "../../../../new_fields/ScriptField"; import { OverlayView, OverlayElementOptions } from "../../OverlayView"; import { emptyFunction } from "../../../../Utils"; import React = require("react"); +import { ObservableMap, runInAction } from "mobx"; +import { Id } from "../../../../new_fields/FieldSymbols"; interface PivotData { type: string; @@ -31,8 +33,7 @@ export interface ViewDefResult { bounds?: ViewDefBounds; } -export function computePivotLayout(pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], viewDefsToJSX: (views: any) => ViewDefResult[]) { - let layoutPoolData: Map<{ layout: Doc, data?: Doc }, any> = new Map(); +export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], viewDefsToJSX: (views: any) => ViewDefResult[]) { const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, 200); const pivotColumnGroups = new Map<FieldResult<Field>, Doc[]>(); @@ -49,6 +50,8 @@ export function computePivotLayout(pivotDoc: Doc, childDocs: Doc[], childPairs: const docMap = new Map<Doc, ViewDefBounds>(); const groupNames: PivotData[] = []; + const expander = 1.05; + const gap = .15; let x = 0; pivotColumnGroups.forEach((val, key) => { let y = 0; @@ -58,25 +61,31 @@ export function computePivotLayout(pivotDoc: Doc, childDocs: Doc[], childPairs: text: String(key), x, y: pivotAxisWidth + 50, - width: pivotAxisWidth * 1.25 * numCols, + width: pivotAxisWidth * expander * numCols, height: 100, fontSize: NumCast(pivotDoc.pivotFontSize, 10) }); for (const doc of val) { let layoutDoc = Doc.Layout(doc); + let wid = pivotAxisWidth; + let hgt = layoutDoc.nativeWidth ? (NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth)) * pivotAxisWidth : pivotAxisWidth; + if (hgt > pivotAxisWidth) { + hgt = pivotAxisWidth; + wid = layoutDoc.nativeHeight ? (NumCast(layoutDoc.nativeWidth) / NumCast(layoutDoc.nativeHeight)) * pivotAxisWidth : pivotAxisWidth; + } docMap.set(doc, { - x: x + xCount * pivotAxisWidth * 1.25, + x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2, y: -y, - width: pivotAxisWidth, - height: layoutDoc.nativeWidth ? (NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth)) * pivotAxisWidth : pivotAxisWidth + width: wid, + height: hgt }); xCount++; if (xCount >= numCols) { - xCount = 0; - y += pivotAxisWidth * 1.25; + xCount = (pivotAxisWidth - wid) / 2; + y += pivotAxisWidth * expander; } } - x += pivotAxisWidth * 1.25 * (numCols + 1); + x += pivotAxisWidth * (numCols * expander + gap); }); childPairs.map(pair => { @@ -88,9 +97,12 @@ export function computePivotLayout(pivotDoc: Doc, childDocs: Doc[], childPairs: height: NumCast(pair.layout.height) }; const pos = docMap.get(pair.layout) || defaultPosition; - layoutPoolData.set(pair, { transition: "transform 1s", ...pos }); + let data = poolData.get(pair.layout[Id]); + if (!data || pos.x !== data.x || pos.y !== data.y || pos.z !== data.z || pos.width !== data.width || pos.height !== data.height) { + runInAction(() => poolData.set(pair.layout[Id], { transition: "transform 1s", ...pos })); + } }); - return { map: layoutPoolData, elements: viewDefsToJSX(groupNames) }; + return { elements: viewDefsToJSX(groupNames) }; } export function AddCustomFreeFormLayout(doc: Doc, dataKey: string): () => void { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index d2731703f..070d4aa65 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -1,5 +1,6 @@ @import "../../globalCssVariables"; +.collectionfreeformview-none, .collectionfreeformview-ease { position: inherit; top: 0; @@ -7,16 +8,14 @@ width: 100%; height: 100%; transform-origin: left top; + border-radius: inherit; +} + +.collectionfreeformview-ease { transition: transform 1s; } .collectionfreeformview-none { - position: inherit; - top: 0; - left: 0; - width: 100%; - height: 100%; - transform-origin: left top; touch-action: none; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 256ceb8f8..3dd655b96 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -73,7 +73,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { private _layoutPoolData = new ObservableMap<string, any>(); public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive - @observable _layoutElements: ViewDefResult[] = []; + @observable.shallow _layoutElements: ViewDefResult[] = []; // shallow because some layout items (eg pivot labels) are just generated 'divs' and can't be frozen as observables @observable _clusterSets: (Doc[])[] = []; @computed get fitToContent() { return (this.props.fitToBox || this.Document.fitToBox) && !this.isAnnotationOverlay; } @@ -653,12 +653,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { childDataProvider = computedFn((doc: Doc) => this._layoutPoolData.get(doc[Id])); - get doPivotLayout() { - return computePivotLayout(this.props.Document, this.childDocs, + doPivotLayout(poolData: ObservableMap<string, any>) { + return computePivotLayout(poolData, this.props.Document, this.childDocs, this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)), this.viewDefsToJSX); } - get doFreeformLayout() { + doFreeformLayout(poolData: ObservableMap<string, any>) { let layoutDocs = this.childLayoutPairs.map(pair => pair.layout); const initResult = this.Document.arrangeInit && this.Document.arrangeInit.script.run({ docs: layoutDocs, collection: this.Document }, console.log); let state = initResult && initResult.success ? initResult.result.scriptState : undefined; @@ -669,7 +669,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { state = pos.state === undefined ? state : pos.state; let data = this._layoutPoolData.get(pair.layout[Id]); if (!data || pos.x !== data.x || pos.y !== data.y || pos.z !== data.z || pos.width !== data.width || pos.height !== data.height || pos.transition !== data.transition) { - runInAction(() => this._layoutPoolData.set(pair.layout[Id], pos)); + runInAction(() => poolData.set(pair.layout[Id], pos)); } }); return { elements: elements }; @@ -678,8 +678,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { get doLayoutComputation() { let computedElementData: { elements: ViewDefResult[] }; switch (this.Document.freeformLayoutEngine) { - case "pivot": computedElementData = this.doPivotLayout; break; - default: computedElementData = this.doFreeformLayout; break; + case "pivot": computedElementData = this.doPivotLayout(this._layoutPoolData); break; + default: computedElementData = this.doFreeformLayout(this._layoutPoolData); break; } this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).forEach(pair => computedElementData.elements.push({ @@ -693,14 +693,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } componentDidMount() { - this._layoutComputeReaction = reaction(() => this.doLayoutComputation, + this._layoutComputeReaction = reaction(() => { trace(); return this.doLayoutComputation }, action((computation: { elements: ViewDefResult[] }) => computation && (this._layoutElements = computation.elements)), { fireImmediately: true }); } componentWillUnmount() { this._layoutComputeReaction && this._layoutComputeReaction(); } - @computed.struct get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); } + @computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); } elementFunc = () => this._layoutElements; @action @@ -873,9 +873,8 @@ interface CollectionFreeFormOverlayViewProps { @observer class CollectionFreeFormOverlayView extends React.Component<CollectionFreeFormOverlayViewProps>{ - @computed.struct get overlayViews() { return this.props.elements().filter(ele => ele.bounds && ele.bounds.z).map(ele => ele.ele); } render() { - return this.overlayViews; + return this.props.elements().filter(ele => ele.bounds && ele.bounds.z).map(ele => ele.ele); } } @@ -898,7 +897,7 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF const panx = -this.props.panX(); const pany = -this.props.panY(); const zoom = this.props.zoomScaling(); - return <div className={freeformclass} style={{ borderRadius: "inherit", transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)` }}> + return <div className={freeformclass} style={{ transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)` }}> {this.props.children()} </div>; } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 7d8f39e41..22c3a29a8 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -672,14 +672,15 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument marqueeing = () => this._marqueeing; visibleHeight = () => this.props.PanelHeight() / this.props.ContentScaling() * 72 / 96; contentZoom = () => this._zoomed; + @computed get contentScaling() { return this.props.ContentScaling() } render() { trace(); return !this.extensionDoc ? (null) : <div className={"pdfViewer-viewer" + (this._zoomed !== 1 ? "-zoomed" : "")} ref={this._mainCont} style={{ - width: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeWidth) : `${100 / this.props.ContentScaling()}%`, - height: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeHeight) : `${100 / this.props.ContentScaling()}%`, - transform: `scale(${this.props.ContentScaling()})` + width: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeWidth) : `${100 / this.contentScaling}%`, + height: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeHeight) : `${100 / this.contentScaling}%`, + transform: `scale(${this.contentScaling})` }} onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}> {this.pdfViewerDiv} {this.overlayLayer} |