aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/LightboxView.tsx27
-rw-r--r--src/client/views/collections/TabDocView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx40
-rw-r--r--src/client/views/nodes/DocumentView.tsx8
4 files changed, 48 insertions, 29 deletions
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 0957fc94d..7fab88800 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -3,7 +3,7 @@ import { action, observable, computed } from 'mobx';
import { observer } from 'mobx-react';
import "normalize.css";
import * as React from 'react';
-import { Doc, Opt } from '../../fields/Doc';
+import { Doc, Opt, DocListCast } from '../../fields/Doc';
import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../Utils';
import { Transform } from '../util/Transform';
import "./LightboxView.scss";
@@ -13,7 +13,7 @@ import { DocUtils } from '../documents/Documents';
import { DocumentManager } from '../util/DocumentManager';
import { SelectionManager } from '../util/SelectionManager';
import { TabDocView } from './collections/TabDocView';
-import { Cast } from '../../fields/Types';
+import { Cast, NumCast } from '../../fields/Types';
interface LightboxViewProps {
PanelWidth: number;
@@ -50,10 +50,10 @@ export class LightboxView extends React.Component<LightboxViewProps> {
return true;
}
- public static IsLightboxDocView(path: DocumentView[]) { return path.includes(LightboxView.LightboxDocView.current!); }
+ public static IsLightboxDocView(path: DocumentView[]) { return path.includes(LightboxView.LightboxDocView!); }
public static LightboxHistory: (Opt<Doc>)[] = [];
public static LightboxFuture: (Opt<Doc>)[] = [];
- public static LightboxDocView = React.createRef<DocumentView>();
+ public static LightboxDocView: Opt<DocumentView>;
@computed get leftBorder() { return Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]); }
@computed get topBorder() { return Math.min(this.props.PanelHeight / 4, this.props.maxBorder[1]); }
lightboxWidth = () => this.props.PanelWidth - this.leftBorder * 2;
@@ -71,10 +71,12 @@ export class LightboxView extends React.Component<LightboxViewProps> {
</div>
</div>;
}
- addDocTab = (doc: Doc, location: string) => {
+ public static AddDocTab = (doc: Doc, location: string) => {
SelectionManager.DeselectAll();
- return LightboxView.SetLightboxDoc(doc);
+ return LightboxView.SetLightboxDoc(doc, [...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + "-annotations"])]
+ .sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)));
}
+ addDocTab = LightboxView.AddDocTab;
fitToBox = () => LightboxView.LightboxDocTarget === LightboxView.LightboxDoc;
render() {
@@ -94,7 +96,18 @@ export class LightboxView extends React.Component<LightboxViewProps> {
width: this.lightboxWidth(),
height: this.lightboxHeight()
}}>
- <DocumentView ref={LightboxView.LightboxDocView}
+ <DocumentView ref={action((r: DocumentView | null) => {
+ LightboxView.LightboxDocView = r !== null ? r : undefined;
+ setTimeout(action(() => {
+ const vals = r?.ComponentView?.freeformData?.();
+ if (vals && r) {
+ r.layoutDoc._panX = vals.panX;
+ r.layoutDoc._panY = vals.panY;
+ r.layoutDoc._viewScale = vals.scale;
+ }
+ LightboxView.LightboxDocTarget = undefined;
+ }));
+ })}
Document={LightboxView.LightboxDoc}
DataDoc={undefined}
addDocument={undefined}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 9048a5f01..d62b8b6f6 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -279,7 +279,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
case "replace": return CollectionDockingView.ReplaceTab(doc, locationParams, this.stack);
- case "lightbox": return LightboxView.SetLightboxDoc(doc, DocListCast(doc[Doc.LayoutFieldKey(doc) + "-annotations"]).sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)));
+ case "lightbox": return LightboxView.AddDocTab(doc, location);
case "inPlace":
case "add":
default:
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1f65cf1ea..954b6478f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -117,7 +117,16 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@observable _marqueeRef = React.createRef<HTMLDivElement>();
@computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); }
- @computed get fitToContentScaling() { return this.fitToContent ? NumCast(this.layoutDoc.fitToContentScaling, 1) : 1; }
+ @computed get fitToContentVals() {
+ return this.fitToContent &&
+ {
+ panX: (this.contentBounds.x + this.contentBounds.r) / 2,
+ panY: (this.contentBounds.y + this.contentBounds.b) / 2,
+ scale: !this.childDocs.length ? 1 :
+ Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y),
+ this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x))
+ } || undefined;
+ }
@computed get fitToContent() { return (this.props.fitContentsToDoc?.() || this.Document._fitToBox) && !this.isAnnotationOverlay; }
@computed get parentScaling() { return 1; }
@computed get contentBounds() { return aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); }
@@ -126,17 +135,9 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
private get isAnnotationOverlay() { return this.props.isAnnotationOverlay; }
private get scaleFieldKey() { return this.props.scaleField || "_viewScale"; }
private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
- private panX = () => this.fitToContent && !this.props.isAnnotationOverlay ? (this.contentBounds.x + this.contentBounds.r) / 2 : this.Document._panX || 0;
- private panY = () => this.fitToContent && !this.props.isAnnotationOverlay ? (this.contentBounds.y + this.contentBounds.b) / 2 : this.Document._panY || 0;
- private zoomScaling = () => {
- const mult = this.fitToContentScaling / this.parentScaling;
- if (this.fitToContent) {
- const zs = !this.childDocs.length ? 1 :
- Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y), this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x));
- return mult * zs;
- }
- return mult * NumCast(this.Document[this.scaleFieldKey], 1);
- }
+ private panX = () => this.fitToContentVals?.panX ?? NumCast(this.Document._panX);
+ private panY = () => this.fitToContentVals?.panY ?? NumCast(this.Document._panY);
+ private zoomScaling = () => (this.fitToContentVals?.scale ?? NumCast(this.Document[this.scaleFieldKey], 1)) / this.parentScaling;
@computed get cachedCenteringShiftX(): number {
const scaling = this.fitToContent || !this.contentScaling ? 1 : this.contentScaling;
return this.props.isAnnotationOverlay ? 0 : this.props.PanelWidth() / 2 / this.parentScaling / scaling; // shift so pan position is at center of window for non-overlay collections
@@ -607,14 +608,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
onClick = (e: React.MouseEvent) => {
- if (this.layoutDoc.targetScale && (Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) {
+ if ((Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) {
if (Date.now() - this._lastTap < 300) { // reset zoom of freeform view to 1-to-1 on a double click
if (e.shiftKey) {
- this.scaleAtPt(this.getTransform().transformPoint(e.clientX, e.clientY), 1);
+ if (this.layoutDoc.targetScale) {
+ this.scaleAtPt(this.getTransform().transformPoint(e.clientX, e.clientY), 1);
+ }
e.stopPropagation();
e.preventDefault();
- } else {
- LightboxView.SetLightboxDoc(this.rootDoc, this.childDocs);
}
}
this._lastTap = Date.now();
@@ -937,6 +938,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
Doc.BrushDoc(this.rootDoc);
!doc.hidden && Doc.linkFollowHighlight(doc);
+ const startTime = Date.now();
// focus on this collection within its parent view. the parent view after focusing determines whether to reset the view change within the collection
const endFocus = async (moved: boolean) => {
doc.hidden && Doc.UnHighlightDoc(doc);
@@ -956,8 +958,9 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
:
new Transform(NumCast(this.rootDoc.x) + this.rootDoc[WidthSym]() / 2 - NumCast(this.rootDoc._panX),
NumCast(this.rootDoc.y) + this.rootDoc[HeightSym]() / 2 - NumCast(this.rootDoc._panY), 1);
+
this.props.focus(cantTransform ? doc : this.rootDoc, willZoom, scale, (didFocus: boolean) =>
- new Promise<boolean>(res => setTimeout(async () => res(await endFocus(didMove || didFocus)), focusSpeed)), xf);
+ new Promise<boolean>(res => setTimeout(async () => res(await endFocus(didMove || didFocus)), Math.max(0, focusSpeed - (Date.now() - startTime)))), xf);
}
}
@@ -1185,10 +1188,11 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.Document._useClusters && !this._clusterSets.length && this.childDocs.length && this.updateClusters(true);
return elements;
}
-
+ freeformData = () => { return this.fitToContentVals; }
@action
componentDidMount() {
super.componentDidMount?.();
+ this.props.setContentView?.(this);
this._layoutComputeReaction = reaction(() => this.doLayoutComputation,
(elements) => this._layoutElements = elements || [],
{ fireImmediately: true, name: "doLayout" });
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d593b75eb..7ba0d7043 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -46,12 +46,13 @@ export type DocAfterFocusFunc = (notFocused: boolean) => Promise<boolean>;
export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, docTransform?: Transform) => void;
export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => any;
export interface DocComponentView {
- getAnchor: () => Doc;
+ getAnchor?: () => Doc;
scrollFocus?: (doc: Doc, smooth: boolean) => Opt<number>; // returns the duration of the focus
back?: () => boolean;
forward?: () => boolean;
url?: () => string;
submitURL?: (url: string) => boolean;
+ freeformData?: () => Opt<{ panX: number, panY: number, scale: number }>;
}
export interface DocumentViewSharedProps {
renderDepth: number;
@@ -388,7 +389,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
let stopPropagate = true;
let preventDefault = true;
!StrListCast(this.props.Document.layers).includes(StyleLayers.Background) && (this.rootDoc._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : this.rootDoc._raiseWhenDragged) && this.props.bringToFront(this.rootDoc);
- if (this._doubleTap && ((this.props.renderDepth && this.props.Document.type !== DocumentType.FONTICON) || this.onDoubleClickHandler)) {// && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
+ if (this._doubleTap && (this.props.Document.type !== DocumentType.FONTICON || this.onDoubleClickHandler)) {// && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
if (this._timeout) {
clearTimeout(this._timeout);
this._timeout = undefined;
@@ -513,7 +514,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
this.onPointerUpHandler.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log);
} else {
this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
- if (!this.props.isSelected(true)) this._lastTap = Date.now();// don't want to process the start of a double tap if the doucment is selected
+ // bcz: this is a placeholder. documents, when selected, should stopPropagation on doubleClicks if they want to keep the DocumentView from getting them
+ if (!this.props.isSelected(true) || ![DocumentType.PDF, DocumentType.RTF].includes(StrCast(this.rootDoc.type) as any)) this._lastTap = Date.now();// don't want to process the start of a double tap if the doucment is selected
}
}