aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-12-14 02:01:57 -0500
committerbobzel <zzzman@gmail.com>2020-12-14 02:01:57 -0500
commit37d9d2cad93a08518cec6c95c8bc941dd5f5ddaa (patch)
tree25b4fee39aeb543333b87b2d03f7fb4645bad1c2 /src
parent257b259717486b984b90b75a8561b7b5c76a6964 (diff)
more changes to ContentScaling to get web/video/image boxes to work with annotation/DocDecorations in contentfitting and freeform views.
Diffstat (limited to 'src')
-rw-r--r--src/client/views/GlobalKeyHandler.ts11
-rw-r--r--src/client/views/StyleProvider.tsx12
-rw-r--r--src/client/views/collections/TabDocView.tsx2
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx3
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx164
-rw-r--r--src/client/views/nodes/ImageBox.tsx33
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx4
-rw-r--r--src/client/views/nodes/WebBox.tsx4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx2
13 files changed, 102 insertions, 143 deletions
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 283419b82..50a8e71f9 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -177,17 +177,10 @@ export class KeyManager {
const preventDefault = true;
switch (keyname) {
+ case "ƒ":
case "f":
const dv = SelectionManager.SelectedDocuments()?.[0];
- if (dv) {
- const ex = dv.props.ScreenToLocalTransform().inverse().transformPoint(0, 0)[0];
- const ey = dv.props.ScreenToLocalTransform().inverse().transformPoint(0, 0)[1];
- DocumentView.FloatDoc(dv, ex, ey);
- }
- // case "n":
- // let toggle = MainView.Instance.addMenuToggle.current!;
- // toggle.checked = !toggle.checked;
- // break;
+ dv && DocumentView.FloatDoc(dv);
}
return {
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 386e03f37..d22f34cd0 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -36,6 +36,7 @@ export enum StyleProp {
PointerEvents = "pointerEvents", // pointer events for DocumentView -- inherits pointer events if not specified
Decorations = "decorations", // additional decoration to display above a DocumentView -- currently only used to display a Lock for making things background
HeaderMargin = "headerMargin", // margin at top of documentview, typically for displaying a title -- doc contents will start below that
+ ShowTitle = "showTitle", // whether to display a title on a Document
}
function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); }
@@ -68,10 +69,16 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie
//
export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps | DocumentViewProps>, property: string): any {
const docProps = testDocProps(props);
+ const selected = property.includes(":selected");
switch (property.split(":")[0]) {
case StyleProp.DocContents: return undefined;
case StyleProp.WidgetColor: return darkScheme() ? "lightgrey" : "dimgrey";
case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null));
+ case StyleProp.HideLinkButton: return props?.dontRegisterView || (!selected && (doc?.isLinkButton || doc?.hideLinkButton));
+ case StyleProp.ShowTitle: return doc && !doc.presentationTargetDoc && StrCast(doc._showTitle,
+ !Doc.IsSystem(doc) && doc.type === DocumentType.RTF ?
+ (doc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") :
+ undefined);
case StyleProp.Color:
const backColor = props?.styleProvider?.(doc, props, StyleProp.BackgroundColor) || "black";
const col = Color(backColor).rgb();
@@ -132,15 +139,16 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps |
}
}
case StyleProp.PointerEvents:
+ if (props?.pointerEvents === "none") return "none";
const layer = doc && props?.layerProvider?.(doc);
if (props?.styleProvider?.(doc, props, StyleProp.Opacity) === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none";
- if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none";
+ if (layer === false && !selected && !SnappingManager.GetIsDragging()) return "none";
if (doc?.type !== DocumentType.INK && layer === true) return "all";
return undefined;
case StyleProp.Decorations:
if (props?.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform) {
const isBackground = StrListCast(doc?.layers).includes(StyleLayers.Background);
- return doc && (isBackground || property.includes(":selected")) && (props?.renderDepth || 0) > 0 &&
+ return doc && (isBackground || selected) && (props?.renderDepth || 0) > 0 &&
((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ?
<div className="styleProvider-lock" onClick={() => toggleBackground(doc)}>
<FontAwesomeIcon icon={isBackground ? "unlock" : "lock"} style={{ color: isBackground ? "red" : undefined }} size="lg" />
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 65b793adb..1f00b3a02 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -374,7 +374,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
@computed get docView() {
TraceMobx();
return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) :
- <><ContentFittingDocumentView key={this._document[Id]} ref={action((r: ContentFittingDocumentView) => console.log(this._view = r))}
+ <><ContentFittingDocumentView key={this._document[Id]} ref={action((r: ContentFittingDocumentView) => this._view = r)}
renderDepth={0}
Document={this._document}
DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index b31c1fcc1..9ecf3d0fb 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -110,7 +110,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
onLinkButtonUp = (e: PointerEvent): void => {
document.removeEventListener("pointermove", this.onLinkButtonMoved);
document.removeEventListener("pointerup", this.onLinkButtonUp);
- DocumentView.followLinkClick(this.props.linkDoc, this.props.sourceDoc, this.props.docView.props, false, false);
+ DocumentView.followLinkClick(this.props.linkDoc, this.props.sourceDoc, this.props.docView.props, false);
e.stopPropagation();
}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 0e790d8db..bfdb7d98e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -167,9 +167,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
PanelWidth: this.panelWidth,
PanelHeight: this.panelHeight
};
- if (this.props.Document.type === DocumentType.PDF) {
- console.log(divProps.NativeWidth?.());
- }
return <div className="collectionFreeFormDocumentView-container"
style={{
boxShadow,
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 396f3807f..5111fa041 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -4,7 +4,7 @@ import { observer } from "mobx-react";
import { Doc } from "../../../fields/Doc";
import { NumCast } from "../../../fields/Types";
import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, OmitKeys, returnVal } from "../../../Utils";
+import { emptyFunction, OmitKeys, returnVal, returnTrue } from "../../../Utils";
import { DocumentView, DocumentViewProps } from "../nodes/DocumentView";
import { StyleProp } from "../StyleProvider";
import "./ContentFittingDocumentView.scss";
@@ -70,12 +70,12 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp
}}>
<DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
ref={action((r: DocumentView | null) => this.docView = r)}
- LayoutTemplate={this.props.LayoutTemplate}
PanelWidth={this.PanelWidth}
PanelHeight={this.PanelHeight}
NativeWidth={this.NativeWidth}
NativeHeight={this.NativeHeight}
ContentScaling={this.NativeScaling}
+ contentFittingXf={returnTrue}
ScreenToLocalTransform={this.screenToLocalTransform}
focus={this.props.focus || emptyFunction}
bringToFront={emptyFunction}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d847eff00..460e5c2c6 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -4,14 +4,13 @@ import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, Field, Opt, S
import { Document } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
-import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from "../../../fields/Schema";
import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
import { MobileInterface } from '../../../mobile/MobileInterface';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
-import { emptyFunction, OmitKeys, returnFalse, returnOne, returnTrue, returnVal, Utils } from "../../../Utils";
+import { emptyFunction, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils";
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from '../../documents/DocumentTypes';
@@ -32,18 +31,18 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { DocComponent } from "../DocComponent";
import { EditableView } from '../EditableView';
import { InkStrokeProperties } from '../InkStrokeProperties';
+import { StyleLayers, StyleProp, testDocProps } from "../StyleProvider";
+import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
import { DocumentContentsView } from "./DocumentContentsView";
import { DocumentLinksButton } from './DocumentLinksButton';
import "./DocumentView.scss";
+import { FieldViewProps } from "./FieldView";
import { LinkAnchorBox } from './LinkAnchorBox';
import { LinkDescriptionPopup } from './LinkDescriptionPopup';
import { PresBox } from './PresBox';
import { RadialMenu } from './RadialMenu';
import { TaskCompletionBox } from './TaskCompletedBox';
import React = require("react");
-import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
-import { StyleProp, StyleLayers, testDocProps } from "../StyleProvider";
-import { FieldViewProps } from "./FieldView";
export type DocAfterFocusFunc = (notFocused: boolean) => boolean;
export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void;
@@ -52,8 +51,8 @@ export interface DocumentViewSharedProps {
renderDepth: number;
Document: Doc;
DataDoc?: Doc;
- ContainingCollectionView: Opt<CollectionView>;
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>;
CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView;
PanelWidth: () => number;
@@ -76,6 +75,7 @@ export interface DocumentViewSharedProps {
moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
pinToPres: (document: Doc) => void;
ScreenToLocalTransform: () => Transform;
+ contentFittingXf?: () => boolean; // bcz: need to figure out why this is needed in VideoBox/ImageBox/WebBox to turn off scaling...
bringToFront: (doc: Doc, sendToBack?: boolean) => void;
onClick?: () => ScriptField;
dropAction?: dropActionType;
@@ -124,14 +124,19 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
public get ContentDiv() { return this._mainCont.current; }
public get LayoutFieldKey() { return Doc.LayoutFieldKey(this.layoutDoc); }
- @computed get ShowTitle() {
- return StrCast(this.layoutDoc._showTitle,
- !Doc.IsSystem(this.layoutDoc) && this.rootDoc.type === DocumentType.RTF && !this.rootDoc.presentationTargetDoc ?
- (this.dataDoc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") :
- undefined);
- }
+ @computed get ShowTitle() { return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.ShowTitle) as (Opt<string>); }
@computed get LocalScaling() { return this.props.ContentScaling?.() || 1; }
@computed get topMost() { return this.props.renderDepth === 0; }
+ @computed get hidden() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Hidden); }
+ @computed get opacity() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Opacity); }
+ @computed get borderRounding() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow); }
+ @computed get hideLinkButton() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkButton + (this.isSelected() ? ":selected" : "")); }
+ @computed get widgetDecorations() { return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Decorations + (this.isSelected() ? ":selected" : "")); }
+ @computed get backgroundColor() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor); }
+ @computed get docContents() { return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.DocContents); }
+ @computed get headerMargin() { return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0; }
+ @computed get pointerEvents() { return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (this.isSelected() ? ":selected" : "")); }
+ @computed get finalLayoutKey() { return StrCast(this.props.Document.layoutKey, "layout"); }
@computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.dataDoc, this.props.freezeDimensions)); }
@computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.dataDoc, this.props.freezeDimensions)); }
@computed get onClickHandler() { return this.props.onClick?.() ?? Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); }
@@ -206,11 +211,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@action
componentDidMount() {
- this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this.props.Document));
- this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
- this._mainCont.current && (this._multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)));
- // this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this)));
-
+ this.componentDidUpdate();
if (!BoolCast(this.rootDoc.dontRegisterView, this.props.dontRegisterView)) {
DocumentManager.Instance.AddView(this);
}
@@ -237,9 +238,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._multiTouchDisposer?.();
this._holdDisposer?.();
Doc.UnBrushDoc(this.props.Document);
- if (!this.props.dontRegisterView) {
- DocumentManager.Instance.RemoveView(this);
- }
+ !this.props.dontRegisterView && DocumentManager.Instance.RemoveView(this);
}
startDragging(x: number, y: number, dropAction: dropActionType) {
@@ -257,13 +256,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@undoBatch @action
- public static FloatDoc(topDocView: DocumentView, x?: number, y?: number) {
- const topDoc = topDocView.props.Document;
- const container = topDocView.props.ContainingCollectionView;
- if (container) {
+ public static FloatDoc(topDocView: DocumentView) {
+ const { Document: topDoc, ContainingCollectionView: container } = topDocView.props;
+ const screenXf = container?.screenToLocalTransform();
+ if (screenXf) {
SelectionManager.DeselectAll();
- if (topDoc.z && (x === undefined && y === undefined)) {
- const spt = container.screenToLocalTransform().inverse().transformPoint(NumCast(topDoc.x), NumCast(topDoc.y));
+ if (topDoc.z) {
+ const spt = screenXf.inverse().transformPoint(NumCast(topDoc.x), NumCast(topDoc.y));
topDoc.z = 0;
topDoc.x = spt[0];
topDoc.y = spt[1];
@@ -271,7 +270,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
topDocView.props.addDocTab(topDoc, "inParent");
} else {
const spt = topDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
- const fpt = container.screenToLocalTransform().transformPoint(x !== undefined ? x : spt[0], y !== undefined ? y : spt[1]);
+ const fpt = screenXf.transformPoint(spt[0], spt[1]);
topDoc.z = 1;
topDoc.x = fpt[0];
topDoc.y = fpt[1];
@@ -281,28 +280,18 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
onKeyDown = (e: React.KeyboardEvent) => {
- if (this.rootDoc._singleLine && ((e.key === "Backspace" && this.dataDoc.text && !(this.dataDoc.text as RichTextField)?.Text) || ["Tab", "Enter"].includes(e.key))) {
- return;
- }
- if (e.altKey && !(e.nativeEvent as any).StopPropagationForReal) {
- (e.nativeEvent as any).StopPropagationForReal = true; // e.stopPropagation() doesn't seem to work...
+ if (e.altKey && !e.nativeEvent.cancelBubble) {
e.stopPropagation();
e.preventDefault();
if (e.key === "†" || e.key === "t") {
if (!StrCast(this.layoutDoc._showTitle)) this.layoutDoc._showTitle = "title";
if (!this._titleRef.current) setTimeout(() => this._titleRef.current?.setIsFocused(true), 0);
else if (!this._titleRef.current.setIsFocused(true)) { // if focus didn't change, focus on interior text...
- {
- this._titleRef.current?.setIsFocused(false);
- const any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any);
- any.keeplocation = true;
- any?.focus();
- }
+ this._titleRef.current?.setIsFocused(false);
+ const any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any);
+ any.keeplocation = true;
+ any?.focus();
}
- } else if (e.key === "f") {
- const ex = (e.nativeEvent.target! as any).getBoundingClientRect().left;
- const ey = (e.nativeEvent.target! as any).getBoundingClientRect().top;
- DocumentView.FloatDoc(this, ex, ey);
}
}
}
@@ -363,13 +352,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
} else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself
this.props.addDocTab(DocUtils.makeCustomViewClicked(Doc.MakeAlias(this.props.Document), undefined, "onClick"), "add:right");
} else if (this.allLinks && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) {
- this.allLinks.length && DocumentView.followLinkClick(undefined, this.props.Document, this.props, e.shiftKey, e.altKey);
+ this.allLinks.length && DocumentView.followLinkClick(undefined, this.props.Document, this.props, e.altKey);
} else {
if ((this.layoutDoc.onDragStart || this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0)) { // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template
} else {
this.select(e.ctrlKey || e.shiftKey);
- //SelectionManager.SelectDoc(this, e.ctrlKey || e.shiftKey);
}
preventDefault = false;
}
@@ -385,7 +373,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
focus: DocFocusFunc,
addDocTab: (doc: Doc, where: string) => boolean,
ContainingCollectionDoc?: Doc
- }, shiftKey: boolean, altKey: boolean) => {
+ }, altKey: boolean) => {
const batch = UndoManager.StartBatch("follow link click");
// open up target if it's not already in view ...
const createViewFunc = (doc: Doc, followLoc: string, finished: Opt<() => void>) => {
@@ -463,9 +451,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
public iconify() {
const layoutKey = Cast(this.props.Document.layoutKey, "string", null);
- const collapse = layoutKey !== "layout_icon";
- if (collapse) {
- this.switchViews(collapse, "icon");
+ if (layoutKey !== "layout_icon") {
+ this.switchViews(true, "icon");
if (layoutKey && layoutKey !== "layout" && layoutKey !== "layout_icon") this.props.Document.deiconifyLayout = layoutKey.replace("layout_", "");
} else {
const deiconifyLayout = Cast(this.props.Document.deiconifyLayout, "string", null);
@@ -668,10 +655,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
drop = async (e: Event, de: DragManager.DropEvent) => {
if (this.props.LayoutTemplateString) return;
if (this.props.Document === CurrentUserUtils.ActiveDashboard) {
- if ((e.target as any)?.closest?.("*.lm_content")) {
- alert("You can't perform this move most likely because you don't have permission to modify the destination.");
- }
- else alert("linking to document tabs not yet supported. Drop link on document content.");
+ alert((e.target as any)?.closest?.("*.lm_content") ?
+ "You can't perform this move most likely because you don't have permission to modify the destination." :
+ "linking to document tabs not yet supported. Drop link on document content.");
return;
}
const makeLink = action((linkDoc: Doc) => {
@@ -717,13 +703,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@undoBatch
- @action
toggleNativeDimensions = () => {
Doc.toggleNativeDimensions(this.layoutDoc, this.LocalScaling, this.props.PanelWidth(), this.props.PanelHeight());
}
@undoBatch
- @action
toggleLockPosition = (): void => {
this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true;
}
@@ -741,7 +725,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this.Document.isLinkButton = true;
}
-
@action
onCopy = () => {
const alias = Doc.MakeAlias(this.props.Document);
@@ -876,34 +859,20 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
});
}
- // does Document set a layout prop
- // does Document set a layout prop
- setsLayoutProp = (prop: string) => this.props.Document[prop] !== this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)] && this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)];
- // get the a layout prop by first choosing the prop from Document, then falling back to the layout doc otherwise.
- getLayoutPropStr = (prop: string) => StrCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]);
- getLayoutPropNum = (prop: string) => NumCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]);
-
isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction);
select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); };
-
- @computed get headerMargin() {
- return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0;
- }
-
- @computed get finalLayoutKey() {
- return StrCast(this.props.Document.layoutKey, "layout");
- }
rootSelected = (outsideReaction?: boolean) => {
return this.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false;
}
+
panelHeight = () => this.props.PanelHeight() - this.headerMargin;
- @computed.struct get linkOffset() { return this.topMost ? [0, undefined, undefined, 10] : [-15, undefined, undefined, -20]; }
- @observable contentsActive: () => boolean = returnFalse;
- @action setContentsActive = (setActive: () => boolean) => this.contentsActive = setActive;
parentActive = (outsideReaction: boolean) => this.props.layerProvider?.(this.layoutDoc) === false ? this.props.parentActive(outsideReaction) : false;
screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin);
contentScaling = () => !this.props.Document._fitWidth ? this.props.PanelWidth() / (this.props.NativeWidth?.() || this.props.PanelWidth()) : this.LocalScaling;
+ @observable contentsActive: () => boolean = returnFalse;
+ @action setContentsActive = (setActive: () => boolean) => this.contentsActive = setActive;
+
@computed get contents() {
TraceMobx();
return (<div className="documentView-contentsView"
@@ -922,6 +891,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
NativeHeight={this.NativeHeight}
PanelWidth={this.props.PanelWidth}
PanelHeight={this.props.PanelHeight}
+ contentFittingXf={this.props.contentFittingXf}
scaling={this.contentScaling}
layerProvider={this.props.layerProvider}
styleProvider={this.props.styleProvider}
@@ -952,8 +922,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onClick={this.onClickFunc}
layoutKey={this.finalLayoutKey} />
{this.layoutDoc.hideAllLinks ? (null) : this.allAnchors}
- {this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkButton) || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) :
- <DocumentLinksButton View={this} links={this.allLinks} Offset={this.linkOffset} />}
+ {this.hideLinkButton ? (null) : <DocumentLinksButton View={this} links={this.allLinks} Offset={this.topMost ? [0, undefined, undefined, 10] : [-15, undefined, undefined, -20]} />}
</div>
);
}
@@ -971,7 +940,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
makeLink = () => this._link; // pass the link placeholde to child views so they can react to make a specialized anchor. This is essentially a function call to the descendants since the value of the _link variable will immediately get set back to undefined.
@undoBatch
- hideLinkAnchor = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && (doc.hidden = true), true)
+ hideLinkAnchor = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && (doc.hidden = true), true)
anchorPanelWidth = () => this.props.PanelWidth() || 1;
anchorPanelHeight = () => this.props.PanelHeight() || 1;
anchorStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string): any => {
@@ -993,7 +962,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); }
@computed get allAnchors() {
TraceMobx();
- if (this.props.LayoutTemplateString?.includes("LinkAnchorBox")) return null;
+ if (this.props.LayoutTemplateString?.includes(LinkAnchorBox.name)) return null;
if (this.layoutDoc.presBox || // presentationbox nodes
this.rootDoc.type === DocumentType.LINK ||
this.props.dontRegisterView) {// view that are not registered
@@ -1020,6 +989,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@computed get innards() {
TraceMobx();
+ const showTitle = this.ShowTitle;
const showTitleHover = StrCast(this.layoutDoc._showTitleHover);
const showCaption = StrCast(this.layoutDoc._showCaption);
const captionView = (!showCaption ? (null) :
@@ -1036,7 +1006,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onClick={this.onClickFunc}
layoutKey={this.finalLayoutKey} />
</div>);
- const titleView = (!this.ShowTitle ? (null) :
+ const titleView = (!showTitle ? (null) :
<div className={`documentView-titleWrapper${showTitleHover ? "-hover" : ""}`} key="title" style={{
position: this.headerMargin ? "relative" : "absolute",
height: this.headerMargin || undefined,
@@ -1044,33 +1014,27 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : undefined,
}}>
<EditableView ref={this._titleRef}
- contents={this.ShowTitle === "title" ? StrCast((this.dataDoc || this.props.Document).title) : this.ShowTitle.split(";").map(field => field + ":" + (this.dataDoc || this.props.Document)[field]?.toString()).join(" ")}
+ contents={showTitle === "title" ? StrCast((this.dataDoc || this.props.Document).title) : showTitle.split(";").map(field => field + ":" + (this.dataDoc || this.props.Document)[field]?.toString()).join(" ")}
display={"block"}
fontSize={10}
- GetValue={() => Field.toString((this.dataDoc || this.props.Document)[this.ShowTitle.split(";")[0]] as any as Field)}
+ GetValue={() => Field.toString((this.dataDoc || this.props.Document)[showTitle.split(";")[0]] as any as Field)}
SetValue={undoBatch((value: string) => {
- this.ShowTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[this.ShowTitle] = value) ? true : true;
+ showTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[showTitle] = value) ? true : true;
})}
/>
</div>);
- return this.props.hideTitle || (!this.ShowTitle && !showCaption) ?
+ return this.props.hideTitle || (!showTitle && !showCaption) ?
this.contents :
<div className="documentView-styleWrapper" >
{!this.headerMargin ? <> {this.contents} {titleView} </> : <> {titleView} {this.contents} </>}
{captionView}
</div>;
}
- @computed get pointerEvents() {
- if (this.props.pointerEvents === "none") return "none";
- return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (this.isSelected() ? ":selected" : ""));
- }
@undoBatch
@action
setCustomView = (custom: boolean, layout: string): void => {
Doc.setNativeView(this.props.Document);
- if (custom) {
- DocUtils.makeCustomViewClicked(this.props.Document, Docs.Create.StackingDocument, layout, undefined);
- }
+ custom && DocUtils.makeCustomViewClicked(this.props.Document, Docs.Create.StackingDocument, layout, undefined);
}
switchViews = action((custom: boolean, view: string) => {
@@ -1084,15 +1048,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@computed get renderDoc() {
TraceMobx();
- if (!(this.props.Document instanceof Doc)) return (null);
- if (GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate) return (null);
- if (this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Hidden)) return null;
- return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.DocContents) ??
+ if (!(this.props.Document instanceof Doc) || GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate || this.hidden) return null;
+ return this.docContents ??
<div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
id={this.props.Document[Id]}
style={{
- background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
- opacity: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Opacity),
+ background: this.backgroundColor,
+ opacity: this.opacity,
color: StrCast(this.layoutDoc.color, "inherit"),
fontFamily: StrCast(this.Document._fontFamily, "inherit"),
fontSize: Cast(this.Document._fontSize, "string", null),
@@ -1102,11 +1064,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}}>
{this.innards}
{this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <div className="documentView-contentBlocker" /> : (null)}
- {this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Decorations + (this.isSelected() ? ":selected" : "")) || (null)}
+ {this.widgetDecorations ?? null}
</div>;
}
render() {
- const borderRounding = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow);
const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : 0) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
const highlightColor = (CurrentUserUtils.ActiveDashboard?.darkScheme ?
["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] :
@@ -1130,11 +1091,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
})}
style={{
pointerEvents: this.pointerEvents,
- outline: highlighting && !borderRounding ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : "solid 0px",
- border: highlighting && borderRounding && highlightStyle === "dashed" ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined,
- boxShadow: highlighting && borderRounding && highlightStyle !== "dashed" ? `0 0 0 ${highlightIndex}px ${highlightColor}` :
- this.Document.isLinkButton && !this.props.dontRegisterView && !this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkButton) ?
- StrCast(this.layoutDoc._linkButtonShadow, "lightblue 0em 0em 1em") :
+ outline: highlighting && !this.borderRounding ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : "solid 0px",
+ border: highlighting && this.borderRounding && highlightStyle === "dashed" ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined,
+ boxShadow: highlighting && this.borderRounding && highlightStyle !== "dashed" ? `0 0 0 ${highlightIndex}px ${highlightColor}` :
+ this.Document.isLinkButton && !this.hideLinkButton ? StrCast(this.layoutDoc._linkButtonShadow, "lightblue 0em 0em 1em") :
this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" :
undefined,
}}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 374f964e3..5fba273fb 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -67,7 +67,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
@observable static _showControls: boolean;
@observable uploadIcon = uploadIcons.idle;
- @computed get contentScaling() { return 1; }
+ @computed get contentScaling() { return this.props.contentFittingXf?.() ? 1 : this.props.scaling?.() || 1; }
protected createDropTarget = (ele: HTMLDivElement) => {
this._dropDisposer?.();
@@ -400,9 +400,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
(this.props.PanelHeight() - this.props.PanelWidth() * aspect) / 2 : 0;
}
- screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.ycenter / this.contentScaling);
-
+ scaling = () => this.contentScaling;
+ screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.ycenter).scale(1 / this.contentScaling);
contentFunc = () => [this.content];
+
render() {
TraceMobx();
return (<div className={`imageBox`} onContextMenu={this.specificContextMenu}
@@ -414,27 +415,27 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
borderRadius: `${Number(StrCast(this.layoutDoc.borderRounding).replace("px", "")) / this.contentScaling}px`
}} >
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
- forceScaling={true}
+ renderDepth={this.props.renderDepth + 1}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc}
+ CollectionView={undefined}
PanelHeight={this.props.PanelHeight}
+ scaling={this.scaling}
+ ScreenToLocalTransform={this.screenToLocalTransform}
PanelWidth={this.props.PanelWidth}
fieldKey={this.annotationKey}
isAnnotationOverlay={true}
+ docFilters={this.props.docFilters}
+ docRangeFilters={this.props.docRangeFilters}
+ searchFilterDocs={this.props.searchFilterDocs}
+ removeDocument={this.removeDocument}
+ moveDocument={this.moveDocument}
+ addDocument={this.addDocument}
+ forceScaling={true}
focus={this.props.focus}
isSelected={this.props.isSelected}
select={emptyFunction}
active={this.annotationsActive}
- ContentScaling={returnOne}
- whenActiveChanged={this.whenActiveChanged}
- removeDocument={this.removeDocument}
- moveDocument={this.moveDocument}
- addDocument={this.addDocument}
- CollectionView={undefined}
- ScreenToLocalTransform={this.screenToLocalTransform}
- renderDepth={this.props.renderDepth + 1}
- docFilters={this.props.docFilters}
- docRangeFilters={this.props.docRangeFilters}
- searchFilterDocs={this.props.searchFilterDocs}
- ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
+ whenActiveChanged={this.whenActiveChanged}>
{this.contentFunc}
</CollectionFreeFormView>
</div >);
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 456de7ede..4956b315d 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -177,7 +177,7 @@ export class ScreenshotBox extends ViewBoxBaseComponent<FieldViewProps, Screensh
isAnnotationOverlay={true}
select={emptyFunction}
active={returnFalse}
- ContentScaling={returnOne}
+ scaling={returnOne}
whenActiveChanged={emptyFunction}
removeDocument={returnFalse}
moveDocument={returnFalse}
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 06a305515..77db7189a 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -414,7 +414,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
return this.addDocument(doc);
}
- @computed get contentScaling() { return this.props.scaling?.() || 1; }
+ @computed get contentScaling() { return this.props.contentFittingXf?.() ? 1 : this.props.scaling?.() || 1; }
scaling = () => this.contentScaling;
screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.scaling());
contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content];
@@ -434,7 +434,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
isAnnotationOverlay={true}
select={emptyFunction}
active={this.annotationsActive}
- ContentScaling={this.scaling}
+ scaling={this.scaling}
ScreenToLocalTransform={this.screenToLocalTransform}
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 0fffdf693..3064de03b 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -647,7 +647,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
marqueeY = () => this._marqueeY;
marqueeing = () => this._marqueeing;
@computed get contentScaling() { return this.props.scaling?.() || 1; }
- scrollXf = () => this.props.ScreenToLocalTransform().scale(1 / this.contentScaling).translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
+ scrollXf = () => this.props.ScreenToLocalTransform().scale(this.props.contentFittingXf?.() ? 1 : 1 / this.contentScaling).translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop));
scaling = () => this.contentScaling;
render() {
return (<div className="webBox" ref={this._mainCont} >
@@ -700,7 +700,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
moveDocument={this.moveDocument}
addDocument={this.addDocument}
CollectionView={undefined}
- ContentScaling={this.scaling}
+ scaling={this.scaling}
ScreenToLocalTransform={this.scrollXf}
renderDepth={this.props.renderDepth + 1}>
</CollectionFreeFormView>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index c6036330d..584674a02 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1627,7 +1627,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
fitContentsToDoc: fitToBox,
select: emptyFunction,
active: this.annotationsActive,
- ContentScaling: this.sidebarContentScaling,
+ scaling: this.sidebarContentScaling,
whenActiveChanged: this.whenActiveChanged,
removeDocument: this.removeDocument,
moveDocument: this.moveDocument,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index d517dba1e..a80314f74 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -117,7 +117,7 @@ export class FormattedTextBoxComment {
textBox.props.addDocTab(linkDoc, e.ctrlKey ? "add" : "add:right");
} else {
const target = LinkManager.getOppositeAnchor(linkDoc, textBox.dataDoc);
- target && DocumentView.followLinkClick(linkDoc, textBox.dataDoc, textBox.props, e.shiftKey, e.altKey);
+ target && DocumentView.followLinkClick(linkDoc, textBox.dataDoc, textBox.props, e.altKey);
}
}
}