aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-06-09 10:39:14 -0400
committerbobzel <zzzman@gmail.com>2022-06-09 10:39:14 -0400
commitec2e780141fb41d3f70aa86b0312211e0b30257c (patch)
tree252ca5ecf456d4f333d5cb6844a16b2f987f6d58
parent8d78df55532b0044edd61ed379f6c469554805f2 (diff)
fixed issues with pinWithView so that thumnails show the pinned area and navigating to the view shows the entire pinned area regardless of panel size.
-rw-r--r--src/client/views/DocumentButtonBar.tsx29
-rw-r--r--src/client/views/collections/TabDocView.tsx33
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx1
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx20
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx8
6 files changed, 64 insertions, 37 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 103734b9b..41224b1c5 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -212,34 +212,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
@undoBatch
@action
- pinWithView = (targetDoc: Doc) => {
- const activeDoc = targetDoc && TabDocView.PinDoc(targetDoc);
- if (activeDoc) {
- const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking;
- const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG);
- if (scrollable) {
- const scroll = targetDoc._scrollTop;
- activeDoc.presPinView = true;
- activeDoc.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
- activeDoc.presPinView = true;
- activeDoc.presStartTime = targetDoc._currentTimecode;
- activeDoc.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
- } else if (pannable) {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeDoc.presPinView = true;
- activeDoc.presPinViewX = x;
- activeDoc.presPinViewY = y;
- activeDoc.presPinViewScale = scale;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const width = targetDoc._clipWidth;
- activeDoc.presPinClipWidth = width;
- activeDoc.presPinView = true;
- }
- }
- }
+ pinWithView = (targetDoc: Doc) => targetDoc && TabDocView.PinDoc(targetDoc, {pinDocView: true});
@computed
get pinWithViewButton() {
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 34fe572e3..f6a75e2db 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -227,6 +227,39 @@ export class TabDocView extends React.Component<TabDocViewProps> {
pinDoc.presPinViewX = viewProps.bounds.left + viewProps.bounds.width / 2;
pinDoc.presPinViewY = viewProps.bounds.top + viewProps.bounds.height / 2;
pinDoc.presPinViewScale = viewProps.scale;
+ pinDoc.contentBounds = new List<number>([viewProps.bounds.left, viewProps.bounds.top, viewProps.bounds.left+viewProps.bounds.width, viewProps.bounds.top+viewProps.bounds.height]);
+ }
+ if (pinProps?.pinDocView) {
+ const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(pinDoc.type as any) || pinDoc._viewType === CollectionViewType.Stacking;
+ const pannable: boolean = ((pinDoc.type === DocumentType.COL && doc._viewType === CollectionViewType.Freeform) || doc.type === DocumentType.IMG);
+ if (scrollable) {
+ const scroll = doc._scrollTop;
+ pinDoc.presPinView = true;
+ pinDoc.presPinViewScroll = scroll;
+ } else if ([DocumentType.AUDIO, DocumentType.VID].includes(doc.type as any)) {
+ pinDoc.presPinView = true;
+ pinDoc.presStartTime = doc._currentTimecode;
+ pinDoc.presEndTime = NumCast(doc._currentTimecode) + 0.1;
+ } else if (pannable) {
+ pinDoc.presPinView = true;
+ pinDoc.presPinViewX = pinDoc._panX;
+ pinDoc.presPinViewY = pinDoc._panY;
+ pinDoc.presPinViewScale = pinDoc._viewScale;
+ const pw = NumCast(pinProps.panelWidth);
+ const ph = NumCast(pinProps.panelHeight);
+ const ps = NumCast(pinDoc._viewScale);
+ if (pw && ph && ps) {
+ pinDoc.contentBounds = new List<number>([
+ NumCast(pinDoc.panX)-pw/2/ps,
+ NumCast(pinDoc.panY)-ph/2/ps,
+ NumCast(pinDoc.panX)+pw/2/ps,
+ NumCast(pinDoc.panY)+ph/2/ps]);
+ }
+ } else if (doc.type === DocumentType.COMPARISON) {
+ const width = doc._clipWidth;
+ pinDoc.presPinClipWidth = width;
+ pinDoc.presPinView = true;
+ }
}
Doc.AddDocToList(curPres, "data", pinDoc, presSelected);
if (!pinProps?.audioRange && duration !== undefined) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5f927a2a9..b70e6ff98 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -56,6 +56,7 @@ import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
import { FieldView, FieldViewProps } from "../../nodes/FieldView";
+import { TabDocView } from "../TabDocView";
export const panZoomSchema = createSchema({
_panX: "number",
@@ -138,7 +139,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
}
@computed get fitToContent() { return (this.props.fitContentsToDoc?.() || this.Document._fitToBox) && !this.isAnnotationOverlay; }
- @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)); }
+ @computed get contentBounds() {
+ const cb = Cast(this.rootDoc.contentBounds, listSpec("number"));
+ return cb ? {x:cb[0], y:cb[1], r:cb[2], b: cb[3]} :
+ this.props.contentBounds?.() ?? aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10));
+ }
@computed get nativeWidth() { return this.fitToContent ? 0 : Doc.NativeWidth(this.Document); }
@computed get nativeHeight() { return this.fitToContent ? 0 : Doc.NativeHeight(this.Document); }
@computed get cachedCenteringShiftX(): number {
@@ -1612,7 +1617,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
!Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
- appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
+ appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, {pinDocView:true, panelWidth: this.props.PanelWidth(), panelHeight:this.props.PanelHeight()}), icon: "map-pin" });
+ //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
this.props.ContainingCollectionView &&
appearanceItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" });
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 59a402e01..26dec3bd5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -112,6 +112,7 @@ export interface DocumentViewSharedProps {
renderDepth: number;
Document: Doc;
DataDoc?: Doc;
+ contentBounds?: () => (undefined|{x:number, y:number, r:number, b:number});
fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document
ContainingCollectionView: Opt<CollectionView>;
ContainingCollectionDoc: Opt<Doc>;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 591480023..6de04bd31 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -35,6 +35,9 @@ export interface PinProps {
setPosition?: boolean;
hidePresBox?: boolean;
pinWithView?: PinViewProps;
+ pinDocView?: boolean;
+ panelWidth?: number;
+ panelHeight?: number
}
export interface PinViewProps {
@@ -339,10 +342,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
} else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) {
bestTarget._currentTimecode = activeItem.presStartTime;
} else {
+ const contentBounds= Cast(activeItem.contentBounds, listSpec("number"));
bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
- bestTarget._panX = activeItem.presPinViewX;
- bestTarget._panY = activeItem.presPinViewY;
- bestTarget._viewScale = activeItem.presPinViewScale;
+ if (contentBounds) {
+ bestTarget._panX = (contentBounds[0] + contentBounds[2])/2;
+ bestTarget._panY = (contentBounds[1] + contentBounds[3])/2;
+ const dv = DocumentManager.Instance.getDocumentView(bestTarget);
+ if (dv) {
+ bestTarget._viewScale = Math.min(dv.props.PanelHeight() / (contentBounds[3] - contentBounds[1]),
+ dv.props.PanelWidth() / (contentBounds[2]- contentBounds[0]));
+ };
+ } else {
+ bestTarget._panX = activeItem.presPinViewX;
+ bestTarget._panY = activeItem.presPinViewY;
+ bestTarget._viewScale = activeItem.presPinViewScale;
+ }
}
this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
});
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index b9951eaae..5eff47a86 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "@material-ui/core";
import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, Opt } from "../../../../fields/Doc";
+import { Doc, DocListCast, Opt } from "../../../../fields/Doc";
import { Id } from "../../../../fields/FieldSymbols";
import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../../Utils";
@@ -13,6 +13,7 @@ import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager } from "../../../util/DragManager";
import { Transform } from "../../../util/Transform";
import { undoBatch } from "../../../util/UndoManager";
+import { CollectionViewType } from "../../collections/CollectionView";
import { ViewBoxBaseComponent } from '../../DocComponent';
import { EditableView } from "../../EditableView";
import { Colors } from "../../global/globalEnums";
@@ -23,7 +24,6 @@ import { PresBox } from "./PresBox";
import "./PresElementBox.scss";
import { PresMovement } from "./PresEnums";
import React = require("react");
-import { CollectionViewType } from "../../collections/CollectionView";
/**
* This class models the view a document added to presentation will have in the presentation.
* It involves some functionality for its buttons and options.
@@ -75,8 +75,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
<div className="presItem-embedded" style={{ height: this.embedHeight(), width: this.embedWidth() }}>
<DocumentView
- Document={this.targetDoc}
- DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
+ Document={this.rootDoc}
+ DataDoc={undefined}//this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
styleProvider={this.styleProvider}
docViewPath={returnEmptyDoclist}
rootSelected={returnTrue}