aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-02-11 00:54:52 -0500
committerbobzel <zzzman@gmail.com>2021-02-11 00:54:52 -0500
commitc86cb3966ecb905c2dc6a6236b71d7ce9c8fb80f (patch)
treeb298bac13fe89cf8119c28ee95268dcc0844b0e0
parentaed4a386bf57ba7b1b144bacd39f9f9ccabe0dfd (diff)
playing with trying to improve chaining of nested focus() method calls.
-rw-r--r--src/Utils.ts4
-rw-r--r--src/client/util/DocumentManager.ts51
-rw-r--r--src/client/views/collections/TabDocView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx56
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
-rw-r--r--src/client/views/nodes/WebBox.tsx4
6 files changed, 67 insertions, 55 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 061c74611..770cef283 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -192,8 +192,8 @@ export namespace Utils {
}
export function scrollIntoView(targetY: number, targetHgt: number, scrollTop: number, contextHgt: number) {
- if (scrollTop + contextHgt < targetY + Math.max(targetHgt * 1.1, 100)) {
- return Math.min(scrollTop, targetY + Math.max(targetHgt * 1.1, 100) - contextHgt);
+ if (scrollTop + contextHgt < targetY + targetHgt * 1.1) {
+ return targetY + targetHgt * 1.1 - contextHgt;
} else if (scrollTop > targetY - targetHgt * .1) {
return Math.max(0, targetY - targetHgt * .1);
}
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index ac7710d34..e5ef924d6 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -143,45 +143,52 @@ export class DocumentManager {
finished?: () => void,
): Promise<void> => {
const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView;
- const focusAndFinish = () => { finished?.(); return false; };
+ const docView = getFirstDocView(targetDoc, originatingDoc);
+ const focusAndFinish = (didFocus: boolean) => {
+ if (originatingDoc?.isPushpin) {
+ if (!didFocus || targetDoc.hidden) {
+ targetDoc.hidden = !targetDoc.hidden;
+ }
+ } else {
+ targetDoc.hidden && (targetDoc.hidden = undefined);
+ docView?.select(false);
+ }
+ finished?.();
+ return false;
+ };
const highlight = () => {
const finalDocView = getFirstDocView(targetDoc);
finalDocView && Doc.linkFollowHighlight(finalDocView.rootDoc);
};
- const docView = getFirstDocView(targetDoc, originatingDoc);
let annotatedDoc = Cast(targetDoc.annotationOn, Doc, null);
+ const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined;
+ const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext : undefined;
+ const targetDocContext = contextDoc || annotatedDoc;
+ const targetDocContextView = targetDocContext && getFirstDocView(targetDocContext);
if (!docView && annotatedDoc && annotatedDoc !== originatingDoc?.context && targetDoc.type === DocumentType.TEXTANCHOR) {
const first = getFirstDocView(annotatedDoc);
if (first) {
annotatedDoc = first.rootDoc;
first.focus(targetDoc, false);
}
- } else if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight?
- if (originatingDoc?.isPushpin) {
- docView.props.focus(docView.rootDoc, willZoom, undefined, (didFocus: boolean) => {
- if (!didFocus || docView.rootDoc.hidden) {
- docView.rootDoc.hidden = !docView.rootDoc.hidden;
- }
- return focusAndFinish();
- });
- }
- else {
- docView.select(false);
- docView.rootDoc.hidden && (docView.rootDoc.hidden = undefined);
- // @ts-ignore
- docView.props.focus(docView.rootDoc, willZoom, undefined, focusAndFinish);
- }
+ } else if (docView && (targetDocContextView || !targetDocContext)) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight?
+ const first = annotatedDoc && getFirstDocView(annotatedDoc);
+ const targetFocus = (outFocus?: boolean) => docView.props.focus(docView.rootDoc, willZoom, undefined, (didFocus: boolean) => focusAndFinish(outFocus || didFocus));
+ const annoFocus = (outFocus?: boolean) => first?.props.focus(first.rootDoc, false, undefined, (didFocus: boolean) => {
+ targetFocus(outFocus || didFocus);
+ return false;
+ });
+ const contextFocus = targetDocContext === annotatedDoc ? undefined : (outFocus?: boolean) => targetDocContextView?.props.focus(targetDocContext, false, undefined, (didFocus: boolean) => {
+ annoFocus(outFocus || didFocus);
+ return false;
+ });
+ (contextFocus || annoFocus || targetFocus)();
highlight();
} else {
- const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined;
- const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext : undefined;
- const targetDocContext = contextDoc || annotatedDoc;
-
if (!targetDocContext) { // we don't have a view and there's no context specified ... create a new view of the target using the dockFunc or default
createViewFunc(Doc.BrushDoc(targetDoc), finished); // bcz: should we use this?: Doc.MakeAlias(targetDoc)));
highlight();
} else { // otherwise try to get a view of the context of the target
- const targetDocContextView = getFirstDocView(targetDocContext);
if (targetDocContextView) { // we found a context view and aren't forced to create a new one ... focus on the context first..
targetDocContext._viewTransition = "transform 500ms";
targetDocContextView.props.focus(targetDocContextView.rootDoc, willZoom);
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 38e1551e6..e1e1c8656 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -356,7 +356,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
</Tooltip>
</>;
}
- focusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, notFocused?: boolean) => {
+ focusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => {
if (!this.tab.header.parent._activeContentItem || this.tab.header.parent._activeContentItem !== this.tab.contentItem) {
this.tab.header.parent.setActiveContentItem(this.tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 68a65dfe7..6fdd569da 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -907,53 +907,59 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
} else {
const layoutdoc = Doc.Layout(doc);
const savedState = { px: NumCast(this.Document._panX), py: NumCast(this.Document._panY), s: this.Document[this.scaleFieldKey], pt: this.Document._viewTransition };
-
const newState = HistoryUtil.getState();
- let newPanX = savedState.px;
- let newPanY = savedState.py;
+ const { px, py } = layoutdoc.annotationOn ? savedState : willZoom ? this.setZoomToDoc(layoutdoc, scale) : this.setPanIntoView(doc);
if (!layoutdoc.annotationOn) { // only pan and zoom to focus on a document if the document is not an annotation in an annotation overlay collection
- willZoom && this.setScaleToZoom(layoutdoc, scale);
- const cx = NumCast(this.props.Document._panX);
- const cy = NumCast(this.props.Document._panY);
- const pwid = this.props.PanelWidth() / NumCast(this.props.Document._viewScale, 1);
- const phgt = this.props.PanelHeight() / NumCast(this.props.Document._viewScale, 1);
- const screen = { left: cx - pwid / 2, right: cx + pwid / 2, top: cy - phgt / 2, bot: cy + phgt / 2 };
- const bounds = { left: NumCast(doc.x) - pwid / 10, right: NumCast(doc.x) + doc[WidthSym]() + pwid / 10, top: NumCast(doc.y) - phgt / 10, bot: NumCast(doc.y) + doc[HeightSym]() + phgt / 10 };
- newPanX = cx + Math.min(0, bounds.left - screen.left) + Math.max(0, bounds.right - screen.right);
- newPanY = cy + Math.min(0, bounds.top - screen.top) + Math.max(0, bounds.bot - screen.bot);
- newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
+ newState.initializers![this.Document[Id]] = { panX: px, panY: py };
HistoryUtil.pushState(newState);
}
if (DocListCast(this.dataDoc[this.props.fieldKey]).includes(doc)) {
// glr: freeform transform speed can be set by adjusting presTransition field - needs a way of knowing when presentation is not active...
- if (!doc.z) this.setPan(newPanX, newPanY, doc.focusSpeed || doc.focusSpeed === 0 ? `transform ${doc.focusSpeed}ms` : "transform 500ms", true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
+ if (!doc.z) this.setPan(px, py, doc.focusSpeed || doc.focusSpeed === 0 ? `transform ${doc.focusSpeed}ms` : "transform 500ms", true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
}
Doc.BrushDoc(this.props.Document);
- const newAfterFocus = (didFocus: boolean) => {
- afterFocus && setTimeout(() => {
- // @ts-ignore
- if (afterFocus?.(didFocus || (newPanX !== savedState.px || newPanY !== savedState.py))) {
+ !doc.hidden && Doc.linkFollowHighlight(doc);
+ this.props.focus(this.props.Document, undefined, undefined, (didFocus: boolean) => {
+ setTimeout(() => {
+ if (afterFocus?.(didFocus || (px !== savedState.px || py !== savedState.py))) {
this.Document._panX = savedState.px;
this.Document._panY = savedState.py;
this.Document[this.scaleFieldKey] = savedState.s;
this.Document._viewTransition = savedState.pt;
}
doc.hidden && Doc.UnHighlightDoc(doc);
- }, newPanX !== savedState.px || newPanY !== savedState.py ? 500 : 0);
+ }, px !== savedState.px || py !== savedState.py ? 500 : 0);
return false;
- };
- this.props.focus(this.props.Document, undefined, undefined, newAfterFocus);
- !doc.hidden && Doc.linkFollowHighlight(doc);
+ });
}
+ }
+ setPanIntoView = (doc: Doc) => {
+ const cx = NumCast(this.props.Document._panX);
+ const cy = NumCast(this.props.Document._panY);
+ const pwid = this.props.PanelWidth() / NumCast(this.props.Document._viewScale, 1);
+ const phgt = this.props.PanelHeight() / NumCast(this.props.Document._viewScale, 1);
+ const screen = { left: cx - pwid / 2, right: cx + pwid / 2, top: cy - phgt / 2, bot: cy + phgt / 2 };
+ const bounds = { left: NumCast(doc.x) - pwid / 10, right: NumCast(doc.x) + doc[WidthSym]() + pwid / 10, top: NumCast(doc.y) - phgt / 10, bot: NumCast(doc.y) + doc[HeightSym]() + phgt / 10 };
+ return {
+ px: cx + Math.min(0, bounds.left - screen.left) + Math.max(0, bounds.right - screen.right),
+ py: cy + Math.min(0, bounds.top - screen.top) + Math.max(0, bounds.bot - screen.bot)
+ };
}
- setScaleToZoom = (doc: Doc, scale: number = 0.75) => {
- const pw = this.isAnnotationOverlay ? Doc.NativeWidth(this.props.Document) : this.props.PanelWidth();
- const ph = this.isAnnotationOverlay ? Doc.NativeHeight(this.props.Document) : this.props.PanelHeight();
+ setZoomToDoc = (doc: Doc, scale: number = 0.75) => {
+ const pw = this.props.PanelWidth();
+ const ph = this.props.PanelHeight();
pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height)));
+ const pwid = pw / NumCast(this.props.Document._viewScale, 1);
+ const phgt = ph / NumCast(this.props.Document._viewScale, 1);
+ const bounds = { left: NumCast(doc.x) - pwid / 10, right: NumCast(doc.x) + doc[WidthSym]() + pwid / 10, top: NumCast(doc.y) - phgt / 10, bot: NumCast(doc.y) + doc[HeightSym]() + phgt / 10 };
+ return {
+ px: (bounds.left + bounds.right) / 2,
+ py: (bounds.top + bounds.bot) / 2
+ };
}
onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a5698e138..d20866f94 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -41,7 +41,6 @@ import { PresBox } from './PresBox';
import { RadialMenu } from './RadialMenu';
import React = require("react");
import { LinkDocPreview } from "./LinkDocPreview";
-import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment";
export type DocAfterFocusFunc = (notFocused: boolean) => boolean;
export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => void;
@@ -919,8 +918,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight());
contentsActive = () => this.docView?.contentsActive();
- focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, focused?: boolean) => {
- return this.docView?.focus(doc, willZoom, scale, afterFocus, focused);
+ focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => {
+ return this.docView?.focus(doc, willZoom, scale, afterFocus);
}
getBounds = () => {
if (!this.docView || !this.docView.ContentDiv || this.docView.props.renderDepth === 0 || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index d3d58b2f8..ef0df25b6 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -4,7 +4,7 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction
import { observer } from "mobx-react";
import { Dictionary } from "typescript-collections";
import * as WebRequest from 'web-request';
-import { Doc, DocListCast, HeightSym, WidthSym, Opt } from "../../../fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { HtmlField } from "../../../fields/HtmlField";
@@ -26,10 +26,10 @@ import { ViewBoxAnnotatableComponent } from "../DocComponent";
import { DocumentDecorations } from "../DocumentDecorations";
import { MarqueeAnnotator } from "../MarqueeAnnotator";
import { Annotation } from "../pdf/Annotation";
+import { DocAfterFocusFunc } from "./DocumentView";
import { FieldView, FieldViewProps } from './FieldView';
import "./WebBox.scss";
import React = require("react");
-import { DocFocusFunc, DocAfterFocusFunc, DocumentView } from "./DocumentView";
const htmlToText = require("html-to-text");
type WebDocument = makeInterface<[typeof documentSchema]>;