From 81ee0bf99da264b76f26a21d57259d478cac07f3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Dec 2020 11:58:25 -0500 Subject: fixed filterBox/TreeView to support checkboxes again. Simplified {DocumentView/CollectionView/FieldView}props --- src/client/documents/Documents.ts | 2 +- src/client/views/PreviewCursor.tsx | 5 +- .../views/collections/CollectionCarousel3DView.tsx | 4 +- .../views/collections/CollectionCarouselView.tsx | 4 +- .../collections/CollectionMasonryViewFieldRow.tsx | 2 +- .../views/collections/CollectionPileView.tsx | 6 +- .../views/collections/CollectionSchemaCells.tsx | 2 +- .../views/collections/CollectionSchemaHeaders.tsx | 3 - .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 12 ++-- .../CollectionStackingViewFieldColumn.tsx | 14 ++-- src/client/views/collections/CollectionSubView.tsx | 42 ++---------- .../views/collections/CollectionTimeView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 20 +++--- src/client/views/collections/CollectionView.tsx | 75 ++++++++++------------ src/client/views/collections/SchemaTable.tsx | 8 +-- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/collections/TreeView.scss | 4 ++ src/client/views/collections/TreeView.tsx | 24 +++---- .../CollectionFreeFormRemoteCursors.tsx | 8 +-- .../collectionFreeForm/CollectionFreeFormView.tsx | 24 +++---- .../collections/collectionFreeForm/MarqueeView.tsx | 28 ++++---- .../CollectionMulticolumnView.tsx | 6 +- .../CollectionMultirowView.tsx | 6 +- src/client/views/nodes/DocumentView.tsx | 71 ++++++++++---------- src/client/views/nodes/FieldView.tsx | 61 +++--------------- src/client/views/nodes/FilterBox.tsx | 8 +-- src/client/views/nodes/LinkBox.tsx | 4 +- src/client/views/nodes/PresBox.tsx | 4 +- src/client/views/nodes/VideoBox.tsx | 1 - 30 files changed, 189 insertions(+), 265 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ae0cd8b92..8a5f0fb5e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1136,7 +1136,7 @@ export namespace DocUtils { newDoc.x = x; newDoc.y = y; if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id]; - docAdder(newDoc); + docAdder?.(newDoc); } }), icon: "eye" diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index d756227f6..ac61dd1d8 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -11,6 +11,7 @@ import { Transform } from "../util/Transform"; import { undoBatch, UndoManager } from '../util/UndoManager'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import "./PreviewCursor.scss"; +import { returnFalse } from '../../Utils'; @observer export class PreviewCursor extends React.Component<{}> { @@ -145,13 +146,13 @@ export class PreviewCursor extends React.Component<{}> { onKeyPress: (e: KeyboardEvent) => void, addLiveText: (doc: Doc) => void, getTransform: () => Transform, - addDocument: (doc: Doc | Doc[]) => boolean, + addDocument: undefined | ((doc: Doc | Doc[]) => boolean), nudge: undefined | ((nudgeX: number, nudgeY: number) => boolean)) { this._clickPoint = [x, y]; this._onKeyPress = onKeyPress; this._addLiveTextDoc = addLiveText; this._getTransform = getTransform; - this._addDocument = addDocument; + this._addDocument = addDocument || returnFalse; this._nudge = nudge; this.Visible = true; } diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 4e30709a6..67f73d44a 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -46,8 +46,8 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume onDoubleClick={this.onChildDoubleClick} onClick={onChildClick} renderDepth={this.props.renderDepth + 1} - LayoutTemplate={this.props.ChildLayoutTemplate} - LayoutTemplateString={this.props.ChildLayoutString} + LayoutTemplate={this.props.childLayoutTemplate} + LayoutTemplateString={this.props.childLayoutString} Document={childPair.layout} DataDoc={childPair.data} PanelWidth={this.panelWidth} diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 16ccdc6f4..8b7a46e2f 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -53,8 +53,8 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) onDoubleClick={this.onContentDoubleClick} onClick={this.onContentClick} renderDepth={this.props.renderDepth + 1} - LayoutTemplate={this.props.ChildLayoutTemplate} - LayoutTemplateString={this.props.ChildLayoutString} + LayoutTemplate={this.props.childLayoutTemplate} + LayoutTemplateString={this.props.childLayoutString} Document={curDoc.layout} DataDoc={curDoc.data} PanelHeight={this.panelHeight} diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index b35644c6b..ff69c7d05 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -146,7 +146,7 @@ export class CollectionMasonryViewFieldRow extends React.Component { diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 2636b98e5..f054e7b7f 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -36,11 +36,11 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { { (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); - return this.props.addDocument(doc); + return this.props.addDocument?.(doc) || false; })} moveDocument={undoBatch((doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { (doc instanceof Doc ? [doc] : doc).map(undoBatch((d) => Doc.deiconifyView(d))); - return this.props.moveDocument(doc, targetCollection, addDoc); + return this.props.moveDocument?.(doc, targetCollection, addDoc) || false; })} /> ; } @@ -91,7 +91,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { const doc = this.childDocs[0]; doc.x = e.clientX; doc.y = e.clientY; - this.props.addDocTab(doc, "inParent") && this.props.removeDocument(doc); + this.props.addDocTab(doc, "inParent") && (this.props.removeDocument?.(doc) || false); dist = 0; } } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 0b3dfe1e4..904b4c761 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -44,7 +44,7 @@ export interface CellProps { renderDepth: number; addDocTab: (document: Doc, where: string) => boolean; pinToPres: (document: Doc) => void; - moveDocument: (document: Doc | Doc[], targetCollection: Doc | undefined, + moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; isFocused: boolean; changeFocusedCellByIndex: (row: number, col: number) => void; diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index b408fd680..f50da0134 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -461,9 +461,6 @@ export class KeysDropdown extends React.Component { } } - - get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } - @computed get scriptField() { const scriptText = "setDocFilter(containingTreeView, heading, this.title, checked)"; const script = ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name }); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 8ae70ce20..e22b8effe 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -484,7 +484,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { const cm = ContextMenu.Instance; const options = cm.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; - optionItems.push({ description: "remove", event: () => this._previewDoc && this.props.removeDocument(this._previewDoc), icon: "trash" }); + optionItems.push({ description: "remove", event: () => this._previewDoc && this.props.removeDocument?.(this._previewDoc), icon: "trash" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); cm.displayMenu(e.clientX, e.clientY); (e.nativeEvent as any).SchemaHandled = true; // not sure why this is needed, but if you right-click quickly on a cell, the Document/Collection contextMenu handlers still fire without this. diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 0e4029764..83ac138f5 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -152,7 +152,7 @@ export class CollectionStackingView extends CollectionSubView boolean): boolean => { - return this.props.removeDocument(doc) && addDocument(doc); + return this.props.removeDocument?.(doc) && addDocument?.(doc) ? true : false; } createRef = (ele: HTMLDivElement | null) => { this._masonryGridRef = ele; @@ -193,9 +193,9 @@ export class CollectionStackingView extends CollectionSubView { FormattedTextBox.SelectOnLoad = doc[Id]; - return this.props.parent.props.addDocument(doc); - }, this.props.parent.props.addDocument, x, y, true); + return this.props.parent.props.addDocument?.(doc) || false; + }, this.props.parent.props.addDocument || returnFalse, x, y, true); Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey => docItems.push({ @@ -249,7 +249,7 @@ export class CollectionStackingViewFieldColumn extends React.Component boolean; - removeDocument: (document: Doc | Doc[]) => boolean; - moveDocument: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; - PanelWidth: () => number; - PanelHeight: () => number; - VisibleHeight?: () => number; - setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; - rootSelected: (outsideReaction?: boolean) => boolean; - fieldKey: string; - NativeWidth?: () => number; - NativeHeight?: () => number; -} export interface SubCollectionViewProps extends CollectionViewProps { CollectionView: Opt; - children?: never | (() => JSX.Element[]) | React.ReactNode; - ChildLayoutTemplate?: () => Doc; - childOpacity?: () => number; - childIgnoreNativeSize?: boolean; - ChildLayoutString?: string; - childClickScript?: ScriptField; - childDoubleClickScript?: ScriptField; - freezeChildDimensions?: boolean; // used by TimeView to coerce documents to treat their width height as their native width/height - overrideDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) - ignoreFields?: string[]; // used in TreeView to ignore specified fields (see LinkBox) - parentActive: (outsideReaction: boolean) => boolean; - isAnnotationOverlay?: boolean; - annotationsKey: string; - layoutEngine?: () => string; } export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: X) { @@ -112,11 +84,11 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: return Cast(this.dataField, listSpec(Doc)); } docFilters = () => { - return this.props.ignoreFields?.includes("_docFilters") ? [] : + return this.props.ignoreFilters ? [] : [...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])]; } docRangeFilters = () => { - return this.props.ignoreFields?.includes("_docRangeFilters") ? [] : + return this.props.ignoreFilters ? [] : [...this.props.docRangeFilters(), ...Cast(this.props.Document._docRangeFilters, listSpec("string"), [])]; } searchFilterDocs = () => { @@ -220,7 +192,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: } } - addDocument = (doc: Doc | Doc[]) => this.props.addDocument(doc); + addDocument = (doc: Doc | Doc[]) => this.props.addDocument?.(doc) || false; @action protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { @@ -329,7 +301,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: DocServer.GetRefField(docid).then(f => { if (f instanceof Doc) { if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView - (f instanceof Doc) && this.props.addDocument(f); + (f instanceof Doc) && this.addDocument(f); } }); } else { @@ -343,7 +315,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const modHtml = srcUrl ? html.replace(reg, srcUrl) : html; const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: "-web page-", _width: 300, _height: 300 }); Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc).text = text; - this.props.addDocument(htmlDoc); + this.addDocument(htmlDoc); if (srcWeb) { const iframe = SelectionManager.SelectedDocuments()[0].ContentDiv?.getElementsByTagName("iframe")?.[0]; const focusNode = (iframe?.contentDocument?.getSelection()?.focusNode as any); @@ -503,7 +475,7 @@ import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DocumentType } from "../../documents/DocumentTypes"; import { FormattedTextBox, GoogleRef } from "../nodes/formattedText/FormattedTextBox"; -import { CollectionView, CollectionViewType } from "./CollectionView"; +import { CollectionView, CollectionViewType, CollectionViewProps } from "./CollectionView"; import { SelectionManager } from "../../util/SelectionManager"; import { OverlayView } from "../OverlayView"; import { setTimeout } from "timers"; diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index c2d682361..e4a3c384c 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -85,7 +85,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { @computed get contents() { return
- +
; } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 681584cc5..265f5a323 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -6,10 +6,11 @@ import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { Document } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../fields/Types'; +import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, Utils } from '../../../Utils'; +import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, Utils } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; +import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from "../../util/DragManager"; import { SelectionManager } from '../../util/SelectionManager'; import { SnappingManager } from '../../util/SnappingManager'; @@ -17,20 +18,17 @@ import { undoBatch, UndoManager } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { EditableView } from "../EditableView"; -import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; +import { DocumentView } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; -import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { TreeView } from "./TreeView"; import React = require("react"); -import { DocumentManager } from '../../util/DocumentManager'; -import { FormattedTextBoxComment } from '../nodes/formattedText/FormattedTextBoxComment'; -import { DocumentView } from '../nodes/DocumentView'; export type collectionTreeViewProps = { treeViewHideTitle?: boolean; treeViewHideHeaderFields?: boolean; + treeViewSkipFields?: string[]; // prevents specific fields from being displayed (see LinkBox) onCheckedClick?: () => ScriptField; onChildClick?: () => ScriptField; }; @@ -92,7 +90,7 @@ export class CollectionTreeView extends CollectionSubView doAddDoc(doc)); } else if (relativeTo === undefined) { - this.props.addDocument(doc); + this.props.addDocument?.(doc); } else { doAddDoc(doc); (doc instanceof Doc ? [doc] : doc).forEach(d => d.context = this.props.Document); @@ -195,18 +193,18 @@ export class CollectionTreeView extends CollectionSubView this.props.active(outsideReaction) || this._isChildActive; @computed get treeChildren() { TraceMobx(); - return this.props.overrideDocuments ? this.props.overrideDocuments : this.childDocs; + return this.props.childDocuments || this.childDocs; } @computed get treeViewElements() { TraceMobx(); const dropAction = StrCast(this.doc.childDropAction) as dropActionType; const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before); - const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(d, target, addDoc); + const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument?.(d, target, addDoc) || false; return TreeView.GetChildElements(this.treeChildren, this, this.doc, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove, moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.styleProvider, this.props.ScreenToLocalTransform, this.outerXf, this.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick, - this.onChildClick, this.props.ignoreFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.dontRegisterChildViews, "boolean", null)); + this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.dontRegisterChildViews, "boolean", null)); } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 8f402c427..af03e4ceb 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -10,7 +10,7 @@ import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; -import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx, normalizeEmail, denormalizeEmail } from '../../../fields/util'; +import { denormalizeEmail, distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; import { returnFalse, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -38,10 +38,7 @@ import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; -import { listSpec } from '../../../fields/Schema'; -const higflyout = require("@hig/flyout"); -export const { anchorPoints } = higflyout; -export const Flyout = higflyout.default; +import { ScriptField } from '../../../fields/ScriptField'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); @@ -64,28 +61,29 @@ export enum CollectionViewType { Grid = "grid", Pile = "pileup" } -export interface CollectionViewCustomProps { +export interface CollectionViewProps extends FieldViewProps { + isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) + annotationsKey: string; // which data field on the collection stores the collection of annotation documents + ignoreFilters?: boolean; + layoutEngine?: () => string; + parentActive: (outsideReaction: boolean) => boolean; filterAddDocument?: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) + VisibleHeight?: () => number; + setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; + + // property overrides for child documents + childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) childOpacity?: () => number; - hideFilter?: true; + childLayoutTemplate?: () => (Doc | undefined);// specify a layout Doc template to use for children of the collection + childLayoutString?: string; + children?: never | (() => JSX.Element[]) | React.ReactNode; + childFreezeDimensions?: boolean; // used by TimeView to coerce documents to treat their width height as their native width/height childIgnoreNativeSize?: boolean; + childClickScript?: ScriptField; + childDoubleClickScript?: ScriptField; } - -export interface CollectionRenderProps { - addDocument: (document: Doc | Doc[]) => boolean; - removeDocument: (document: Doc | Doc[]) => boolean; - moveDocument: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; - active: () => boolean; - parentActive: (outsideReaction: boolean) => boolean; - whenActiveChanged: (isActive: boolean) => void; - PanelWidth: () => number; - PanelHeight: () => number; - ChildLayoutTemplate?: () => Doc;// specify a layout Doc template to use for children of the collection - ChildLayoutString?: string;// specify a layout string to use for children of the collection -} - @observer -export class CollectionView extends Touchable { +export class CollectionView extends Touchable { public static LayoutString(fieldStr: string) { return FieldView.LayoutString(CollectionView, fieldStr); } _isChildActive = false; //TODO should this be observable? @@ -97,22 +95,13 @@ export class CollectionView extends Touchable([ - [AclPrivate, SharingPermissions.None], - [AclReadonly, SharingPermissions.View], - [AclAddonly, SharingPermissions.Add], - [AclEdit, SharingPermissions.Edit], - [AclAdmin, SharingPermissions.Admin] - ]); - get collectionViewType(): CollectionViewType | undefined { const viewField = StrCast(this.props.Document._viewType); if (CollectionView._safeMode) { - if (viewField === CollectionViewType.Freeform || viewField === CollectionViewType.Schema) { - return CollectionViewType.Tree; - } - if (viewField === CollectionViewType.Invalid) { - return CollectionViewType.Freeform; + switch (viewField) { + case CollectionViewType.Freeform: + case CollectionViewType.Schema: return CollectionViewType.Tree; + case CollectionViewType.Invalid: return CollectionViewType.Freeform; } } return viewField as any as CollectionViewType; @@ -136,7 +125,6 @@ export class CollectionView extends Touchable Doc.AreProtosEqual(doc, this.props.Document))) return false; const targetDataDoc = this.props.Document[DataSym]; const docList = DocListCast(targetDataDoc[this.props.fieldKey]); @@ -253,9 +241,8 @@ export class CollectionView extends Touchable this.props.renderDepth ? this.props.ScreenToLocalTransform() : this.props.ScreenToLocalTransform().scale(this.props.PanelWidth() / this.bodyPanelWidth()); - private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => { + private SubView = (type: CollectionViewType, props: SubCollectionViewProps) => { TraceMobx(); - const props: SubCollectionViewProps = { ...this.props, ...renderProps, ScreenToLocalTransform: this.screenToLocalTransform, CollectionView: this, annotationsKey: "" }; switch (type) { case CollectionViewType.Schema: return (); case CollectionViewType.Docking: return (); @@ -273,7 +260,7 @@ export class CollectionView extends Touchable); case CollectionViewType.Grid: return (); case CollectionViewType.Freeform: - default: { this.props.Document._freeformLayoutEngine = undefined; return (); } + default: { this.props.Document._freeformLayoutEngine = undefined; return (); } } } @@ -386,7 +373,8 @@ export class CollectionView extends Touchable; fieldKey: string; renderDepth: number; - deleteDocument: (document: Doc | Doc[]) => boolean; - addDocument: (document: Doc | Doc[]) => boolean; - moveDocument: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; + deleteDocument?: (document: Doc | Doc[]) => boolean; + addDocument?: (document: Doc | Doc[]) => boolean; + moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; ScreenToLocalTransform: () => Transform; active: (outsideReaction: boolean | undefined) => boolean; onDrop: (e: React.DragEvent, options: DocumentOptions, completed?: (() => void) | undefined) => void; @@ -376,7 +376,7 @@ export class SchemaTable extends React.Component { @undoBatch createRow = action(() => { - this.props.addDocument(Docs.Create.TextDocument("", { title: "", _width: 100, _height: 30 })); + this.props.addDocument?.(Docs.Create.TextDocument("", { title: "", _width: 100, _height: 30 })); this._focusedCell = { row: this.childDocs.length, col: this._focusedCell.col }; }); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index e1fd47592..3c1aaae47 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -339,7 +339,7 @@ export class TabDocView extends React.Component { ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} parentActive={returnFalse} - ChildLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this. + childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this. noOverlay={true} // don't render overlay Docs since they won't scale active={returnTrue} select={emptyFunction} diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 84b5af7be..0a97166f0 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -17,6 +17,10 @@ left: -10px; position: absolute; } + .treeView-checkIcon { + left: -10px; + position: absolute; + } &:hover { .treeView-expandIcon { display: unset; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 675ba60c0..be8a27ab0 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -49,7 +49,7 @@ export interface TreeViewProps { outdentDocument?: () => void; ScreenToLocalTransform: () => Transform; dontRegisterView?: boolean; - backgroundColor?: (doc: Opt, props: Opt, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => string | undefined; + backgroundColor?: (doc: Opt, props: DocumentViewProps, property: string) => string | undefined; outerXf: () => { translateX: number, translateY: number }; treeView: CollectionTreeView; parentKey: string; @@ -59,7 +59,7 @@ export interface TreeViewProps { renderedIds: string[]; // list of document ids rendered used to avoid unending expansion of items in a cycle onCheckedClick?: () => ScriptField; onChildClick?: () => ScriptField; - ignoreFields?: string[]; + skipFields?: string[]; firstLevel: boolean; whenActiveChanged: (isActive: boolean) => void; } @@ -311,7 +311,7 @@ export class TreeView extends React.Component { doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)); for (const key of Object.keys(ids).slice().sort()) { - if (this.props.ignoreFields?.includes(key) || key === "title" || key === "treeViewOpen") continue; + if (this.props.skipFields?.includes(key) || key === "title" || key === "treeViewOpen") continue; const contents = doc[key]; let contentElement: (JSX.Element | null)[] | JSX.Element = []; @@ -327,7 +327,7 @@ export class TreeView extends React.Component { this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, - [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.ignoreFields, false, this.props.whenActiveChanged, this.props.dontRegisterView); + [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView); } else { contentElement = { this.dataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, - [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.ignoreFields, false, this.props.whenActiveChanged, this.props.dontRegisterView)} + [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView)} ; } else if (this.treeViewExpandedView === "fields") { return
    @@ -449,14 +449,14 @@ export class TreeView extends React.Component { !(this.doc.text as RichTextField)?.Text ? (null) : :
    -
    - +
    - + {this.onCheckedClick ? (null) : }
    }
    ; @@ -710,7 +710,7 @@ export class TreeView extends React.Component { dropAction: dropActionType, addDocTab: (doc: Doc, where: string) => boolean, pinToPres: (document: Doc) => void, - backgroundColor: undefined | ((document: Opt, props: Opt, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => string | undefined), + styleProvider: undefined | ((document: Opt, props: DocumentViewProps, property: string) => string | undefined), screenToLocalXf: () => Transform, outerXf: () => { translateX: number, translateY: number }, active: (outsideReaction?: boolean) => boolean, @@ -722,7 +722,7 @@ export class TreeView extends React.Component { renderedIds: string[], onCheckedClick: undefined | (() => ScriptField), onChildClick: undefined | (() => ScriptField), - ignoreFields: string[] | undefined, + skipFields: string[] | undefined, firstLevel: boolean, whenActiveChanged: (isActive: boolean) => void, dontRegisterView: boolean | undefined) { @@ -783,7 +783,7 @@ export class TreeView extends React.Component { renderDepth={renderDepth} removeDoc={StrCast(containingCollection.freezeChildren).includes("remove") ? undefined : remove} addDocument={addDocument} - backgroundColor={backgroundColor} + backgroundColor={styleProvider} panelWidth={rowWidth} panelHeight={rowHeight} ChromeHeight={ChromeHeight} @@ -799,7 +799,7 @@ export class TreeView extends React.Component { treeViewHideHeaderFields={treeViewHideHeaderFields} treeViewPreventOpen={treeViewPreventOpen} renderedIds={renderedIds} - ignoreFields={ignoreFields} + skipFields={skipFields} firstLevel={firstLevel} whenActiveChanged={whenActiveChanged} />; }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx index 548ad78a5..9f6938e67 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx @@ -1,16 +1,16 @@ +import { computed } from "mobx"; import { observer } from "mobx-react"; import * as mobxUtils from 'mobx-utils'; import CursorField from "../../../../fields/CursorField"; +import { FieldResult } from "../../../../fields/Doc"; +import { List } from "../../../../fields/List"; import { listSpec } from "../../../../fields/Schema"; import { Cast } from "../../../../fields/Types"; import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; -import { CollectionViewProps } from "../CollectionSubView"; +import { CollectionViewProps } from "../CollectionView"; import "./CollectionFreeFormView.scss"; import React = require("react"); import v5 = require("uuid/v5"); -import { computed } from "mobx"; -import { FieldResult } from "../../../../fields/Doc"; -import { List } from "../../../../fields/List"; @observer export class CollectionFreeFormRemoteCursors extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 136600164..0f466fc16 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -158,11 +158,11 @@ export class CollectionFreeFormView extends CollectionSubView { let retVal = false; if (newBox instanceof Doc) { - retVal = this.props.addDocument(newBox); + retVal = this.props.addDocument?.(newBox) || false; retVal && this.bringToFront(newBox); retVal && this.updateCluster(newBox); } else { - retVal = this.props.addDocument(newBox); + retVal = this.props.addDocument?.(newBox) || false; // bcz: deal with clusters } if (retVal) { @@ -270,7 +270,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, property: string) => { + getClusterColor = (doc: Opt, props: DocumentViewProps, property: string) => { let clusterColor = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 if (property !== "backgroundColor") return clusterColor; const cluster = NumCast(doc?.cluster); @@ -510,7 +510,7 @@ export class CollectionFreeFormView extends CollectionSubView this.props.removeDocument(d)); + sel.forEach(d => this.props.removeDocument?.(d)); e.stopPropagation(); break; case GestureUtils.Gestures.StartBracket: @@ -999,9 +999,9 @@ export class CollectionFreeFormView extends CollectionSubView { const pt = this.getTransform().transformPoint(NumCast(doc.x), NumCast(doc.y)); doc.x = pt[0]; doc.y = pt[1]; }); - return this.props.addDocument(doc); + return this.props.addDocument?.(doc) || false; } } if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { @@ -1172,8 +1172,8 @@ export class CollectionFreeFormView extends CollectionSubView, bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica) })); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index a963b9158..39df606f7 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -8,7 +8,7 @@ import { RichTextField } from "../../../../fields/RichTextField"; import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types"; import { GetEffectiveAcl } from "../../../../fields/util"; -import { Utils, intersectRect } from "../../../../Utils"; +import { Utils, intersectRect, returnFalse } from "../../../../Utils"; import { CognitiveServices } from "../../../cognitive_services/CognitiveServices"; import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; @@ -93,7 +93,7 @@ export class MarqueeView extends React.Component { const indent = line.search(/\S|$/); const newBox = Docs.Create.TextDocument(line, { _width: 200, _height: 35, x: x + indent / 3 * 10, y: ypos, title: line }); - this.props.addDocument(newBox); + this.props.addDocument?.(newBox); ypos += 40 * this.Transform.Scale; }); })(); @@ -143,11 +143,11 @@ export class MarqueeView extends React.Component SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(slide)!, false)); e.stopPropagation(); } else if (!e.ctrlKey && !e.metaKey && SelectionManager.SelectedDocuments().length < 2) { - FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout && !this.props.ChildLayoutString ? e.key : ""; + FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout && !this.props.childLayoutString ? e.key : ""; FormattedTextBox.LiveTextUndo = UndoManager.StartBatch("live text batch"); this.props.addLiveTextDocument(CurrentUserUtils.GetNewTextDoc("-typed text-", x, y, 200, 100, this.props.xMargin === 0)); e.stopPropagation(); @@ -191,7 +191,7 @@ export class MarqueeView extends React.Component c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", _width: 300, _height: 100 }); - this.props.addDocument(newCol); + this.props.addDocument?.(newCol); } } @@ -333,7 +333,7 @@ export class MarqueeView extends React.Component { const selected = this.marqueeSelect(false); SelectionManager.DeselectAll(); - selected.forEach(doc => this.props.removeDocument(doc)); + selected.forEach(doc => this.props.removeDocument?.(doc)); this.cleanupInteractions(false); MarqueeOptionsMenu.Instance.fadeOut(true); @@ -363,9 +363,9 @@ export class MarqueeView extends React.Component { const selected = this.marqueeSelect(false); SelectionManager.DeselectAll(); - selected.forEach(d => this.props.removeDocument(d)); + selected.forEach(d => this.props.removeDocument?.(d)); const newCollection = DocUtils.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2); - this.props.addDocument(newCollection!); + this.props.addDocument?.(newCollection!); this.props.selectDocuments([newCollection!]); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); @@ -424,10 +424,10 @@ export class MarqueeView extends React.Component r.category === "line"); const text = lines.map((l: any) => l.recognizedText).join("\r\n"); - this.props.addDocument(Docs.Create.TextDocument(text, { _width: this.Bounds.width, _height: this.Bounds.height, x: this.Bounds.left + this.Bounds.width, y: this.Bounds.top, title: text })); + this.props.addDocument?.(Docs.Create.TextDocument(text, { _width: this.Bounds.width, _height: this.Bounds.height, x: this.Bounds.left + this.Bounds.width, y: this.Bounds.top, title: text })); }); } } @@ -503,7 +503,7 @@ export class MarqueeView extends React.Component { const selected = this.marqueeSelect(false).map(d => { - this.props.removeDocument(d); + this.props.removeDocument?.(d); d.x = NumCast(d.x) - this.Bounds.left; d.y = NumCast(d.y) - this.Bounds.top; return d; @@ -524,7 +524,7 @@ export class MarqueeView extends React.Component { const newCollection = this.getCollection([], undefined, ["background"]); - this.props.addDocument(newCollection); + this.props.addDocument?.(newCollection); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); setTimeout(() => this.props.selectDocuments([newCollection])); diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 7ce269c92..586c5d1df 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -217,9 +217,9 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu Document={layout} DataDoc={layout.resolvedDataDoc as Doc} styleProvider={this.props.styleProvider} - LayoutTemplate={this.props.ChildLayoutTemplate} - LayoutTemplateString={this.props.ChildLayoutString} - FreezeDimensions={this.props.freezeChildDimensions} + LayoutTemplate={this.props.childLayoutTemplate} + LayoutTemplateString={this.props.childLayoutString} + FreezeDimensions={this.props.childFreezeDimensions} renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 7700ea128..87c56de6f 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -217,9 +217,9 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) Document={layout} DataDoc={layout.resolvedDataDoc as Doc} styleProvider={this.props.styleProvider} - LayoutTemplate={this.props.ChildLayoutTemplate} - LayoutTemplateString={this.props.ChildLayoutString} - FreezeDimensions={this.props.freezeChildDimensions} + LayoutTemplate={this.props.childLayoutTemplate} + LayoutTemplateString={this.props.childLayoutString} + FreezeDimensions={this.props.childFreezeDimensions} renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5ed49185b..dc048843f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -45,57 +45,60 @@ import React = require("react"); export type DocAfterFocusFunc = (notFocused: boolean) => boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; -export interface DocumentViewProps { +export interface DocumentViewSharedProps { ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; - docFilters: () => string[]; + Document: Doc; + DataDoc?: Doc; contentsActive?: (setActive: () => boolean) => void; + onClick?: () => ScriptField; + dropAction?: dropActionType; + backgroundHalo?: (doc: Doc) => boolean; + docFilters: () => string[]; docRangeFilters: () => string[]; searchFilterDocs: () => Doc[]; - FreezeDimensions?: boolean; + rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected + renderDepth: number; + addDocTab: (doc: Doc, where: string) => boolean; + addDocument?: (doc: Doc | Doc[]) => boolean; + removeDocument?: (doc: Doc | Doc[]) => boolean; + moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; + pinToPres: (document: Doc) => void; + layerProvider?: (doc: Doc, assign?: boolean) => boolean; + styleProvider?: (doc: Opt, props: DocumentViewProps, property: string) => any; + ScreenToLocalTransform: () => Transform; + bringToFront: (doc: Doc, sendToBack?: boolean) => void; + parentActive: (outsideReaction: boolean) => boolean; + whenActiveChanged: (isActive: boolean) => void; + LayoutTemplateString?: string; + dontRegisterView?: boolean; + focus: DocFocusFunc; + ignoreAutoHeight?: boolean; + PanelWidth: () => number; + PanelHeight: () => number; NativeWidth?: () => number; NativeHeight?: () => number; - Document: Doc; - DataDoc?: Doc; - layerProvider?: (doc: Doc, assign?: boolean) => boolean; + ContentScaling: () => number; + ChromeHeight?: () => number; + pointerEvents?: string; +} +export interface DocumentViewProps extends DocumentViewSharedProps { + // properties specific to DocumentViews but not to FieldView + FreezeDimensions?: boolean; + fitToBox?: boolean; + treeViewDoc?: Doc; + dragDivName?: string; + contentsPointerEvents?: string; getView?: (view: DocumentView) => any; - LayoutTemplateString?: string; LayoutTemplate?: () => Opt; - fitToBox?: boolean; - ignoreAutoHeight?: boolean; contextMenuItems?: () => { script: ScriptField, label: string }[]; - rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected - onClick?: () => ScriptField; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; onPointerUp?: () => ScriptField; - treeViewDoc?: Doc; - dropAction?: dropActionType; - dragDivName?: string; nudge?: (x: number, y: number) => void; - addDocument?: (doc: Doc | Doc[]) => boolean; - removeDocument?: (doc: Doc | Doc[]) => boolean; - moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; - ScreenToLocalTransform: () => Transform; setupDragLines?: (snapToDraggedDoc: boolean) => void; - renderDepth: number; - ContentScaling: () => number; - PanelWidth: () => number; - PanelHeight: () => number; - pointerEvents?: string; - contentsPointerEvents?: string; - focus: DocFocusFunc; - parentActive: (outsideReaction: boolean) => boolean; - whenActiveChanged: (isActive: boolean) => void; - bringToFront: (doc: Doc, sendToBack?: boolean) => void; - addDocTab: (doc: Doc, where: string) => boolean; - pinToPres: (document: Doc) => void; - backgroundHalo?: (doc: Doc) => boolean; - styleProvider?: (doc: Opt, props: DocumentViewProps, property: string) => any; forceHideLinkButton?: () => boolean; opacity?: () => number | undefined; - ChromeHeight?: () => number; - dontRegisterView?: boolean; layoutKey?: string; radialMenu?: String[]; display?: string; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 5cd752fdb..1d58893ae 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -2,70 +2,29 @@ import React = require("react"); import { computed } from "mobx"; import { observer } from "mobx-react"; import { DateField } from "../../../fields/DateField"; -import { Doc, FieldResult, Opt, Field } from "../../../fields/Doc"; +import { Doc, Field, FieldResult, Opt } from "../../../fields/Doc"; import { List } from "../../../fields/List"; -import { ScriptField } from "../../../fields/ScriptField"; -import { AudioField, VideoField, WebField } from "../../../fields/URLField"; -import { Transform } from "../../util/Transform"; -import { CollectionView } from "../collections/CollectionView"; -import { AudioBox } from "./AudioBox"; +import { VideoField, WebField } from "../../../fields/URLField"; +import { DocumentViewSharedProps } from "./DocumentView"; import { VideoBox } from "./VideoBox"; -import { dropActionType } from "../../util/DragManager"; -import { DocAfterFocusFunc, DocFocusFunc, DocumentViewProps } from "./DocumentView"; // // these properties get assigned through the render() method of the DocumentView when it creates this node. // However, that only happens because the properties are "defined" in the markup for the field view. // See the LayoutString method on each field view : ImageBox, FormattedTextBox, etc. // -export interface FieldViewProps { +export interface FieldViewProps extends DocumentViewSharedProps { + // FieldView specific props that are not part of DocumentView props fieldKey: string; fitToBox?: boolean; - ContainingCollectionView: Opt; - ContainingCollectionDoc: Opt; - Document: Doc; - DataDoc?: Doc; - layerProvider?: (doc: Doc, assign?: boolean) => boolean; - contentsActive?: (setActive: () => boolean) => void; - onClick?: () => ScriptField; - dropAction: dropActionType; - backgroundHalo?: () => boolean; - docFilters: () => string[]; - docRangeFilters: () => string[]; - searchFilterDocs: () => Doc[]; - isSelected: (outsideReaction?: boolean) => boolean; - select: (isCtrlPressed: boolean) => void; - rootSelected: (outsideReaction?: boolean) => boolean; - renderDepth: number; - addDocument?: (document: Doc | Doc[]) => boolean; - addDocTab: (document: Doc, where: string) => boolean; - pinToPres: (document: Doc) => void; - removeDocument?: (document: Doc | Doc[]) => boolean; - moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; - styleProvider?: (document: Opt, props: Opt, property: string) => any; - ScreenToLocalTransform: () => Transform; - bringToFront: (doc: Doc, sendToBack?: boolean) => void; - parentActive: (outsideReaction: boolean) => boolean; + overflow?: boolean; // bcz: would like to think this can be avoided -- need to look at further active: (outsideReaction?: boolean) => boolean; - whenActiveChanged: (isActive: boolean) => void; - LayoutTemplateString?: string; - dontRegisterView?: boolean; - focus: DocFocusFunc; - presMultiSelect?: (doc: Doc) => void; //added for selecting multiple documents in a presentation - ignoreAutoHeight?: boolean; - PanelWidth: () => number; - PanelHeight: () => number; - PanelPosition?: string; - overflow?: boolean; - NativeHeight?: () => number; - NativeWidth?: () => number; - setVideoBox?: (player: VideoBox) => void; - ContentScaling: () => number; - ChromeHeight?: () => number; - childLayoutTemplate?: () => Opt; + select: (isCtrlPressed: boolean) => void; + isSelected: (outsideReaction?: boolean) => boolean; + // properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React) - fontSize?: number; pointerEvents?: string; + fontSize?: number; height?: number; width?: number; background?: string; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 0161f51fd..b90bf9eb1 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -9,7 +9,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; import { Cast } from "../../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnZero } from "../../../Utils"; +import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnZero, returnTrue } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { CollectionDockingView } from "../collections/CollectionDockingView"; @@ -153,7 +153,6 @@ export class FilterBox extends ViewBoxBaseComponent "rgba(105, 105, 105, 0.432)"; - get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves) @computed get scriptField() { const scriptText = "setDocFilter(this?.target, heading, this.title, checked)"; const script = ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name }); @@ -181,7 +180,6 @@ export class FilterBox extends ViewBoxBaseComponent
    (
    {mode !== CollectionViewType.Invalid ? removeDocument={returnFalse} dontRegisterView={true} focus={this.selectElement} - ScreenToLocalTransform={this.getTransform} /> + ScreenToLocalTransform={this.getTransform} + /> : (null) }
    diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 998ca839d..f64d80731 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -183,7 +183,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.Document._videoStart, (videoStart) => { -- cgit v1.2.3-70-g09d2 From 30338491c7b3cbba852931c76774f6bfd44d4060 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Dec 2020 12:54:41 -0500 Subject: removed annotationsKey prop in favor of reusing fieldKey. Fixed web pages to allow dash annotations again. --- src/client/views/MainView.tsx | 1 - src/client/views/TemplateMenu.tsx | 1 - src/client/views/collections/CollectionStackingView.tsx | 4 ++-- src/client/views/collections/CollectionSubView.tsx | 14 ++++++-------- src/client/views/collections/CollectionView.tsx | 5 +---- src/client/views/collections/TabDocView.tsx | 1 - .../collectionFreeForm/CollectionFreeFormView.tsx | 11 +++++------ .../views/collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 2 -- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/LinkBox.tsx | 1 - src/client/views/nodes/PresBox.tsx | 1 - src/client/views/nodes/ScreenshotBox.tsx | 1 - src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/nodes/WebBox.scss | 4 +++- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 13 ++++++++----- src/client/views/pdf/PDFViewer.tsx | 4 ++-- src/client/views/search/SearchBox.tsx | 1 - 19 files changed, 31 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 9b3d5c6ae..2705d2c34 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -456,7 +456,6 @@ export class MainView extends React.Component { DataDoc={undefined} fieldKey={"data"} dropAction={"alias"} - annotationsKey={""} parentActive={returnFalse} styleProvider={TabDocView.styleProvider} rootSelected={returnTrue} diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 9c5c70c60..203274681 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -152,7 +152,6 @@ export class TemplateMenu extends React.Component { PanelWidth={this.return100} PanelHeight={this.return100} treeViewHideHeaderFields={true} - annotationsKey={""} dontRegisterView={true} fieldKey={"data"} moveDocument={returnFalse} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 83ac138f5..058536f69 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -352,8 +352,8 @@ export class CollectionStackingView extends CollectionSubView { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { const height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => NumCast(Doc.Layout(doc)._viewScale, 1) * Number(getComputedStyle(r).height.replace("px", ""))))); - if (this.props.annotationsKey) { - doc[this.props.annotationsKey + "-height"] = height; + if (this.props.isAnnotationOverlay) { + doc[this.props.fieldKey + "-height"] = height; } else { Doc.Layout(doc)._height = height * NumCast(Doc.Layout(doc)._viewScale, 1); } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 592d6ab87..38e461e46 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -67,14 +67,14 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: // sets the dataDoc's data field to an empty list if the data field is undefined - prevents issues with addonly // setTimeout changes it outside of the @computed section setTimeout(() => { - if (!this.dataDoc[this.props.annotationsKey || this.props.fieldKey]) this.dataDoc[this.props.annotationsKey || this.props.fieldKey] = new List(); + if (!this.dataDoc[this.props.fieldKey]) this.dataDoc[this.props.fieldKey] = new List(); }, 1000); - return this.dataDoc[this.props.annotationsKey || this.props.fieldKey]; + return this.dataDoc[this.props.fieldKey]; } get childLayoutPairs(): { layout: Doc; data: Doc; }[] { const { Document, DataDoc } = this.props; - const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.annotationsKey ? DataDoc : undefined, doc)). + const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.isAnnotationOverlay ? DataDoc : undefined, doc)). filter(pair => { // filter out any documents that have a proto that we don't have permissions to (which we determine by not having any keys return pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); }); @@ -84,12 +84,10 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: return Cast(this.dataField, listSpec(Doc)); } docFilters = () => { - return this.props.ignoreFilters ? [] : - [...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])]; + return [...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])]; } docRangeFilters = () => { - return this.props.ignoreFilters ? [] : - [...this.props.docRangeFilters(), ...Cast(this.props.Document._docRangeFilters, listSpec("string"), [])]; + return [...this.props.docRangeFilters(), ...Cast(this.props.Document._docRangeFilters, listSpec("string"), [])]; } searchFilterDocs = () => { return [...this.props.searchFilterDocs(), ...DocListCast(this.props.Document._searchFilterDocs)]; @@ -104,7 +102,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: // For example, if an image doc is rendered with a slide template, the template will try to render the data field as a collection. // Since the data field is actually an image, we set the list of documents to the singleton of root document's proto which will be an image. const rootDoc = Cast(this.props.Document.rootDocument, Doc, null); - rawdocs = rootDoc && !this.props.annotationsKey ? [Doc.GetProto(rootDoc)] : []; + rawdocs = rootDoc && !this.props.isAnnotationOverlay ? [Doc.GetProto(rootDoc)] : []; } const docs = rawdocs.filter(d => !(d instanceof Promise) && GetEffectiveAcl(Doc.GetProto(d)) !== AclPrivate).map(d => d as Doc); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index af03e4ceb..511fc723d 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -63,8 +63,6 @@ export enum CollectionViewType { } export interface CollectionViewProps extends FieldViewProps { isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) - annotationsKey: string; // which data field on the collection stores the collection of annotation documents - ignoreFilters?: boolean; layoutEngine?: () => string; parentActive: (outsideReaction: boolean) => boolean; filterAddDocument?: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) @@ -72,11 +70,11 @@ export interface CollectionViewProps extends FieldViewProps { setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; // property overrides for child documents + children?: never | (() => JSX.Element[]) | React.ReactNode; childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) childOpacity?: () => number; childLayoutTemplate?: () => (Doc | undefined);// specify a layout Doc template to use for children of the collection childLayoutString?: string; - children?: never | (() => JSX.Element[]) | React.ReactNode; childFreezeDimensions?: boolean; // used by TimeView to coerce documents to treat their width height as their native width/height childIgnoreNativeSize?: boolean; childClickScript?: ScriptField; @@ -387,7 +385,6 @@ export class CollectionView extends Touchable { childLayoutString: this.childLayoutString, ScreenToLocalTransform: this.screenToLocalTransform, CollectionView: this, - annotationsKey: "" }; const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.treeViewOutlineMode || this.collectionViewType === CollectionViewType.Linear ? undefined : this.props.styleProvider?.(this.props.Document, this.props, "boxShadow"); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 3c1aaae47..fd50c6273 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -346,7 +346,6 @@ export class TabDocView extends React.Component { dropAction={undefined} isSelected={returnFalse} dontRegisterView={true} - annotationsKey={""} fieldKey={Doc.LayoutFieldKey(this._document!)} bringToFront={emptyFunction} rootSelected={returnTrue} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0f466fc16..e09abd017 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -47,7 +47,6 @@ import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; -import { isUndefined } from "lodash"; export const panZoomSchema = createSchema({ _panX: "number", @@ -950,7 +949,7 @@ export class CollectionFreeFormView extends CollectionSubView this.doLayoutComputation, (elements) => this._layoutElements = elements || [], { fireImmediately: true, name: "doLayout" }); - if (!this.props.annotationsKey) { + if (!this.props.isAnnotationOverlay) { this._boundsReaction = reaction(() => this.contentBounds, bounds => (!this.fitToContent && this._layoutElements?.length) && setTimeout(() => { const rbounds = Cast(this.Document._renderContentBounds, listSpec("number"), [0, 0, 0, 0]); @@ -1291,7 +1290,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.props.annotationsKey || this.props.Document.annotationOn || !ContextMenu.Instance) return; + if (this.props.isAnnotationOverlay || this.props.Document.annotationOn || !ContextMenu.Instance) return; const appearance = ContextMenu.Instance.findByDescription("Appearance..."); const appearanceItems = appearance && "subitems" in appearance ? appearance.subitems : []; @@ -1527,7 +1526,7 @@ export class CollectionFreeFormView extends CollectionSubView - {this.Document._freeformLOD && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? + {this.Document._freeformLOD && !this.props.active() && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 ? this.placeholder : this.marqueeView} {!this.props.noOverlay ? : (null)} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 39df606f7..52310d628 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -634,7 +634,7 @@ export class MarqueeView extends React.Component e.preventDefault()} onScroll={(e) => e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0} onClick={this.onClick} onPointerDown={this.onPointerDown}> {this._visible ? this.marqueeDiv : null} diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index b90bf9eb1..ffe1684d4 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -208,8 +208,6 @@ export class FilterBox extends ViewBoxBaseComponent( ChromeHeight={returnZero} childDocuments={[this.dataDoc]} treeViewSkipFields={Cast(this.props.Document.linkBoxExcludedKeys, listSpec("string"), null)} - annotationsKey={""} dontRegisterView={true} renderDepth={this.props.renderDepth + 1} CollectionView={undefined} diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index c2385cab8..da74edbe3 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -2412,7 +2412,6 @@ export class PresBox extends ViewBoxBaseComponent
    {mode !== CollectionViewType.Invalid ? Opt; // bcz: hack: notifies the text document when the container has made a link. allows the text doc to react and setup a hyeprlink for any selected text @@ -1606,7 +1607,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp sidebarContentScaling = () => this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); @computed get sidebarCollection() { const fitToBox = this.props.Document._fitToBox; - const collectionProps = { + const collectionProps: SubCollectionViewProps & collectionFreeformViewProps = { ...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit, NativeWidth: returnZero, NativeHeight: returnZero, @@ -1616,8 +1617,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp yMargin: 0, chromeStatus: "enabled", scaleField: this.annotationKey + "-scale", - annotationsKey: this.annotationKey, isAnnotationOverlay: true, + fieldKey: this.annotationKey, fitToBox: fitToBox, focus: this.props.focus, isSelected: this.props.isSelected, @@ -1636,7 +1637,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) :
    - {this.layoutDoc.sidebarViewType === CollectionViewType.Freeform ? : } + {this.layoutDoc.sidebarViewType === CollectionViewType.Freeform ? + : + }
    ; } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 9b689eb6b..633a34c5e 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -736,7 +736,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent Date: Thu, 10 Dec 2020 14:18:53 -0500 Subject: more cleanup/organization of 'props' . removed VisibleHeight props and cleaned up PDF and other props --- src/client/util/CurrentUserUtils.ts | 1 - .../util/Import & Export/DirectoryImportBox.tsx | 1 - src/client/views/PropertiesView.tsx | 2 +- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 21 +++-- .../views/collections/CollectionTimeView.tsx | 7 +- src/client/views/collections/CollectionView.tsx | 36 ++++---- src/client/views/collections/SchemaTable.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 16 ++-- .../collectionGrid/CollectionGridView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 2 +- .../CollectionMultirowView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- .../views/nodes/ContentFittingDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/KeyValueBox.tsx | 1 - src/client/views/nodes/PDFBox.tsx | 96 +++++----------------- src/client/views/nodes/VideoBox.tsx | 11 +-- src/client/views/nodes/WebBox.tsx | 19 +---- .../views/nodes/formattedText/FormattedTextBox.tsx | 3 - src/client/views/pdf/PDFViewer.tsx | 50 +++-------- src/fields/documentSchemas.ts | 2 - 22 files changed, 84 insertions(+), 200 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 213bc3d88..676e7ce3e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -801,7 +801,6 @@ export class CurrentUserUtils { } } - static setupUserDoc(doc: Doc) { if (doc.myUserDoc === undefined) { doc.treeViewOpen = true; diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 7f01966b9..d9f010557 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -158,7 +158,6 @@ export class DirectoryImportBox extends React.Component { importContainer = Docs.Create.SchemaDocument(headers, docs, options); } runInAction(() => this.phase = 'External: uploading files to Google Photos...'); - importContainer._columnsStack = false; await GooglePhotos.Export.CollectionToAlbum({ collection: importContainer }); Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer); !this.persistent && this.props.removeDocument && this.props.removeDocument(doc); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 08394cd97..233429f4d 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -272,7 +272,7 @@ export class PropertiesView extends React.Component { treeViewDoc={undefined} styleProvider={this.props.styleProvider} fitToBox={true} - FreezeDimensions={true} + freezeDimensions={true} dontCenter={"y"} NativeWidth={layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} NativeHeight={layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined} diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index e22b8effe..c64048345 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -401,7 +401,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { Document={this.previewDocument} DataDoc={undefined} fitToBox={true} - FreezeDimensions={true} + freezeDimensions={true} dontCenter={"y"} focus={emptyFunction} renderDepth={this.props.renderDepth} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 058536f69..b1c5dec84 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -3,7 +3,6 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { CursorProperty } from "csstype"; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import Switch from 'rc-switch'; import { DataSym, Doc, HeightSym, WidthSym } from "../../../fields/Doc"; import { collectionSchema, documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; @@ -12,23 +11,23 @@ import { listSpec, makeInterface } from "../../../fields/Schema"; import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, smoothScroll, returnVal } from "../../../Utils"; +import { emptyFunction, returnFalse, returnOne, returnVal, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils"; +import { DocUtils } from "../../documents/Documents"; import { DragManager, dropActionType } from "../../util/DragManager"; +import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { EditableView } from "../EditableView"; +import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; +import { DocAfterFocusFunc } from "../nodes/DocumentView"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; -import { SnappingManager } from "../../util/SnappingManager"; -import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; -import { DocUtils } from "../../documents/Documents"; -import { DocAfterFocusFunc } from "../nodes/DocumentView"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -56,7 +55,7 @@ export class CollectionStackingView extends CollectionSubView doc) { @computed get contents() { return
    - +
    ; } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 511fc723d..dbbb3e991 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -66,7 +66,6 @@ export interface CollectionViewProps extends FieldViewProps { layoutEngine?: () => string; parentActive: (outsideReaction: boolean) => boolean; filterAddDocument?: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) - VisibleHeight?: () => number; setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; // property overrides for child documents @@ -242,28 +241,27 @@ export class CollectionView extends Touchable { private SubView = (type: CollectionViewType, props: SubCollectionViewProps) => { TraceMobx(); switch (type) { - case CollectionViewType.Schema: return (); - case CollectionViewType.Docking: return (); - case CollectionViewType.Tree: return (); - //case CollectionViewType.Staff: return (); - case CollectionViewType.Multicolumn: return (); - case CollectionViewType.Multirow: return (); - case CollectionViewType.Linear: { return (); } - case CollectionViewType.Pile: { return (); } - case CollectionViewType.Carousel: { return (); } - case CollectionViewType.Carousel3D: { return (); } - case CollectionViewType.Stacking: { this.props.Document._columnsStack = true; return (); } - case CollectionViewType.Masonry: { this.props.Document._columnsStack = false; return (); } - case CollectionViewType.Time: { return (); } - case CollectionViewType.Map: return (); - case CollectionViewType.Grid: return (); - case CollectionViewType.Freeform: - default: { this.props.Document._freeformLayoutEngine = undefined; return (); } + default: + case CollectionViewType.Freeform: return ; + case CollectionViewType.Schema: return ; + case CollectionViewType.Docking: return ; + case CollectionViewType.Tree: return ; + case CollectionViewType.Multicolumn: return ; + case CollectionViewType.Multirow: return ; + case CollectionViewType.Linear: return ; + case CollectionViewType.Pile: return ; + case CollectionViewType.Carousel: return ; + case CollectionViewType.Carousel3D: return ; + case CollectionViewType.Stacking: return ; + case CollectionViewType.Masonry: return ; + case CollectionViewType.Time: return ; + case CollectionViewType.Map: return ; + case CollectionViewType.Grid: return ; + //case CollectionViewType.Staff: return ; } } setupViewTypes(category: string, func: (viewType: CollectionViewType) => Doc, addExtras: boolean) { - const subItems: ContextMenuProps[] = []; subItems.push({ description: "Freeform", event: () => func(CollectionViewType.Freeform), icon: "signature" }); if (addExtras && CollectionView._safeMode) { diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index b532d3302..24a67faaf 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -571,7 +571,7 @@ export class SchemaTable extends React.Component { Document={this._showDoc} DataDoc={this._showDataDoc} fitToBox={true} - FreezeDimensions={true} + freezeDimensions={true} focus={emptyFunction} renderDepth={this.props.renderDepth} rootSelected={() => false} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index e09abd017..94de40bc8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -918,7 +918,7 @@ export class CollectionFreeFormView extends CollectionSubView, bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica) })); diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index f3e385746..bef197bee 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -170,7 +170,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { PanelWidth={width} PanelHeight={height} ContentScaling={returnOne} - FreezeDimensions={true} + freezeDimensions={true} fitToBox={true} ScreenToLocalTransform={dxf} onClick={this.onChildClickHandler} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 586c5d1df..d4913a5ed 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -219,7 +219,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu styleProvider={this.props.styleProvider} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} - FreezeDimensions={this.props.childFreezeDimensions} + freezeDimensions={this.props.childFreezeDimensions} renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 87c56de6f..9039090d1 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -219,7 +219,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) styleProvider={this.props.styleProvider} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} - FreezeDimensions={this.props.childFreezeDimensions} + freezeDimensions={this.props.childFreezeDimensions} renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index b4b887617..d68184da6 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -52,7 +52,7 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu undefined); } @computed get topMost() { return this.props.renderDepth === 0; } - @computed get freezeDimensions() { return this.props.FreezeDimensions; } + @computed get freezeDimensions() { return this.props.freezeDimensions; } @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.dataDoc, this.freezeDimensions)); } @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.dataDoc, this.freezeDimensions)); } @computed get onClickHandler() { return this.props.onClick?.() ?? Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); } diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 4ac932c24..8acf4081c 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -169,7 +169,6 @@ export class KeyValueBox extends React.Component { getTemplate = async () => { const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template" }); - parent._columnsStack = false; parent._columnWidth = 100; for (const row of this.rows.filter(row => row.isChecked)) { await this.createTemplateField(parent, row); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 42b24f6f6..a2f3fb2d1 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,28 +1,27 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable, runInAction, reaction, IReactionDisposer, trace, untracked, computed } from 'mobx'; +import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; -import { Opt, WidthSym, Doc, HeightSym } from "../../../fields/Doc"; +import { Doc, Opt, WidthSym } from "../../../fields/Doc"; +import { documentSchema } from '../../../fields/documentSchemas'; import { makeInterface } from "../../../fields/Schema"; -import { ScriptField } from '../../../fields/ScriptField'; -import { Cast, NumCast, StrCast } from "../../../fields/Types"; -import { PdfField, URLField } from "../../../fields/URLField"; +import { Cast, NumCast } from "../../../fields/Types"; +import { PdfField } from "../../../fields/URLField"; +import { TraceMobx } from '../../../fields/util'; import { Utils } from '../../../Utils'; +import { KeyCodes } from '../../util/KeyCodes'; import { undoBatch } from '../../util/UndoManager'; import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView'; +import { CollectionViewType } from '../collections/CollectionView'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { PDFViewer } from "../pdf/PDFViewer"; import { FieldView, FieldViewProps } from './FieldView'; import { pageSchema } from "./ImageBox"; -import { KeyCodes } from '../../util/KeyCodes'; import "./PDFBox.scss"; import React = require("react"); -import { documentSchema } from '../../../fields/documentSchemas'; -import { CollectionViewType } from '../collections/CollectionView'; -import { TraceMobx } from '../../../fields/util'; type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>; const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @@ -30,17 +29,11 @@ const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @observer export class PDFBox extends ViewBoxAnnotatableComponent(PdfDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PDFBox, fieldKey); } - private _keyValue: string = ""; - private _valueValue: string = ""; - private _scriptValue: string = ""; private _searchString: string = ""; private _initialScale: number = 0; // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not. Getting bigger after startup won't make it automatically be live. private _displayPdfLive = false; // has this box ever had its contents activated -- if so, stop drawing the overlay title private _pdfViewer: PDFViewer | undefined; private _searchRef = React.createRef(); - private _keyRef = React.createRef(); - private _valueRef = React.createRef(); - private _scriptRef = React.createRef(); private _selectReactionDisposer: IReactionDisposer | undefined; @observable private _searching: boolean = false; @@ -130,25 +123,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent { - const scriptText = this._scriptValue ? this._scriptValue : - this._keyValue && this._valueValue ? `this.${this._keyValue} === ${this._valueValue}` : "true"; - this.props.Document.filterScript = ScriptField.MakeFunction(scriptText); - } - - private resetFilters = () => { - this._keyValue = this._valueValue = this._scriptValue = ""; - this._keyRef.current && (this._keyRef.current.value = ""); - this._valueRef.current && (this._valueRef.current.value = ""); - this._scriptRef.current && (this._scriptRef.current.value = ""); - this.applyFilter(); - } - private newKeyChange = (e: React.ChangeEvent) => this._keyValue = e.currentTarget.value; - private newValueChange = (e: React.ChangeEvent) => this._valueValue = e.currentTarget.value; - private newScriptChange = (e: React.ChangeEvent) => this._scriptValue = e.currentTarget.value; - whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); setPdfViewer = (pdfViewer: PDFViewer) => { this._pdfViewer = pdfViewer; }; searchStringChanged = (e: React.ChangeEvent) => this._searchString = e.currentTarget.value; @@ -197,36 +171,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent this._pageControls = !this._pageControls)} /> {this._pageControls ? pageBtns : (null)}
    - {/*
    e.stopPropagation()}> - -
    -
    - Annotation View Settings -
    -
    - - -
    -
    - -
    -
    - - -
    -
    -
    */}
    ); } @@ -253,19 +197,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent 600) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}> -
    - 600) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}> +
    + + startupLive={true} + /> {this.settingsPanel()}
    ; } diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 8d10768ff..90a5dee23 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -427,11 +427,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent + renderDepth={this.props.renderDepth + 1}> {this.contentFunc} diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 197ff20d5..47464d794 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -646,14 +646,6 @@ export class WebBox extends ViewBoxAnnotatableComponent this._marqueeX; marqueeY = () => this._marqueeY; marqueeing = () => this._marqueeing; - visibleHeight = () => { - if (this._mainCont.current) { - const boundingRect = this._mainCont.current.getBoundingClientRect(); - const scaling = (Doc.NativeWidth(this.Document) || 0) / boundingRect.width; - return Math.min(boundingRect.height * scaling, this.props.PanelHeight() * scaling); - } - return this.props.PanelHeight(); - } scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); render() { const scaling = Number.isFinite(this.props.ContentScaling()) ? this.props.ContentScaling() || 1 : 1; @@ -697,13 +689,8 @@ export class WebBox extends ViewBoxAnnotatableComponent + renderDepth={this.props.renderDepth + 1}> diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 33515e475..bfbd7805d 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1620,8 +1620,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp isAnnotationOverlay: true, fieldKey: this.annotationKey, fitToBox: fitToBox, - focus: this.props.focus, - isSelected: this.props.isSelected, select: emptyFunction, active: this.annotationsActive, ContentScaling: this.sidebarContentScaling, @@ -1632,7 +1630,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp CollectionView: undefined, ScreenToLocalTransform: this.sidebarScreenToLocal, renderDepth: this.props.renderDepth + 1, - ContainingCollectionDoc: this.props.ContainingCollectionDoc, }; return !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) :
    + renderDepth={this.props.renderDepth + 1}>
    ; } @@ -778,7 +751,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent this._marqueeX; marqueeY = () => this._marqueeY; marqueeing = () => this._marqueeing; - visibleHeight = () => this.props.PanelHeight() / this.props.ContentScaling(); contentZoom = () => this._zoomed; render() { TraceMobx(); diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 979238767..67df56015 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -49,14 +49,12 @@ export const documentSchema = createSchema({ _showTitle: "string", // the fieldkey whose contents should be displayed at the top of the document _showTitleHover: "string", // the showTitle should be shown only on hover _showAudio: "boolean", // whether to show the audio record icon on documents - _freeformLayoutEngine: "string",// the string ID for the layout engine to use to layout freeform view documents _freeformLOD: "boolean", // whether to enable LOD switching for CollectionFreeFormViews _pivotField: "string", // specifies which field key should be used as the timeline/pivot axis _replacedChrome: "string", // what the default chrome is replaced with. Currently only supports the value of 'replaced' for PresBox's. _chromeStatus: "string", // determines the state of the collection chrome. values allowed are 'replaced', 'enabled', 'disabled', 'collapsed' _columnsFill: "boolean", // whether documents in a stacking view column should be sized to fill the column _columnsSort: "string", // how a document should be sorted "ascending", "descending", undefined (none) - _columnsStack: "boolean", // whether a stacking document stacks vertically (as opposed to masonry horizontal) _columnsHideIfEmpty: "boolean", // whether empty stacking view column headings should be hidden _columnHeaders: listSpec(SchemaHeaderField), // header descriptions for stacking/masonry _schemaHeaders: listSpec(SchemaHeaderField), // header descriptions for schema views -- cgit v1.2.3-70-g09d2 From dcf5ba2699d7f83f604bedeadea3ba69061a0fd1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Dec 2020 15:53:26 -0500 Subject: more cleanup to documentViewprops. got rid of nudge() added --- src/client/views/GlobalKeyHandler.ts | 16 ++++++++-------- src/client/views/collections/TabDocView.tsx | 4 +--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 5 +++-- src/client/views/nodes/DocumentView.tsx | 14 +++++++------- src/client/views/nodes/FieldView.tsx | 1 - 5 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 3f3d382e4..aa901911f 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -141,10 +141,10 @@ export class KeyManager { UndoManager.RunInBatch(() => selected.map(dv => !dv.props.Document._stayInCollection && dv.props.removeDocument?.(dv.props.Document)), "delete"); SelectionManager.DeselectAll(); break; - case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(-1, 0)), "nudge left"); break; - case "arrowright": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(1, 0)), "nudge right"); break; - case "arrowup": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(0, -1)), "nudge up"); break; - case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(0, 1)), "nudge down"); break; + case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge(-1, 0)), "nudge left"); break; + case "arrowright": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(1, 0)), "nudge right"); break; + case "arrowup": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, -1)), "nudge up"); break; + case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, 1)), "nudge down"); break; } return { @@ -158,10 +158,10 @@ export class KeyManager { const preventDefault = false; switch (keyname) { - case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(-10, 0)), "nudge left"); break; - case "arrowright": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(10, 0)), "nudge right"); break; - case "arrowup": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(0, -10)), "nudge up"); break; - case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.nudge?.(0, 10)), "nudge down"); break; + case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(-10, 0)), "nudge left"); break; + case "arrowright": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(10, 0)), "nudge right"); break; + case "arrowup": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, -10)), "nudge up"); break; + case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, 10)), "nudge down"); break; } return { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index fd50c6273..5c815c1f6 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -386,7 +386,6 @@ export class TabDocView extends React.Component { } afterFocus?.(false); } - setView = action((view: DocumentView) => this._view = view); active = () => this._isActive; // @@ -504,9 +503,8 @@ export class TabDocView extends React.Component { @computed get docView() { TraceMobx(); return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : - <> this._view = r)} Document={this._document} - getView={this.setView} DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined} bringToFront={emptyFunction} rootSelected={returnTrue} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index d68184da6..ff37847df 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -140,6 +140,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.Opacity; NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; + returnThis = () => this; @computed get pointerEvents() { if (this.props.pointerEvents === "none") return "none"; return this.props.styleProvider?.(this.Document, this.props, !this._contentView?.docView?.isSelected() ? "pointerEvents:selected" : "pointerEvents"); @@ -149,9 +150,9 @@ export class CollectionFreeFormDocumentView extends DocComponent boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; @@ -48,6 +49,7 @@ export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterF export interface DocumentViewSharedProps { ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; + CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; Document: Doc; DataDoc?: Doc; contentsActive?: (setActive: () => boolean) => void; @@ -81,29 +83,27 @@ export interface DocumentViewSharedProps { ContentScaling: () => number; ChromeHeight?: () => number; pointerEvents?: string; + scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document } export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView + layoutKey?: string; freezeDimensions?: boolean; fitToBox?: boolean; treeViewDoc?: Doc; dragDivName?: string; contentsPointerEvents?: string; - getView?: (view: DocumentView) => any; + radialMenu?: String[]; + display?: string; + relative?: boolean; LayoutTemplate?: () => Opt; contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; onPointerUp?: () => ScriptField; - nudge?: (x: number, y: number) => void; setupDragLines?: (snapToDraggedDoc: boolean) => void; forceHideLinkButton?: () => boolean; opacity?: () => number | undefined; - layoutKey?: string; - radialMenu?: String[]; - display?: string; - relative?: boolean; - scriptContext?: any; } @observer diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 1d58893ae..057c7afae 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -31,7 +31,6 @@ export interface FieldViewProps extends DocumentViewSharedProps { color?: string; xMargin?: number; yMargin?: number; - scriptContext?: any; } @observer -- cgit v1.2.3-70-g09d2 From 896db53261aca91de21eabfaa6fed0c1b27e3e51 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Dec 2020 21:41:54 -0500 Subject: moved opacity and borderRounding into styleProviders. fixed contextMenu clcik from button bar --- src/client/views/DocumentButtonBar.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 17 +++++++++--- src/client/views/collections/TabDocView.tsx | 24 +++++++++++------ src/client/views/collections/TreeView.tsx | 10 ++++++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 ++- .../views/nodes/CollectionFreeFormDocumentView.tsx | 24 ++++++++--------- src/client/views/nodes/DocumentView.scss | 3 +++ src/client/views/nodes/DocumentView.tsx | 30 ++++++++++------------ src/client/views/nodes/LabelBox.tsx | 2 +- src/client/views/nodes/SliderBox.tsx | 2 +- .../views/presentationview/PresElementBox.tsx | 8 ++++-- 11 files changed, 76 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index fa0b9a238..dc6311696 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -339,7 +339,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV let child = SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0]; while (child.children.length) { const next = Array.from(child.children).find(c => typeof (c.className) === "string"); - if (next?.className.includes("documentView-node")) break; + if (next?.className.includes(DocumentView.ROOT_DIV)) break; if (next?.className.includes("dashFieldView")) break; if (next) child = next; else break; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index b1c5dec84..408a8d969 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -22,7 +22,7 @@ import { ContextMenuProps } from "../ContextMenuItem"; import { EditableView } from "../EditableView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; -import { DocAfterFocusFunc } from "../nodes/DocumentView"; +import { DocAfterFocusFunc, DocumentViewProps } from "../nodes/DocumentView"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; @@ -187,14 +187,24 @@ export class CollectionStackingView extends CollectionSubView Transform, width: () => number) { const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc; const height = () => this.getDocHeight(doc); - const opacity = () => this.Document._currentFrame === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity; + const styleProvider = (doc: Doc | undefined, props: DocumentViewProps, property: string) => { + if (property === "opacity" && doc) { + if (this.props.childOpacity) { + return this.props.childOpacity(); + } + if (this.Document._currentFrame !== undefined) { + return CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity; + } + } + return this.props.styleProvider?.(doc, props, property); + }; return { // // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // - public static styleProvider = (doc: Opt, props: DocumentViewProps | undefined, property: string): any => { + public static styleProvider = (doc: Opt, props: DocumentViewProps, property: string): any => { switch (property) { + case "docContents": return undefined; + case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey"; + case "opacity": return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); + case "hidden": return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); + case "borderRounding": return !doc ? undefined : StrCast(doc._borderRounding, StrCast(doc.borderRounding)); case "backgroundColor": { if (Doc.UserDoc().renderStyle === "comic") return undefined; - let docColor = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); + let docColor: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); if (!docColor) { switch (doc?.type) { case DocumentType.PRESELEMENT: docColor = TabDocView.darkScheme ? "" : ""; break; @@ -457,20 +462,23 @@ export class TabDocView extends React.Component { if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor).fade(0.5).toString(); return docColor; } - case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey"; - case "hidden": return (BoolCast(doc?.hidden) /* || props?.layerProvider?.(doc) === false*/); case "boxShadow": { + if (!doc || props.styleProvider?.(doc, props, "opacity") === 0) return undefined; // if it's not visible, then no shadow) + const isBackground = StrListCast(doc.layers).includes("background"); switch (doc?.type) { - case DocumentType.COL: return StrListCast(doc.layers).includes("background") ? undefined : + case DocumentType.COL: return isBackground ? undefined : `${TabDocView.darkScheme ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; - default: return undefined; + default: + return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow + props.backgroundHalo?.(doc) && doc.type !== DocumentType.INK ? (`${props.styleProvider?.(doc, props, "backgroundColor")} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground ? 100 : 50) / props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big + StrCast(doc.boxShadow, "") } } - case "docContents": return undefined; default: if (property.startsWith("pointerEvents")) { const layer = doc && props?.layerProvider?.(doc); - if (doc?.Opacity === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; + if (props.styleProvider?.(doc, props, "opacity") === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none"; if (doc?.type !== DocumentType.INK && layer === true) return "all"; return undefined; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index be8a27ab0..24dd905a9 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -441,7 +441,7 @@ export class TreeView extends React.Component { return
    @@ -496,6 +496,12 @@ export class TreeView extends React.Component { e.preventDefault(); } } + styleProvider = (doc: (Doc | undefined), props: DocumentViewProps, property: string): any => { + // override opacity and backgroundColor just for this treeView document: opacity = 1, and backgroundColor = undefined unless it is explicitly set on the document + if (property === "opacity" && doc === this.props.document) return this.outlineMode ? undefined : 1; + if (property === "backgroundColor" && doc === this.props.document) return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); + return this.props.treeView.props.styleProvider?.(doc, props, property); + } onKeyDown = (e: React.KeyboardEvent) => { if (this.doc.treeViewHideHeader || this.outlineMode) { e.stopPropagation(); @@ -520,6 +526,7 @@ export class TreeView extends React.Component { ref={this._docRef} Document={this.doc} DataDoc={undefined} + styleProvider={this.styleProvider} treeViewDoc={this.props.treeView.props.Document} addDocument={undefined} addDocTab={this.props.addDocTab} @@ -535,7 +542,6 @@ export class TreeView extends React.Component { PanelWidth={this.truncateTitleWidth} PanelHeight={returnZero} contextMenuItems={this.contextMenuItems} - opacity={this.outlineMode ? undefined : returnOne} renderDepth={1} focus={returnTrue} parentActive={returnTrue} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 94de40bc8..a8e24ebbe 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1049,7 +1049,8 @@ export class CollectionFreeFormView extends CollectionSubView { + if (property === "opacity" && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children + return this.props.styleProvider?.(doc, props, property); + } + static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; public static getValues(doc: Doc, time: number) { return CollectionFreeFormDocumentView.animFields.reduce((p, val) => { @@ -137,7 +142,6 @@ export class CollectionFreeFormDocumentView extends DocComponent (this.sizeProvider?.height || this.props.PanelHeight?.()); getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling()); focusDoc = (doc: Doc) => this.props.focus(doc, false); - opacity = () => this.Opacity; NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; returnThis = () => this; @@ -148,13 +152,13 @@ export class CollectionFreeFormDocumentView extends DocComponent diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index ad72250b6..d25d7af05 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -1,5 +1,8 @@ @import "../globalCssVariables"; +.documentView-effectsWrapper { + border-radius: inherit; +} .documentView-node, .documentView-node-topmost { position: inherit; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 591859737..ed3fa6918 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -103,11 +103,11 @@ export interface DocumentViewProps extends DocumentViewSharedProps { onPointerUp?: () => ScriptField; setupDragLines?: (snapToDraggedDoc: boolean) => void; forceHideLinkButton?: () => boolean; - opacity?: () => number | undefined; } @observer export class DocumentView extends DocComponent(Document) { + public static ROOT_DIV = "documentView-effectsWrapper"; @observable _animateScalingTo = 0; private _downX: number = 0; private _downY: number = 0; @@ -1090,24 +1090,22 @@ export class DocumentView extends DocComponent(Docu 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, "hidden")) return null; - const backgroundColor = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor"); - const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null))); - const finalOpacity = this.props.opacity ? this.props.opacity() : opacity; - const finalColor = this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor; - const fullDegree = 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 borderRounding = this.layoutDoc.borderRounding; - const localScale = fullDegree; + const background = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor"); + const borderRounding = this.props.styleProvider?.(this.layoutDoc, this.props, "borderRounding"); + const opacity = this.props.styleProvider?.(this.layoutDoc, this.props, "opacity"); + 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 highlightColors = CurrentUserUtils.ActiveDashboard?.darkScheme ? ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] : ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"]; const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"]; - let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear && this.props.Document.type !== DocumentType.INK; + let highlighting = highlightIndex && ![DocumentType.FONTICON, DocumentType.INK].includes(this.layoutDoc.type as any) && this.layoutDoc._viewType !== CollectionViewType.Linear; highlighting = highlighting && this.props.focus !== emptyFunction && this.layoutDoc.title !== "[pres element template]"; // bcz: hack to turn off highlighting onsidebar panel documents. need to flag a document as not highlightable in a more direct way const topmost = this.topMost ? "-topmost" : ""; return this.props.styleProvider?.(this.rootDoc, this.props, "docContents") ??
    !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))} onPointerLeave={action(e => { let entered = false; @@ -1122,15 +1120,15 @@ export class DocumentView extends DocComponent(Docu transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : `transform 0.5s ease-${this._animateScalingTo < 1 ? "in" : "out"}`, pointerEvents: this.pointerEvents, color: StrCast(this.layoutDoc.color, "inherit"), - outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px", - border: highlighting && borderRounding && highlightStyles[fullDegree] === "dashed" ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined, - boxShadow: highlighting && borderRounding && highlightStyles[fullDegree] !== "dashed" ? `0 0 0 ${localScale}px ${highlightColors[fullDegree]}` : + outline: highlighting && !borderRounding ? `${highlightColors[highlightIndex]} ${highlightStyles[highlightIndex]} ${highlightIndex}px` : "solid 0px", + border: highlighting && borderRounding && highlightStyles[highlightIndex] === "dashed" ? `${highlightStyles[highlightIndex]} ${highlightColors[highlightIndex]} ${highlightIndex}px` : undefined, + boxShadow: highlighting && borderRounding && highlightStyles[highlightIndex] !== "dashed" ? `0 0 0 ${highlightIndex}px ${highlightColors[highlightIndex]}` : this.Document.isLinkButton && !this.props.dontRegisterView && !this.props.forceHideLinkButton?.() ? StrCast(this.layoutDoc._linkButtonShadow, "lightblue 0em 0em 1em") : this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined, - background: finalColor, - opacity: finalOpacity, + background, + opacity, fontFamily: StrCast(this.Document._fontFamily, "inherit"), fontSize: !this.props.treeViewDoc ? Cast(this.Document._fontSize, "string", null) : undefined, }}> @@ -1140,7 +1138,7 @@ export class DocumentView extends DocComponent(Docu
    ; } render() { - return
    + return
    {PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc}
    ; } diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 826ccd340..dd751b802 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -72,7 +72,7 @@ export class LabelBox extends ViewBoxBaseComponent this._mouseOver = false)} onMouseOver={action(() => this._mouseOver = true)} ref={this.createDropTarget} onContextMenu={this.specificContextMenu} - style={{ boxShadow: this.layoutDoc.opacity ? StrCast(this.layoutDoc.boxShadow) : "" }}> + style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, "boxShadow") }}>
    e.stopPropagation()} - style={{ boxShadow: this.layoutDoc.opacity === 0 ? undefined : StrCast(this.layoutDoc.boxShadow, "") }}> + style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, "boxShadow") }}>
    this.props.PanelWidth(); // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); embedWidth = (): number => this.props.PanelWidth() - 35; + styleProvider = (doc: (Doc | undefined), props: DocumentViewProps, property: string): any => { + if (property === "opacity") return 1; + return this.props.styleProvider?.(doc, props, property); + } /** * The function that is responsible for rendering a preview or not for this * presentation element. @@ -87,7 +92,7 @@ export class PresElementBox extends ViewBoxBaseComponent Date: Thu, 10 Dec 2020 22:25:37 -0500 Subject: fixed infinite loop in treeView. changed styleProvider signature back to have an optional 'props' --- src/client/views/PropertiesView.tsx | 4 ++-- .../views/collections/CollectionStackingView.tsx | 4 ++-- src/client/views/collections/TabDocView.tsx | 10 +++++----- src/client/views/collections/TreeView.tsx | 18 +++++++++--------- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 8 ++++++-- src/client/views/nodes/LinkDocPreview.tsx | 4 ++-- src/client/views/presentationview/PresElementBox.tsx | 4 ++-- 9 files changed, 30 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 233429f4d..352c70e94 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -28,7 +28,7 @@ import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; import { CollectionViewType } from "./collections/CollectionView"; -import { DocumentViewProps } from "./nodes/DocumentView"; +import { DocumentViewProps, StyleProviderFunc } from "./nodes/DocumentView"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -37,7 +37,7 @@ const _global = (window /* browser */ || global /* node */) as any; interface PropertiesViewProps { width: number; height: number; - styleProvider?: (doc: Opt, props: Opt, property: string) => any; + styleProvider?: StyleProviderFunc; } @observer diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 408a8d969..8dfb7cefe 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { CursorProperty } from "csstype"; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, HeightSym, WidthSym } from "../../../fields/Doc"; +import { DataSym, Doc, HeightSym, WidthSym, Opt } from "../../../fields/Doc"; import { collectionSchema, documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; @@ -187,7 +187,7 @@ export class CollectionStackingView extends CollectionSubView Transform, width: () => number) { const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc; const height = () => this.getDocHeight(doc); - const styleProvider = (doc: Doc | undefined, props: DocumentViewProps, property: string) => { + const styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === "opacity" && doc) { if (this.props.childOpacity) { return this.props.childOpacity(); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 5b5d8ee4a..045fee797 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -432,7 +432,7 @@ export class TabDocView extends React.Component { // // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // - public static styleProvider = (doc: Opt, props: DocumentViewProps, property: string): any => { + public static styleProvider = (doc: Opt, props: Opt, property: string): any => { switch (property) { case "docContents": return undefined; case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey"; @@ -463,22 +463,22 @@ export class TabDocView extends React.Component { return docColor; } case "boxShadow": { - if (!doc || props.styleProvider?.(doc, props, "opacity") === 0) return undefined; // if it's not visible, then no shadow) + if (!doc || props?.styleProvider?.(doc, props, "opacity") === 0) return undefined; // if it's not visible, then no shadow) const isBackground = StrListCast(doc.layers).includes("background"); switch (doc?.type) { case DocumentType.COL: return isBackground ? undefined : `${TabDocView.darkScheme ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; default: return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow - props.backgroundHalo?.(doc) && doc.type !== DocumentType.INK ? (`${props.styleProvider?.(doc, props, "backgroundColor")} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground ? 100 : 50) / props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + props?.backgroundHalo?.(doc) && doc.type !== DocumentType.INK ? (`${props?.styleProvider?.(doc, props, "backgroundColor")} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground ? 100 : 50) / props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big - StrCast(doc.boxShadow, "") + StrCast(doc.boxShadow, ""); } } default: if (property.startsWith("pointerEvents")) { const layer = doc && props?.layerProvider?.(doc); - if (props.styleProvider?.(doc, props, "opacity") === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; + if (props?.styleProvider?.(doc, props, "opacity") === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none"; if (doc?.type !== DocumentType.INK && layer === true) return "all"; return undefined; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 24dd905a9..d34cca852 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -21,7 +21,7 @@ import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from '../../util/UndoManager'; import { EditableView } from "../EditableView"; import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; -import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewProps, StyleProviderFunc } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { KeyValueBox } from '../nodes/KeyValueBox'; @@ -49,7 +49,7 @@ export interface TreeViewProps { outdentDocument?: () => void; ScreenToLocalTransform: () => Transform; dontRegisterView?: boolean; - backgroundColor?: (doc: Opt, props: DocumentViewProps, property: string) => string | undefined; + styleProvider?: StyleProviderFunc | undefined; outerXf: () => { translateX: number, translateY: number }; treeView: CollectionTreeView; parentKey: string; @@ -325,7 +325,7 @@ export class TreeView extends React.Component { const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true); contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] : DocListCast(contents), this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, + this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.styleProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView); } else { @@ -404,7 +404,7 @@ export class TreeView extends React.Component { {!docs ? (null) : TreeView.GetChildElements(docs, this.props.treeView, this.layoutDoc, this.dataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, + StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.styleProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView)}
; @@ -496,11 +496,11 @@ export class TreeView extends React.Component { e.preventDefault(); } } - styleProvider = (doc: (Doc | undefined), props: DocumentViewProps, property: string): any => { + styleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { // override opacity and backgroundColor just for this treeView document: opacity = 1, and backgroundColor = undefined unless it is explicitly set on the document if (property === "opacity" && doc === this.props.document) return this.outlineMode ? undefined : 1; if (property === "backgroundColor" && doc === this.props.document) return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); - return this.props.treeView.props.styleProvider?.(doc, props, property); + return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView } onKeyDown = (e: React.KeyboardEvent) => { if (this.doc.treeViewHideHeader || this.outlineMode) { @@ -606,7 +606,7 @@ export class TreeView extends React.Component { renderDepth={this.props.renderDepth + 1} rootSelected={returnTrue} treeViewDoc={undefined} - styleProvider={this.props.backgroundColor} + styleProvider={this.styleProvider} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -716,7 +716,7 @@ export class TreeView extends React.Component { dropAction: dropActionType, addDocTab: (doc: Doc, where: string) => boolean, pinToPres: (document: Doc) => void, - styleProvider: undefined | ((document: Opt, props: DocumentViewProps, property: string) => string | undefined), + styleProvider: undefined | StyleProviderFunc, screenToLocalXf: () => Transform, outerXf: () => { translateX: number, translateY: number }, active: (outsideReaction?: boolean) => boolean, @@ -789,7 +789,7 @@ export class TreeView extends React.Component { renderDepth={renderDepth} removeDoc={StrCast(containingCollection.freezeChildren).includes("remove") ? undefined : remove} addDocument={addDocument} - backgroundColor={styleProvider} + styleProvider={styleProvider} panelWidth={rowWidth} panelHeight={rowHeight} ChromeHeight={ChromeHeight} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a8e24ebbe..1b6cfbd21 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -395,7 +395,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: DocumentViewProps, property: string) => { + getClusterColor = (doc: Opt, props: Opt, property: string) => { let clusterColor = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 if (property !== "backgroundColor") return clusterColor; const cluster = NumCast(doc?.cluster); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 60d33468a..46c311350 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -58,7 +58,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { + styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === "opacity" && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children return this.props.styleProvider?.(doc, props, property); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ed3fa6918..502f874e0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -45,6 +45,7 @@ import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView export type DocAfterFocusFunc = (notFocused: boolean) => boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; +export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; export interface DocumentViewSharedProps { ContainingCollectionView: Opt; @@ -67,7 +68,7 @@ export interface DocumentViewSharedProps { moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; pinToPres: (document: Doc) => void; layerProvider?: (doc: Doc, assign?: boolean) => boolean; - styleProvider?: (doc: Opt, props: DocumentViewProps, property: string) => any; + styleProvider?: StyleProviderFunc; ScreenToLocalTransform: () => Transform; bringToFront: (doc: Doc, sendToBack?: boolean) => void; parentActive: (outsideReaction: boolean) => boolean; @@ -982,6 +983,9 @@ export class DocumentView extends DocComponent(Docu @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } + anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { + return property === "backgroundColor" ? "transparent" : undefined; + } @computed get allAnchors() { TraceMobx(); if (this.props.LayoutTemplateString?.includes("LinkAnchorBox")) return null; @@ -1003,7 +1007,7 @@ export class DocumentView extends DocComponent(Docu ContentScaling={returnOne} dontRegisterView={false} forceHideLinkButton={returnTrue} - styleProvider={(doc: Opt, props: DocumentViewProps, property: string) => property === "backgroundColor" ? "transparent" : undefined} + styleProvider={this.anchorStyleProvider} removeDocument={this.hideLinkAnchor} pointerEvents={"none"} LayoutTemplate={undefined} diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index f66811098..e0c8c032f 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -11,14 +11,14 @@ import { ContextMenu } from '../ContextMenu'; import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; import { DocumentLinksButton } from './DocumentLinksButton'; import React = require("react"); -import { DocumentViewProps } from './DocumentView'; +import { StyleProviderFunc } from './DocumentView'; import { Id } from '../../../fields/FieldSymbols'; interface Props { linkDoc?: Doc; linkSrc?: Doc; href?: string; - styleProvider?: (doc: Opt, props: Opt, property: string) => any; + styleProvider?: StyleProviderFunc; addDocTab: (document: Doc, where: string) => boolean; location: number[]; } diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 7eda04930..45d943bff 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, reaction, runInAction, observable, trace } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DataSym } from "../../../fields/Doc"; +import { Doc, DataSym, Opt } from "../../../fields/Doc"; import { documentSchema } from '../../../fields/documentSchemas'; import { Id } from "../../../fields/FieldSymbols"; import { createSchema, makeInterface } from '../../../fields/Schema'; @@ -77,7 +77,7 @@ export class PresElementBox extends ViewBoxBaseComponent this.props.PanelWidth(); // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); embedWidth = (): number => this.props.PanelWidth() - 35; - styleProvider = (doc: (Doc | undefined), props: DocumentViewProps, property: string): any => { + styleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { if (property === "opacity") return 1; return this.props.styleProvider?.(doc, props, property); } -- cgit v1.2.3-70-g09d2 From f9f7e0aac784d3b32c5adab04d8ec5d7807b0390 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Dec 2020 23:11:46 -0500 Subject: a little refactoring in CollecftionFreeFormView --- .../collectionFreeForm/CollectionFreeFormView.tsx | 95 ++++++++-------------- 1 file changed, 35 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 1b6cfbd21..75411b3c5 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,7 +1,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; -import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from "../../../../fields/Doc"; import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas"; import { Id } from "../../../../fields/FieldSymbols"; import { InkData, InkField, InkTool } from "../../../../fields/InkField"; @@ -80,6 +80,8 @@ export type collectionFreeformViewProps = { @observer export class CollectionFreeFormView extends CollectionSubView>(PanZoomDocument) { + public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive + private _lastX: number = 0; private _lastY: number = 0; private _downX: number = 0; @@ -94,18 +96,22 @@ export class CollectionFreeFormView extends CollectionSubView(); private _layoutSizeData = new ObservableMap(); private _cachedPool: Map = new Map(); + private _lastTap = 0; + private _nudgeTime = 0; + private _thumbIdentifier?: number; + + @observable private _hLines: number[] | undefined; + @observable private _vLines: number[] | undefined; @observable private _pullCoords: number[] = [0, 0]; @observable private _pullDirection: string = ""; + @observable private _showAnimTimeline = false; - public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive @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[])[] = []; @observable _timelineRef = React.createRef(); - @observable _marqueeRef = React.createRef(); - @observable canPanX: boolean = true; - @observable canPanY: boolean = true; + @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 fitToContent() { return (this.props.fitToBox || this.Document._fitToBox) && !this.isAnnotationOverlay; } @computed get parentScaling() { return this.props.ContentScaling && this.fitToContent ? this.props.ContentScaling() : 1; } @@ -154,6 +160,7 @@ export class CollectionFreeFormView extends CollectionSubView { let retVal = false; if (newBox instanceof Doc) { @@ -303,6 +310,7 @@ export class CollectionFreeFormView extends CollectionSubView { if (e.nativeEvent.cancelBubble || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) { @@ -595,8 +602,6 @@ export class CollectionFreeFormView extends CollectionSubView { if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) return; @@ -768,7 +773,6 @@ export class CollectionFreeFormView extends CollectionSubView { let deltaScale = deltaY > 0 ? (1 / 1.05) : 1.05; @@ -981,7 +984,6 @@ export class CollectionFreeFormView extends CollectionSubView this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); // @ts-ignore @@ -1047,6 +1049,7 @@ export class CollectionFreeFormView extends CollectionSubView - @action onDragAutoScroll = (e: CustomEvent) => { if ((e as any).handlePan || this.props.isAnnotationOverlay) return; @@ -1254,7 +1255,6 @@ export class CollectionFreeFormView extends CollectionSubView { const docs = this.childLayoutPairs; @@ -1288,8 +1288,6 @@ export class CollectionFreeFormView extends CollectionSubView { if (this.props.isAnnotationOverlay || this.props.Document.annotationOn || !ContextMenu.Instance) return; @@ -1304,7 +1302,6 @@ export class CollectionFreeFormView extends CollectionSubView Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null; !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document._useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document._useClusters), icon: "braille" }) : null; !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" }); @@ -1312,7 +1309,7 @@ export class CollectionFreeFormView extends CollectionSubView this.showTimeline = !this.showTimeline), icon: "eye" }); + optionItems.push({ description: (this._showAnimTimeline ? "Close" : "Open") + " Animation Timeline", event: action(() => this._showAnimTimeline = !this._showAnimTimeline), icon: "eye" }); this.props.ContainingCollectionView && optionItems.push({ description: "Move Items Out of Collection", event: this.promoteCollection, icon: "table" }); optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" }); @@ -1320,7 +1317,6 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._freeformLOD = !this.Document._freeformLOD, icon: "table" }); - } !options && ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); const mores = ContextMenu.Instance.findByDescription("More..."); @@ -1349,11 +1345,10 @@ export class CollectionFreeFormView extends CollectionSubView { + setTimeout(() => SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => { docs.docs.forEach(d => LinkManager.Instance.addLink(d)); - }); - }, 2000); // need to give solr some time to update so that this query will find any link docs we've added. + }), 2000); // need to give solr some time to update so that this query will find any link docs we've added. } } } @@ -1361,57 +1356,38 @@ export class CollectionFreeFormView extends CollectionSubView r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top); - } - @action setupDragLines = (snapToDraggedDoc: boolean = false) => { const activeDocs = this.getActiveDocuments(); - if (activeDocs.length > 50) { - DragManager.SetSnapLines([], []); - return; - } const size = this.getTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight()); const selRect = { left: this.panX() - size[0] / 2, top: this.panY() - size[1] / 2, width: size[0], height: size[1] }; const docDims = (doc: Doc) => ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) }); - const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => { - if (this.intersectRect(docDims(doc), rect)) { - snappableDocs.push(doc); - } - }; - const snappableDocs: Doc[] = []; // the set of documents in the visible viewport that we will try to snap to; + const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => intersectRect(docDims(doc), rect); + const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) }; - this.getActiveDocuments().filter(doc => !Cast(doc.layers, listSpec("string"), []).includes("background") && doc.z === undefined).map(doc => isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to - !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => isDocInView(doc, selRect)); // if not, see if there are background docs to snap to - !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => isDocInView(doc, otherBounds)); // if not, then why not snap to floating docs + let snappableDocs = activeDocs.filter(doc => !StrListCast(doc.layers).includes("background") && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to + !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect))); // if not, see if there are background docs to snap to + !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z !== undefined && isDocInView(doc, otherBounds))); // if not, then why not snap to floating docs const horizLines: number[] = []; const vertLines: number[] = []; + const invXf = this.getTransform().inverse(); snappableDocs.filter(doc => snapToDraggedDoc || !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)).forEach(doc => { const { left, top, width, height } = docDims(doc); - const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top); - const docSize = this.getTransform().inverse().transformDirection(width, height); + const topLeftInScreen = invXf.transformPoint(left, top); + const docSize = invXf.transformDirection(width, height); horizLines.push(topLeftInScreen[1], topLeftInScreen[1] + docSize[1] / 2, topLeftInScreen[1] + docSize[1]); // horiz center line vertLines.push(topLeftInScreen[0], topLeftInScreen[0] + docSize[0] / 2, topLeftInScreen[0] + docSize[0]);// right line }); DragManager.SetSnapLines(horizLines, vertLines); } + onPointerOver = (e: React.PointerEvent) => { - if (SnappingManager.GetIsDragging()) { - this.setupDragLines(e.ctrlKey || e.shiftKey); - } + SnappingManager.GetIsDragging() && this.setupDragLines(e.ctrlKey || e.shiftKey); e.stopPropagation(); } - @observable private _hLines: number[] | undefined; - @observable private _vLines: number[] | undefined; - private childViews = () => { const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : []; return [ @@ -1426,13 +1402,13 @@ export class CollectionFreeFormView extends CollectionSubView); return eles; } + @computed get placeholder() { return
{this.props.Document.title?.toString()}
; } - _nudgeTime = 0; nudge = action((x: number, y: number) => { if (this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform || this.props.ContainingCollectionDoc._panX !== undefined) { // bcz: this isn't ideal, but want to try it out... @@ -1450,7 +1426,7 @@ export class CollectionFreeFormView extends CollectionSubView; } + trySelectCluster = (addToSel: boolean) => { if (this._hitCluster !== -1) { - if (!addToSel) { - SelectionManager.DeselectAll(); - } + !addToSel && SelectionManager.DeselectAll(); const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.props.Document._useClusters ? NumCast(cd.cluster) : NumCast(cd.group, -1)) === this._hitCluster); this.selectDocuments(eles); return true; } return false; } + @computed get marqueeView() { return
- {this.layoutDoc["_backgroundGrid-show"] ? this.grid : (null)} + {this.layoutDoc["_backgroundGrid-show"] ? this.backgroundGrid : (null)}
- {this.showTimeline ? : (null)} + {this._showAnimTimeline ? : (null)}
; } - @computed get contentScaling() { if (this.props.isAnnotationOverlay && !this.props.forceScaling) return 0; const nw = returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); -- cgit v1.2.3-70-g09d2 From 495b60322b56d50f90398757c3a3c1f56da66cdc Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 11 Dec 2020 02:07:40 -0500 Subject: cleaning up more doumentViewProps. reduced use of treeViewDoc prop. added hideTitle. fixed background shadow on isButton documents. --- src/client/views/DocumentDecorations.tsx | 4 +- src/client/views/PropertiesView.tsx | 1 - .../views/collections/CollectionTreeView.tsx | 2 - src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/collections/TreeView.scss | 8 ++ src/client/views/collections/TreeView.tsx | 43 ++++++---- .../CollectionFreeFormLinkView.tsx | 2 +- .../CollectionFreeFormLinksView.tsx | 6 +- src/client/views/nodes/DocumentView.tsx | 94 ++++++++++------------ src/client/views/nodes/LinkAnchorBox.tsx | 4 +- 10 files changed, 87 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8d905bcac..d4d91659f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -630,8 +630,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b top: bounds.y - this._resizeBorderWidth / 2 - this._titleHeight, }}> {closeIcon} - {Object.keys(SelectionManager.SelectedDocuments()[0].props).includes("treeViewDoc") ? (null) : titleArea} - {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK || Object.keys(SelectionManager.SelectedDocuments()[0].props).includes("treeViewDoc") ? (null) : + {titleArea} + {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : {`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}} placement="top">
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 352c70e94..03e0a35ec 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -269,7 +269,6 @@ export class PropertiesView extends React.Component { DataDoc={this.dataDoc} renderDepth={1} rootSelected={returnFalse} - treeViewDoc={undefined} styleProvider={this.props.styleProvider} fitToBox={true} freezeDimensions={true} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 265f5a323..89ed3a147 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -104,7 +104,6 @@ export class CollectionTreeView extends CollectionSubView this.doc.treeViewPreventOpen = !this.doc.treeViewPreventOpen, icon: "paint-brush" }); layoutItems.push({ description: (this.doc.treeViewHideHeaderFields ? "Show" : "Hide") + " Header Fields", event: () => this.doc.treeViewHideHeaderFields = !this.doc.treeViewHideHeaderFields, icon: "paint-brush" }); layoutItems.push({ description: (this.doc.treeViewHideTitle ? "Show" : "Hide") + " Title", event: () => this.doc.treeViewHideTitle = !this.doc.treeViewHideTitle, icon: "paint-brush" }); - layoutItems.push({ description: (this.doc.treeViewHideLinkLines ? "Show" : "Hide") + " Link Lines", event: () => this.doc.treeViewHideLinkLines = !this.doc.treeViewHideLinkLines, icon: "paint-brush" }); ContextMenu.Instance.addItem({ description: "Options...", subitems: layoutItems, icon: "eye" }); const existingOnClick = ContextMenu.Instance.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; @@ -163,7 +162,6 @@ export class CollectionTreeView extends CollectionSubView { (document.activeElement !== titleEle) && titleEle.focus(); } }; - tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => (v.topMost || v.props.treeViewDoc) && v.props.Document === doc), + tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.topMost && v.props.Document === doc), action((selected) => { if (selected) this._activated = true; const toggle = tab.element[0].children[1].children[0] as HTMLInputElement; diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 0a97166f0..796b2438e 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -1,5 +1,13 @@ @import "../globalCssVariables"; +.treeView-label { + max-height: 1.5em; + text-overflow: ellipsis; + display: inline-block; + white-space: pre; + width: 100%; + overflow: hidden; +} .treeView-container, .treeView-container-active { .bullet-outline { diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index d34cca852..53cdca2af 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -325,7 +325,7 @@ export class TreeView extends React.Component { const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true); contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] : DocListCast(contents), this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.styleProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, + this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView); } else { @@ -404,7 +404,7 @@ export class TreeView extends React.Component { {!docs ? (null) : TreeView.GetChildElements(docs, this.props.treeView, this.layoutDoc, this.dataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move, - StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.styleProvider, this.props.ScreenToLocalTransform, + StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen, [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView)} ; @@ -413,7 +413,7 @@ export class TreeView extends React.Component { {this.expandedField}
; } else { - return this.renderDocument(false); + return this.renderEmbeddedDocument(false); } } @@ -441,7 +441,7 @@ export class TreeView extends React.Component { return
@@ -496,10 +496,25 @@ export class TreeView extends React.Component { e.preventDefault(); } } - styleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { - // override opacity and backgroundColor just for this treeView document: opacity = 1, and backgroundColor = undefined unless it is explicitly set on the document - if (property === "opacity" && doc === this.props.document) return this.outlineMode ? undefined : 1; - if (property === "backgroundColor" && doc === this.props.document) return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); + titleStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { + if (!doc || doc !== this.doc) return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView + + switch (property) { + case "opacity": return this.outlineMode ? undefined : 1; + case "backgroundColor": return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); + case "docContents": return !props?.treeViewDoc ? (null) : +
+ {StrCast(doc?.title)} +
; + default: if (property.startsWith("decorations")) return (null); + } + } + embeddedStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { + if (property.startsWith("decorations")) return (null); return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView } onKeyDown = (e: React.KeyboardEvent) => { @@ -526,7 +541,7 @@ export class TreeView extends React.Component { ref={this._docRef} Document={this.doc} DataDoc={undefined} - styleProvider={this.styleProvider} + styleProvider={this.titleStyleProvider} treeViewDoc={this.props.treeView.props.Document} addDocument={undefined} addDocTab={this.props.addDocTab} @@ -552,7 +567,7 @@ export class TreeView extends React.Component { docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} ContainingCollectionView={undefined} - ContainingCollectionDoc={this.props.containingCollection} + ContainingCollectionDoc={this.props.treeView.props.Document} />; return <>
{ ; } - renderDocument = (asText: boolean) => { + renderEmbeddedDocument = (asText: boolean) => { const panelWidth = asText || StrCast(Doc.LayoutField(this.layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.expandPanelWidth; const panelHeight = asText ? this.rtfOutlineHeight : StrCast(Doc.LayoutField(this.layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.expandPanelHeight; return this._dref = r)} @@ -599,14 +614,14 @@ export class TreeView extends React.Component { NativeWidth={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} NativeHeight={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined} fitToBox={!asText && this.isCollectionDoc !== undefined} + hideTitle={asText} LayoutTemplateString={asText ? FormattedTextBox.LayoutString("text") : undefined} focus={asText ? this.refocus : returnFalse} dontRegisterView={asText ? undefined : this.props.dontRegisterView} ScreenToLocalTransform={this.docTransform} renderDepth={this.props.renderDepth + 1} rootSelected={returnTrue} - treeViewDoc={undefined} - styleProvider={this.styleProvider} + styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -627,7 +642,7 @@ export class TreeView extends React.Component { @computed get renderDocumentAsHeader() { return <> {this.renderBullet} - {this.renderDocument(true)} + {this.renderEmbeddedDocument(true)} ; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index c81bd068c..473363292 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -103,7 +103,7 @@ export class CollectionFreeFormLinkView extends React.Component - c.a.props.Document.type === DocumentType.LINK - && !c.a.props.treeViewDoc?.treeViewHideLinkLines && !c.b.props.treeViewDoc?.treeViewHideLinkLines - ).map(c => ); + return connections.filter(c => c.a.props.Document.type === DocumentType.LINK) + .map(c => ); } render() { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 502f874e0..9449f92ab 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -90,6 +90,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView layoutKey?: string; freezeDimensions?: boolean; + hideTitle?: boolean; fitToBox?: boolean; treeViewDoc?: Doc; dragDivName?: string; @@ -103,7 +104,6 @@ export interface DocumentViewProps extends DocumentViewSharedProps { onPointerDown?: () => ScriptField; onPointerUp?: () => ScriptField; setupDragLines?: (snapToDraggedDoc: boolean) => void; - forceHideLinkButton?: () => boolean; } @observer @@ -129,7 +129,7 @@ export class DocumentView extends DocComponent(Docu public get LayoutFieldKey() { return this.props.layoutKey || Doc.LayoutFieldKey(this.layoutDoc); } @computed get ShowTitle() { return StrCast(this.layoutDoc._showTitle, - !Doc.IsSystem(this.layoutDoc) && this.rootDoc.type === DocumentType.RTF && !this.props.treeViewDoc && !this.rootDoc.presentationTargetDoc ? + !Doc.IsSystem(this.layoutDoc) && this.rootDoc.type === DocumentType.RTF && !this.rootDoc.presentationTargetDoc ? (this.dataDoc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : undefined); } @@ -813,7 +813,7 @@ export class DocumentView extends DocComponent(Docu if (!this.Document.annotationOn) { const options = cm.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; - !this.props.treeViewDoc && this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform && optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); + this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform && optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); @@ -957,8 +957,7 @@ export class DocumentView extends DocComponent(Docu onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} - {/* {this.allAnchors} */} - {this.props.forceHideLinkButton?.() || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) : + {this.props.styleProvider?.(this.layoutDoc, this.props, "hideLinkButton") || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) : }
); @@ -980,17 +979,17 @@ export class DocumentView extends DocComponent(Docu hideLinkAnchor = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && (doc.hidden = true), true) anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; + anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { + if (property === "backgroundColor") return props?.LayoutTemplateString ? "transparent" : this.props.styleProvider?.(doc, props, "backgroundColor"); + if (property === "hideLinkButton") return true; + } @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } - anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { - return property === "backgroundColor" ? "transparent" : undefined; - } @computed get allAnchors() { TraceMobx(); if (this.props.LayoutTemplateString?.includes("LinkAnchorBox")) return null; - if ((this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots - this.layoutDoc.presBox || // presentationbox nodes + if (this.layoutDoc.presBox || // presentationbox nodes this.rootDoc.type === DocumentType.LINK || this.props.dontRegisterView) {// view that are not registered return (null); @@ -1006,7 +1005,6 @@ export class DocumentView extends DocComponent(Docu PanelHeight={this.anchorPanelHeight} ContentScaling={returnOne} dontRegisterView={false} - forceHideLinkButton={returnTrue} styleProvider={this.anchorStyleProvider} removeDocument={this.hideLinkAnchor} pointerEvents={"none"} @@ -1016,17 +1014,6 @@ export class DocumentView extends DocComponent(Docu } @computed get innards() { TraceMobx(); - const pos = this.props.relative ? "relative" : undefined; - if (this.props.treeViewDoc && !this.props.LayoutTemplateString?.includes("LinkAnchorBox")) { // this happens when the document is a tree view label (but not an anchor dot) - return
- {StrCast(this.props.Document.title)} - {this.allAnchors} -
; - } - const showTitleHover = StrCast(this.layoutDoc._showTitleHover); const showCaption = StrCast(this.layoutDoc._showCaption); const captionView = (!showCaption ? (null) : @@ -1060,7 +1047,7 @@ export class DocumentView extends DocComponent(Docu })} />
); - return !this.ShowTitle && !showCaption ? + return this.props.hideTitle || (!this.ShowTitle && !showCaption) ? this.contents :
{this.showOverlappingTitle ? <> {this.contents} {titleView} : <> {titleView} {this.contents} } @@ -1094,19 +1081,37 @@ export class DocumentView extends DocComponent(Docu 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, "hidden")) return null; - const background = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor"); + return this.props.styleProvider?.(this.rootDoc, this.props, "docContents") ?? +
+ {this.innards} + {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
: (null)} + {this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations") || (null)} +
; + } + render() { const borderRounding = this.props.styleProvider?.(this.layoutDoc, this.props, "borderRounding"); - const opacity = this.props.styleProvider?.(this.layoutDoc, this.props, "opacity"); 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 highlightColors = CurrentUserUtils.ActiveDashboard?.darkScheme ? + const highlightColor = (CurrentUserUtils.ActiveDashboard?.darkScheme ? ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] : - ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"]; - const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"]; + ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"])[highlightIndex]; + const highlightStyle = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"][highlightIndex]; let highlighting = highlightIndex && ![DocumentType.FONTICON, DocumentType.INK].includes(this.layoutDoc.type as any) && this.layoutDoc._viewType !== CollectionViewType.Linear; highlighting = highlighting && this.props.focus !== emptyFunction && this.layoutDoc.title !== "[pres element template]"; // bcz: hack to turn off highlighting onsidebar panel documents. need to flag a document as not highlightable in a more direct way - const topmost = this.topMost ? "-topmost" : ""; - return this.props.styleProvider?.(this.rootDoc, this.props, "docContents") ??
(Docu !entered && Doc.UnBrushDoc(this.props.Document); })} style={{ - transformOrigin: this._animateScalingTo ? "center center" : undefined, - transform: this._animateScalingTo ? `scale(${this._animateScalingTo})` : undefined, - transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : `transform 0.5s ease-${this._animateScalingTo < 1 ? "in" : "out"}`, - pointerEvents: this.pointerEvents, - color: StrCast(this.layoutDoc.color, "inherit"), - outline: highlighting && !borderRounding ? `${highlightColors[highlightIndex]} ${highlightStyles[highlightIndex]} ${highlightIndex}px` : "solid 0px", - border: highlighting && borderRounding && highlightStyles[highlightIndex] === "dashed" ? `${highlightStyles[highlightIndex]} ${highlightColors[highlightIndex]} ${highlightIndex}px` : undefined, - boxShadow: highlighting && borderRounding && highlightStyles[highlightIndex] !== "dashed" ? `0 0 0 ${highlightIndex}px ${highlightColors[highlightIndex]}` : - this.Document.isLinkButton && !this.props.dontRegisterView && !this.props.forceHideLinkButton?.() ? + 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, "hideLinkButton") ? StrCast(this.layoutDoc._linkButtonShadow, "lightblue 0em 0em 1em") : this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined, - background, - opacity, - fontFamily: StrCast(this.Document._fontFamily, "inherit"), - fontSize: !this.props.treeViewDoc ? Cast(this.Document._fontSize, "string", null) : undefined, - }}> - {this.innards} - {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
: (null)} - {!this.props.treeViewDoc && this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations") || (null)} -
; - } - render() { - return
+ }} + > {PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc}
; } diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index 7ce9abf27..b5b53501d 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -4,7 +4,7 @@ import { Doc, DocListCast } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { makeInterface } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; -import { Utils, setupMoveUpEvents, emptyFunction } from '../../../Utils'; +import { Utils, setupMoveUpEvents, emptyFunction, OmitKeys } from '../../../Utils'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import { ViewBoxBaseComponent } from "../DocComponent"; @@ -117,7 +117,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent Date: Fri, 11 Dec 2020 02:48:36 -0500 Subject: fixed pointerevents set through styleProvider. fixed crash when color strings use uppercase. fixed empty text boxes to set default font size/family --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/collections/TabDocView.tsx | 27 ++++++++++------------ src/client/views/nodes/DocumentView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 6 ++--- 5 files changed, 18 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8a5f0fb5e..2f190fbfd 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -711,7 +711,7 @@ export namespace Docs { export function LinkDocument(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, options: DocumentOptions = {}, id?: string) { const doc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { dontRegisterChildViews: true, - isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightBlue", // lightBlue is default color for linking dot and link documents text comment area + isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area treeViewExpandedView: "fields", removeDropProperties: new List(["_layers", "isLinkButton"]), ...options }, id); const linkDocProto = Doc.GetProto(doc); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 676e7ce3e..2a7e95666 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -252,7 +252,7 @@ export class CurrentUserUtils { doc["template-note-Idea"] = new PrefetchProxy(noteView); } if (doc["template-note-Topic"] === undefined) { - const noteView = Docs.Create.TextDocument("", { title: "text", style: "Topic", backgroundColor: "lightBlue", system: true }); + const noteView = Docs.Create.TextDocument("", { title: "text", style: "Topic", backgroundColor: "lightblue", system: true }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic"); doc["template-note-Topic"] = new PrefetchProxy(noteView); } diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 0fac68582..ba8b5e418 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -433,7 +433,7 @@ export class TabDocView extends React.Component { // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // public static styleProvider = (doc: Opt, props: Opt, property: string): any => { - switch (property) { + switch (property.split(":")[0]) { case "docContents": return undefined; case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey"; case "opacity": return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); @@ -459,7 +459,7 @@ export class TabDocView extends React.Component { default: docColor = TabDocView.darkScheme ? "black" : "white"; break; } } - if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor).fade(0.5).toString(); + if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor.toLowerCase()).fade(0.5).toString(); return docColor; } case "boxShadow": { @@ -475,15 +475,14 @@ export class TabDocView extends React.Component { StrCast(doc.boxShadow, ""); } } - default: - if (property.startsWith("pointerEvents")) { - const layer = doc && props?.layerProvider?.(doc); - if (props?.styleProvider?.(doc, props, "opacity") === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; - if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none"; - if (doc?.type !== DocumentType.INK && layer === true) return "all"; - return undefined; - } - if (property.startsWith("decorations") && props?.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform) { + case "pointerEvents": + const layer = doc && props?.layerProvider?.(doc); + if (props?.styleProvider?.(doc, props, "opacity") === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; + if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none"; + if (doc?.type !== DocumentType.INK && layer === true) return "all"; + return undefined; + case "decorations": + if (props?.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform) { const isBackground = StrListCast(doc?.layers).includes("background"); return doc && (isBackground || property.includes(":selected")) && (props?.renderDepth || 0) > 0 && ((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ? @@ -498,13 +497,11 @@ export class TabDocView extends React.Component { if (doc) { switch (property) { case "docContents": - if (doc.type === DocumentType.COL) return null; const background = doc.type === DocumentType.PDF ? "red" : doc.type === DocumentType.IMG ? "blue" : doc.type === DocumentType.RTF ? "orange" : doc.type === DocumentType.VID ? "purple" : doc.type === DocumentType.WEB ? "yellow" : "gray"; - return
; + return doc.type === DocumentType.COL ? undefined :
; default: - if (property.startsWith("pointerEvents")) return "none"; - return TabDocView.styleProvider(doc, props, property); + return (property.startsWith("pointerEvents")) ? "none" : TabDocView.styleProvider(doc, props, property); } } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 9449f92ab..cbbb27450 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1093,7 +1093,6 @@ export class DocumentView extends DocComponent(Docu transformOrigin: this._animateScalingTo ? "center center" : undefined, transform: this._animateScalingTo ? `scale(${this._animateScalingTo})` : undefined, transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : `transform 0.5s ease-${this._animateScalingTo < 1 ? "in" : "out"}`, - pointerEvents: this.pointerEvents, }}> {this.innards} {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
: (null)} @@ -1124,6 +1123,7 @@ export class DocumentView extends DocComponent(Docu !entered && Doc.UnBrushDoc(this.props.Document); })} 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}` : diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index bfbd7805d..415c8c184 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -270,8 +270,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._pause = false; this.insertTime(); } - !curText && tx.storedMarks?.map(m => m.type.name === "pFontSize" && (Doc.UserDoc().fontSize = this.layoutDoc._fontSize = m.attrs.fontSize)); - !curText && tx.storedMarks?.map(m => m.type.name === "pFontFamily" && (Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily)); + !curText && tx.storedMarks?.filter(m => m.type.name === "pFontSize").map(m => Doc.UserDoc().fontSize = this.layoutDoc._fontSize = (m.attrs.fontSize + "px")); + !curText && tx.storedMarks?.filter(m => m.type.name === "pFontFamily").map(m => Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily); this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText); this.dataDoc[this.props.fieldKey + "-noTemplate"] = true;//(curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, self: this.rootDoc, text: curText }); @@ -1599,7 +1599,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const annotated = DocListCast(this.dataDoc[this.annotationKey]).filter(d => d?.author).length; return !this.props.isSelected() && !(annotated && !this.sidebarWidth()) ? (null) :
; } -- cgit v1.2.3-70-g09d2 From 6346a318634f6d4ebe561a871905982d748bf43e Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 11 Dec 2020 12:25:06 -0500 Subject: converted all style sheet properties to enums. --- src/client/views/MainView.tsx | 13 +- src/client/views/OverlayView.tsx | 3 +- src/client/views/PropertiesView.tsx | 3 +- src/client/views/StyleProvider.scss | 19 +++ src/client/views/StyleProvider.tsx | 153 +++++++++++++++++++++ .../views/collections/CollectionCarouselView.tsx | 3 +- .../views/collections/CollectionStackingView.tsx | 3 +- .../views/collections/CollectionTreeView.tsx | 3 +- src/client/views/collections/CollectionView.tsx | 3 +- src/client/views/collections/TabDocView.tsx | 127 ++--------------- src/client/views/collections/TreeView.tsx | 17 +-- .../collectionFreeForm/CollectionFreeFormView.tsx | 23 ++-- .../collections/collectionFreeForm/MarqueeView.tsx | 4 +- .../collectionGrid/CollectionGridView.tsx | 2 - src/client/views/nodes/AudioBox.tsx | 9 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 11 +- .../views/nodes/ContentFittingDocumentView.tsx | 19 --- src/client/views/nodes/DocHolderBox.tsx | 3 +- src/client/views/nodes/DocumentView.scss | 19 --- src/client/views/nodes/DocumentView.tsx | 39 +++--- src/client/views/nodes/FontIconBox.tsx | 3 +- src/client/views/nodes/LabelBox.tsx | 3 +- src/client/views/nodes/LinkAnchorBox.tsx | 10 +- src/client/views/nodes/LinkBox.tsx | 3 +- src/client/views/nodes/SliderBox.tsx | 3 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 3 +- .../views/presentationview/PresElementBox.tsx | 5 +- 27 files changed, 280 insertions(+), 226 deletions(-) create mode 100644 src/client/views/StyleProvider.scss create mode 100644 src/client/views/StyleProvider.tsx (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 2705d2c34..2cb529317 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -59,6 +59,7 @@ import { TraceMobx } from '../../fields/util'; import { SelectionManager } from '../util/SelectionManager'; import { UndoManager } from '../util/UndoManager'; import { TabDocView } from './collections/TabDocView'; +import { DefaultStyleProvider } from './StyleProvider'; const _global = (window /* browser */ || global /* node */) as any; @observer @@ -319,7 +320,7 @@ export class MainView extends React.Component { PanelHeight={this.getContentsHeight} renderDepth={0} focus={emptyFunction} - styleProvider={TabDocView.styleProvider} + styleProvider={DefaultStyleProvider} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -352,7 +353,7 @@ export class MainView extends React.Component { PanelHeight={this.getContentsHeight} renderDepth={0} focus={emptyFunction} - styleProvider={TabDocView.styleProvider} + styleProvider={DefaultStyleProvider} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} @@ -404,7 +405,7 @@ export class MainView extends React.Component {
- {this.propertiesWidth() < 10 ? (null) : } + {this.propertiesWidth() < 10 ? (null) : }
; } @@ -457,7 +458,7 @@ export class MainView extends React.Component { fieldKey={"data"} dropAction={"alias"} parentActive={returnFalse} - styleProvider={TabDocView.styleProvider} + styleProvider={DefaultStyleProvider} rootSelected={returnTrue} bringToFront={emptyFunction} select={emptyFunction} @@ -532,7 +533,7 @@ export class MainView extends React.Component { pinToPres={emptyFunction} rootSelected={returnTrue} onClick={undefined} - styleProvider={TabDocView.styleProvider} + styleProvider={DefaultStyleProvider} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} ContentScaling={returnOne} @@ -595,7 +596,7 @@ export class MainView extends React.Component { {LinkDescriptionPopup.descriptionPopup ? : null} {DocumentLinksButton.EditLink ? : (null)} - {LinkDocPreview.LinkInfo ? : (null)} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index b7bd88344..124da6016 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -16,6 +16,7 @@ import { DragManager } from "../util/DragManager"; import { List } from "../../fields/List"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { TabDocView } from "./collections/TabDocView"; +import { DefaultStyleProvider } from "./StyleProvider"; export type OverlayDisposer = () => void; @@ -195,7 +196,7 @@ export class OverlayView extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyFunction} - styleProvider={TabDocView.styleProvider} + styleProvider={DefaultStyleProvider} addDocTab={returnFalse} pinToPres={emptyFunction} docFilters={returnEmptyFilter} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 03e0a35ec..eb7df0248 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -29,6 +29,7 @@ import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; import { CollectionViewType } from "./collections/CollectionView"; import { DocumentViewProps, StyleProviderFunc } from "./nodes/DocumentView"; +import { DefaultStyleProvider } from "./StyleProvider"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -269,7 +270,7 @@ export class PropertiesView extends React.Component { DataDoc={this.dataDoc} renderDepth={1} rootSelected={returnFalse} - styleProvider={this.props.styleProvider} + styleProvider={DefaultStyleProvider} fitToBox={true} freezeDimensions={true} dontCenter={"y"} diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss new file mode 100644 index 000000000..df63288f1 --- /dev/null +++ b/src/client/views/StyleProvider.scss @@ -0,0 +1,19 @@ +.styleProvider-lock { + font-size: 12px; + width: 20; + height: 20; + position: absolute; + right: -5; + top: -5; + background: transparent; + pointer-events: all; + opacity: 0.3; + display: flex; + color: gold; + border-radius: 3px; + justify-content: center; + cursor: default; +} +.styleProvider-lock:hover { + opacity:1; +} \ No newline at end of file diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx new file mode 100644 index 000000000..0fe6df84c --- /dev/null +++ b/src/client/views/StyleProvider.tsx @@ -0,0 +1,153 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import 'golden-layout/src/css/goldenlayout-base.css'; +import 'golden-layout/src/css/goldenlayout-dark-theme.css'; +import { runInAction } from 'mobx'; +import { Doc, Opt, StrListCast } from "../../fields/Doc"; +import { List } from '../../fields/List'; +import { BoolCast, Cast, StrCast } from "../../fields/Types"; +import { DocumentType } from '../documents/DocumentTypes'; +import { CurrentUserUtils } from '../util/CurrentUserUtils'; +import { SnappingManager } from '../util/SnappingManager'; +import { UndoManager } from '../util/UndoManager'; +import { CollectionViewType } from './collections/CollectionView'; +import { DocumentViewProps } from "./nodes/DocumentView"; +import "./StyleProvider.scss"; +import React = require("react"); +import Color = require('color'); +import { listSpec } from '../../fields/Schema'; + +export enum StyleLayers { + Background = "background" +} + +export enum StyleProp { + DocContents = "docContents", + Opacity = "opacity", + Hidden = "hidden", + BoxShadow = "boxShadow", + BorderRounding = "borderRounding", + BackgroundColor = "backgroundColor", + WidgetColor = "widgetColor", + LinkBackgroundColor = "linkBackgroundColor", + HideLinkButton = "hideLinkButton", + LinkSource = "linkSource", + PointerEvents = "pointerEvents", + Decorations = "decorations", +} + +function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } + +function toggleBackground(doc: Doc) { + UndoManager.RunInBatch(() => runInAction(() => { + const layers = StrListCast(doc.layers); + if (!layers.includes(StyleLayers.Background)) { + if (!layers.length) doc.layers = new List([StyleLayers.Background]); + else layers.push(StyleLayers.Background); + } + else layers.splice(layers.indexOf(StyleLayers.Background), 1); + doc._overflow = !layers.includes(StyleLayers.Background) ? "visible" : undefined; + if (!layers.includes(StyleLayers.Background)) { + //this.props.bringToFront(doc, true); + // const wid = this.Document[WidthSym](); // change the nativewidth and height if the background is to be a collection that aggregates stuff that is added to it. + // const hgt = this.Document[HeightSym](); + // Doc.SetNativeWidth(this.props.Document[DataSym], wid); + // Doc.SetNativeHeight(this.props.Document[DataSym], hgt); + } + }), "toggleBackground"); +} + +// +// a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab +// +export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { + 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.Hidden: return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); + case StyleProp.BorderRounding: return !doc ? undefined : StrCast(doc._borderRounding, StrCast(doc.borderRounding)); + case StyleProp.BackgroundColor: { + if (Doc.UserDoc().renderStyle === "comic") return undefined; + let docColor: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); + if (!docColor) { + switch (doc?.type) { + case DocumentType.PRESELEMENT: docColor = darkScheme() ? "" : ""; break; + case DocumentType.PRES: docColor = darkScheme() ? "#3e3e3e" : "white"; break; + case DocumentType.FONTICON: docColor = "black"; break; + case DocumentType.RTF: docColor = darkScheme() ? "#2d2d2d" : "#f1efeb"; break; + case DocumentType.LABEL: + case DocumentType.BUTTON: docColor = darkScheme() ? "#2d2d2d" : "lightgray"; break; + case DocumentType.LINK: + case DocumentType.COL: + docColor = Doc.IsSystem(doc) ? (darkScheme() ? "rgb(62,62,62)" : "lightgrey") : + StrListCast(doc.layers).includes(StyleLayers.Background) ? "cyan" : + doc.annotationOn ? "#00000015" : + StrCast((props?.renderDepth || 0) > 0 ? + Doc.UserDoc().activeCollectionNestedBackground : + Doc.UserDoc().activeCollectionBackground); + break; + //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)"; + default: docColor = darkScheme() ? "black" : "white"; break; + } + } + if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor.toLowerCase()).fade(0.5).toString(); + return docColor; + } + case StyleProp.BoxShadow: { + if (!doc || props?.styleProvider?.(doc, props, StyleProp.Opacity) === 0) return undefined; // if it's not visible, then no shadow) + const isBackground = StrListCast(doc.layers).includes(StyleLayers.Background); + switch (doc?.type) { + case DocumentType.COL: return isBackground ? undefined : + `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; + default: + return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow + props?.backgroundHalo?.(doc) && doc.type !== DocumentType.INK ? (`${props?.styleProvider?.(doc, props, StyleProp.BackgroundColor)} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground ? 100 : 50) / props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big + StrCast(doc.boxShadow, ""); + } + } + case StyleProp.PointerEvents: + 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 (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 && + ((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ? +
toggleBackground(doc)}> + +
+ : (null); + } + } +} + +// +// a preliminary semantic-"layering/grouping" mechanism for determining interactive properties of documents +// currently, the provider tests whether the docuemnt's layer field matches the activeLayer field of the tab. +// if it matches, then the document gets pointer events, otherwise it does not. +// +export function DefaultLayerProvider(thisDoc: Doc) { + return (doc: Doc, assign?: boolean) => { + if (doc.z) return true; + if (assign) { + const activeLayer = StrCast(thisDoc?.activeLayer); + if (activeLayer) { + const layers = Cast(doc.layers, listSpec("string"), []); + if (layers.length && !layers.includes(activeLayer)) layers.push(activeLayer); + else if (!layers.length) doc.layers = new List([activeLayer]); + if (activeLayer === "red" || activeLayer === "green" || activeLayer === "blue") doc._backgroundColor = activeLayer; + } + return true; + } else { + if (Doc.AreProtosEqual(doc, thisDoc)) return true; + const layers = Cast(doc.layers, listSpec("string"), []); + if (!layers.length && !thisDoc?.activeLayer) return true; + if (layers.includes(StrCast(thisDoc?.activeLayer))) return true; + return false; + } + }; +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 8b7a46e2f..26c36507a 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -15,6 +15,7 @@ import { ContextMenu } from '../ContextMenu'; import { ObjectField } from '../../../fields/ObjectField'; import { returnFalse, returnZero, OmitKeys } from '../../../Utils'; import { ScriptField } from '../../../fields/ScriptField'; +import { StyleProp } from '../StyleProvider'; type CarouselDocument = makeInterface<[typeof documentSchema, typeof collectionSchema]>; const CarouselDocument = makeInterface(documentSchema, collectionSchema); @@ -65,7 +66,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 8dfb7cefe..2896d244e 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -28,6 +28,7 @@ import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; +import { StyleProp } from "../StyleProvider"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -188,7 +189,7 @@ export class CollectionStackingView extends CollectionSubView this.getDocHeight(doc); const styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { - if (property === "opacity" && doc) { + if (property === StyleProp.Opacity && doc) { if (this.props.childOpacity) { return this.props.childOpacity(); } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 89ed3a147..4e521956d 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -24,6 +24,7 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { TreeView } from "./TreeView"; import React = require("react"); +import { StyleProp } from '../StyleProvider'; export type collectionTreeViewProps = { treeViewHideTitle?: boolean; @@ -211,7 +212,7 @@ export class CollectionTreeView extends CollectionSubView { CollectionView: this, }; const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.treeViewOutlineMode || this.collectionViewType === CollectionViewType.Linear ? undefined : - this.props.styleProvider?.(this.props.Document, this.props, "boxShadow"); + this.props.styleProvider?.(this.props.Document, this.props, StyleProp.BoxShadow); return (
{this.showIsTagged()} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index ba8b5e418..8b5143013 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -32,6 +32,7 @@ import React = require("react"); import { List } from '../../../fields/List'; import { DocumentType } from '../../documents/DocumentTypes'; import Color = require('color'); +import { StyleProp, DefaultStyleProvider, DefaultLayerProvider, StyleLayers } from '../StyleProvider'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -84,7 +85,7 @@ export class TabDocView extends React.Component { toggle.style.borderLeft = "solid 1px black"; toggle.onclick = (e: MouseEvent) => { if (tab.contentItem === tab.header.parent.getActiveContentItem()) { - tab.DashDoc.activeLayer = tab.DashDoc.activeLayer ? undefined : "background"; + tab.DashDoc.activeLayer = tab.DashDoc.activeLayer ? undefined : StyleLayers.Background; } }; tab.element[0].style.borderTopRightRadius = "8px"; @@ -279,7 +280,6 @@ export class TabDocView extends React.Component { @computed get previewPanelCenteringOffset() { return this.nativeWidth() ? (this._panelWidth - this.nativeWidth() * this.ContentScaling()) / 2 : 0; } @computed get widthpercent() { return this.nativeWidth() ? `${(this.nativeWidth() * this.ContentScaling()) / this._panelWidth * 100}% ` : undefined; } @computed get layoutDoc() { return this._document && Doc.Layout(this._document); } - @computed static get darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } // adds a tab to the layout based on the locaiton parameter which can be: // close[:{left,right,top,bottom}] - e.g., "close" will close the tab, "close:left" will close the left tab, @@ -303,7 +303,7 @@ export class TabDocView extends React.Component { } } - @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, TabDocView.styleProvider(this._document, undefined, "backgroundColor"))); } + @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); } @computed get renderBounds() { const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0]; const xbounds = bounds[2] - bounds[0]; @@ -374,7 +374,7 @@ export class TabDocView extends React.Component { {"toggle minimap"}
}>
e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} - style={{ background: TabDocView.styleProvider(this._document, undefined, "backgroundColor") }} > + style={{ background: DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor) }} >
@@ -388,123 +388,22 @@ export class TabDocView extends React.Component { } active = () => this._isActive; - // - // a preliminary semantic-"layering/grouping" mechanism for determining interactive properties of documents - // currently, the provider tests whether the docuemnt's layer field matches the activeLayer field of the tab. - // if it matches, then the document gets pointer events, otherwise it does not. - // - layerProvider = (doc: Doc, assign?: boolean) => { - if (doc.z) return true; - if (assign) { - const activeLayer = StrCast(this._document?.activeLayer); - if (activeLayer) { - const layers = Cast(doc.layers, listSpec("string"), []); - if (layers.length && !layers.includes(activeLayer)) layers.push(activeLayer); - else if (!layers.length) doc.layers = new List([activeLayer]); - if (activeLayer === "red" || activeLayer === "green" || activeLayer === "blue") doc._backgroundColor = activeLayer; - } - return true; - } else { - if (Doc.AreProtosEqual(doc, this._document)) return true; - const layers = Cast(doc.layers, listSpec("string"), []); - if (!layers.length && !this._document?.activeLayer) return true; - if (layers.includes(StrCast(this._document?.activeLayer))) return true; - return false; - } - } - static toggleBackground = undoBatch(action((doc: Doc) => { - const layers = StrListCast(doc.layers); - if (!layers.includes("background")) { - if (!layers.length) doc.layers = new List(["background"]); - else layers.push("background"); - } - else layers.splice(layers.indexOf("background"), 1); - doc._overflow = !layers.includes("background") ? "visible" : undefined; - if (!layers.includes("background")) { - //this.props.bringToFront(doc, true); - // const wid = this.Document[WidthSym](); // change the nativewidth and height if the background is to be a collection that aggregates stuff that is added to it. - // const hgt = this.Document[HeightSym](); - // Doc.SetNativeWidth(this.props.Document[DataSym], wid); - // Doc.SetNativeHeight(this.props.Document[DataSym], hgt); - } - })); - // - // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab - // - public static styleProvider = (doc: Opt, props: Opt, property: string): any => { - switch (property.split(":")[0]) { - case "docContents": return undefined; - case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey"; - case "opacity": return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); - case "hidden": return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); - case "borderRounding": return !doc ? undefined : StrCast(doc._borderRounding, StrCast(doc.borderRounding)); - case "backgroundColor": { - if (Doc.UserDoc().renderStyle === "comic") return undefined; - let docColor: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); - if (!docColor) { - switch (doc?.type) { - case DocumentType.PRESELEMENT: docColor = TabDocView.darkScheme ? "" : ""; break; - case DocumentType.PRES: docColor = TabDocView.darkScheme ? "#3e3e3e" : "white"; break; - case DocumentType.FONTICON: docColor = "black"; break; - case DocumentType.RTF: docColor = TabDocView.darkScheme ? "#2d2d2d" : "#f1efeb"; break; - case DocumentType.LABEL: - case DocumentType.BUTTON: docColor = TabDocView.darkScheme ? "#2d2d2d" : "lightgray"; break; - case DocumentType.LINK: - case DocumentType.COL: - docColor = Doc.IsSystem(doc) ? (TabDocView.darkScheme ? "rgb(62,62,62)" : "lightgrey") : - StrCast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground); - break; - //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)"; - default: docColor = TabDocView.darkScheme ? "black" : "white"; break; - } - } - if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor.toLowerCase()).fade(0.5).toString(); - return docColor; - } - case "boxShadow": { - if (!doc || props?.styleProvider?.(doc, props, "opacity") === 0) return undefined; // if it's not visible, then no shadow) - const isBackground = StrListCast(doc.layers).includes("background"); - switch (doc?.type) { - case DocumentType.COL: return isBackground ? undefined : - `${TabDocView.darkScheme ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; - default: - return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow - props?.backgroundHalo?.(doc) && doc.type !== DocumentType.INK ? (`${props?.styleProvider?.(doc, props, "backgroundColor")} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground ? 100 : 50) / props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent - isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big - StrCast(doc.boxShadow, ""); - } - } - case "pointerEvents": - const layer = doc && props?.layerProvider?.(doc); - if (props?.styleProvider?.(doc, props, "opacity") === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none"; - if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none"; - if (doc?.type !== DocumentType.INK && layer === true) return "all"; - return undefined; - case "decorations": - if (props?.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform) { - const isBackground = StrListCast(doc?.layers).includes("background"); - return doc && (isBackground || property.includes(":selected")) && (props?.renderDepth || 0) > 0 && - ((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ? -
TabDocView.toggleBackground(doc)}> - -
- : (null); - } - } - } public static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (doc) { - switch (property) { - case "docContents": + switch (property.split(":")[0]) { + default: return DefaultStyleProvider(doc, props, property); + case StyleProp.PointerEvents: return "none"; + case StyleProp.DocContents: const background = doc.type === DocumentType.PDF ? "red" : doc.type === DocumentType.IMG ? "blue" : doc.type === DocumentType.RTF ? "orange" : doc.type === DocumentType.VID ? "purple" : doc.type === DocumentType.WEB ? "yellow" : "gray"; - return doc.type === DocumentType.COL ? undefined :
; - default: - return (property.startsWith("pointerEvents")) ? "none" : TabDocView.styleProvider(doc, props, property); + return doc.type === DocumentType.COL ? + undefined : +
; } } } + @computed get layerProvider() { return this._document && DefaultLayerProvider(this._document); } @computed get docView() { TraceMobx(); return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : @@ -526,7 +425,7 @@ export class TabDocView extends React.Component { parentActive={this.active} whenActiveChanged={emptyFunction} focus={this.focusFunc} - styleProvider={TabDocView.styleProvider} + styleProvider={DefaultStyleProvider} addDocTab={this.addDocTab} pinToPres={TabDocView.PinDoc} docFilters={CollectionDockingView.Instance.docFilters} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 53cdca2af..28503a23f 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -29,6 +29,7 @@ import { CollectionTreeView } from './CollectionTreeView'; import { CollectionView, CollectionViewType } from './CollectionView'; import "./TreeView.scss"; import React = require("react"); +import { StyleProp } from '../StyleProvider'; export interface TreeViewProps { document: Doc; @@ -441,7 +442,7 @@ export class TreeView extends React.Component { return
@@ -499,22 +500,22 @@ export class TreeView extends React.Component { titleStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { if (!doc || doc !== this.doc) return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView - switch (property) { - case "opacity": return this.outlineMode ? undefined : 1; - case "backgroundColor": return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); - case "docContents": return !props?.treeViewDoc ? (null) : + switch (property.split(":")[0]) { + case StyleProp.Opacity: return this.outlineMode ? undefined : 1; + case StyleProp.BackgroundColor: return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); + case StyleProp.DocContents: return !props?.treeViewDoc ? (null) :
{StrCast(doc?.title)}
; - default: if (property.startsWith("decorations")) return (null); + case StyleProp.Decorations: return (null); } } embeddedStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { - if (property.startsWith("decorations")) return (null); + if (property.startsWith(StyleProp.Decorations)) return (null); return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView } onKeyDown = (e: React.KeyboardEvent) => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 75411b3c5..cfc5e8b61 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -47,6 +47,7 @@ import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; +import { StyleProp, StyleLayers } from "../../StyleProvider"; export const panZoomSchema = createSchema({ _panX: "number", @@ -246,7 +247,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, property: string) => { - let clusterColor = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 - if (property !== "backgroundColor") return clusterColor; + let styleProp = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 + if (property !== StyleProp.BackgroundColor) return styleProp; const cluster = NumCast(doc?.cluster); if (this.Document._useClusters) { if (this._clusterSets.length <= cluster) { @@ -413,14 +414,14 @@ export class CollectionFreeFormView extends CollectionSubView s.backgroundColor); // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document - set && set.filter(s => !Cast(s.layers, listSpec("string"), []).includes("background")).map(s => clusterColor = StrCast(s.backgroundColor)); - set && set.filter(s => Cast(s.layers, listSpec("string"), []).includes("background")).map(s => clusterColor = StrCast(s.backgroundColor)); + set && set.filter(s => !StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); + set && set.filter(s => StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); } - } else if (doc && NumCast(doc.group, -1) !== -1) clusterColor = "gray"; - return clusterColor; + } else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; + return styleProp; } @action @@ -870,7 +871,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (sendToBack || Cast(doc.layers, listSpec("string"), []).includes("background")) { + if (sendToBack || StrListCast(doc.layers).includes(StyleLayers.Background)) { doc.zIndex = 0; } else if (doc.isInkMask) { doc.zIndex = 5000; @@ -1053,7 +1054,7 @@ export class CollectionFreeFormView extends CollectionSubView intersectRect(docDims(doc), rect); const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) }; - let snappableDocs = activeDocs.filter(doc => !StrListCast(doc.layers).includes("background") && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to + let snappableDocs = activeDocs.filter(doc => !StrListCast(doc.layers).includes(StyleLayers.Background) && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect))); // if not, see if there are background docs to snap to !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z !== undefined && isDocInView(doc, otherBounds))); // if not, then why not snap to floating docs diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 52310d628..f1f190bff 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -27,6 +27,7 @@ import { CollectionView } from "../CollectionView"; import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu"; import "./MarqueeView.scss"; import React = require("react"); +import { StyleLayers } from "../../StyleProvider"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -349,7 +350,6 @@ export class MarqueeView extends React.Component(layers); - newCollection.backgroundColor = this.props.isAnnotationOverlay ? "#00000015" : layers.includes("background") ? "cyan" : undefined; newCollection._width = this.Bounds.width; newCollection._height = this.Bounds.height; newCollection.x = this.Bounds.left; @@ -523,7 +523,7 @@ export class MarqueeView extends React.Component { - const newCollection = this.getCollection([], undefined, ["background"]); + const newCollection = this.getCollection([], undefined, [StyleLayers.Background]); this.props.addDocument?.(newCollection); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index bef197bee..1a4eb8b7b 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -165,8 +165,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} Document={layout} DataDoc={layout.resolvedDataDoc as Doc} - styleProvider={this.props.styleProvider} - ContainingCollectionDoc={this.props.Document} PanelWidth={width} PanelHeight={height} ContentScaling={returnOne} diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index c89e21312..b495cdd1b 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -29,6 +29,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment"; import { LinkAnchorBox } from "./LinkAnchorBox"; import { LinkDocPreview } from "./LinkDocPreview"; +import { StyleProp } from "../StyleProvider"; declare class MediaRecorder { // whatever MediaRecorder has @@ -538,7 +539,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox.RangeScript; labelScript = () => AudioBox.LabelScript; - + static audioStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + if (property === StyleProp.BackgroundColor) return "transparent"; + if (property === StyleProp.PointerEvents) return "none"; + } render() { const interactive = SnappingManager.GetIsDragging() || this.active() ? "-interactive" : ""; this._first = true; // for indicating the first marker that is rendered @@ -637,8 +641,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent, props: Opt, property: string) => property === "backgroundColor" ? "transparent" : undefined} - pointerEvents={"none"} + styleProvider={AudioBox.audioStyleProvider} LayoutTemplate={undefined} LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)} /> diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 46c311350..1b47f4551 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -16,6 +16,7 @@ import "./CollectionFreeFormDocumentView.scss"; import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import React = require("react"); +import { StyleProp } from "../StyleProvider"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; @@ -59,7 +60,7 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { - if (property === "opacity" && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children + if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children return this.props.styleProvider?.(doc, props, property); } @@ -147,13 +148,13 @@ export class CollectionFreeFormDocumentView extends DocComponent this; @computed get pointerEvents() { if (this.props.pointerEvents === "none") return "none"; - return this.props.styleProvider?.(this.Document, this.props, !this._contentView?.docView?.isSelected() ? "pointerEvents:selected" : "pointerEvents"); + return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (!this._contentView?.docView?.isSelected() ? ":selected" : "")); } render() { TraceMobx(); - const backgroundColor = this.props.styleProvider?.(this.Document, this.props, "backgroundColor"); - const borderRadius = this.props.styleProvider?.(this.Document, this.props, "borderRounding"); - const boxShadow = this.props.styleProvider?.(this.Document, this.props, "boxShadow"); + const backgroundColor = this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor); + const borderRadius = this.props.styleProvider?.(this.Document, this.props, StyleProp.BorderRounding); + const boxShadow = this.props.styleProvider?.(this.Document, this.props, StyleProp.BoxShadow); const divProps: DocumentViewProps = { ...this.props, CollectionFreeFormDocumentView: this.returnThis, diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 7b767a10a..ae0275c3d 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -67,32 +67,13 @@ export class ContentFittingDocumentView extends React.Component this.docView = r)} - Document={this.props.Document} - DataDoc={this.props.DataDoc} LayoutTemplate={this.props.LayoutTemplate} - LayoutTemplateString={this.props.LayoutTemplateString} PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} ContentScaling={returnOne} - fitToBox={this.props.fitToBox} - layoutKey={this.props.layoutKey} - dropAction={this.props.dropAction} - onClick={this.props.onClick} - styleProvider={this.props.styleProvider} - addDocument={this.props.addDocument} - removeDocument={this.props.removeDocument} - moveDocument={this.props.moveDocument} - whenActiveChanged={this.props.whenActiveChanged} - ContainingCollectionView={this.props.ContainingCollectionView} - ContainingCollectionDoc={this.props.ContainingCollectionDoc} - addDocTab={this.props.addDocTab} - pinToPres={this.props.pinToPres} - parentActive={this.props.parentActive} ScreenToLocalTransform={this.getTransform} - renderDepth={this.props.renderDepth} focus={this.props.focus || emptyFunction} bringToFront={emptyFunction} - dontRegisterView={this.props.dontRegisterView} />
)}
); diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx index e14093e70..1bc7bc8d7 100644 --- a/src/client/views/nodes/DocHolderBox.tsx +++ b/src/client/views/nodes/DocHolderBox.tsx @@ -19,6 +19,7 @@ import "./DocHolderBox.scss"; import { DocumentView } from "./DocumentView"; import { FieldView, FieldViewProps } from "./FieldView"; import React = require("react"); +import { StyleProp } from "../StyleProvider"; type DocHolderBoxSchema = makeInterface<[typeof documentSchema, typeof collectionSchema]>; const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); @@ -182,7 +183,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; - export interface DocumentViewSharedProps { ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; @@ -118,6 +118,7 @@ export class DocumentView extends DocComponent(Docu private _doubleTap = false; private _mainCont = React.createRef(); private _titleRef = React.createRef(); + private _timeout: NodeJS.Timeout | undefined; private _dropDisposer?: DragManager.DragDropDisposer; private _gestureEventDisposer?: GestureUtils.GestureEventDisposer; private _holdDisposer?: InteractionUtils.MultiTouchEventDisposer; @@ -310,14 +311,12 @@ export class DocumentView extends DocComponent(Docu } } - _timeout: NodeJS.Timeout | undefined; - onClick = action((e: React.MouseEvent | React.PointerEvent) => { if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && this.props.renderDepth >= 0 && (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { let stopPropagate = true; let preventDefault = true; - !Cast(this.props.Document.layers, listSpec("string"), []).includes("background") && (this.rootDoc._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : this.rootDoc._raiseWhenDragged) && this.props.bringToFront(this.rootDoc); + !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._timeout) { clearTimeout(this._timeout); @@ -957,7 +956,7 @@ export class DocumentView extends DocComponent(Docu onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} - {this.props.styleProvider?.(this.layoutDoc, this.props, "hideLinkButton") || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) : + {this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkButton) || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) : }
); @@ -980,8 +979,13 @@ export class DocumentView extends DocComponent(Docu anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { - if (property === "backgroundColor") return props?.LayoutTemplateString ? "transparent" : this.props.styleProvider?.(doc, props, "backgroundColor"); - if (property === "hideLinkButton") return true; + switch (property.split(":")[0]) { + case StyleProp.BackgroundColor: return "transparent"; + case StyleProp.LinkBackgroundColor: return this.props.styleProvider?.(doc, props, StyleProp.BackgroundColor); + case StyleProp.HideLinkButton: return true; + case StyleProp.PointerEvents: return "none"; + case StyleProp.LinkSource: return this.props.Document; + } } @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @@ -999,15 +1003,12 @@ export class DocumentView extends DocComponent(Docu
); @@ -1056,7 +1057,7 @@ export class DocumentView extends DocComponent(Docu } @computed get pointerEvents() { if (this.props.pointerEvents === "none") return "none"; - return this.props.styleProvider?.(this.Document, this.props, this.isSelected() ? "pointerEvents:selected" : "pointerEvents"); + return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (this.isSelected() ? ":selected" : "")); } @undoBatch @action @@ -1080,13 +1081,13 @@ export class DocumentView extends DocComponent(Docu 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, "hidden")) return null; - return this.props.styleProvider?.(this.rootDoc, this.props, "docContents") ?? + if (this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Hidden)) return null; + return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.DocContents) ??
(Docu }}> {this.innards} {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
: (null)} - {this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations") || (null)} + {this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Decorations + (this.isSelected() ? ":selected" : "")) || (null)}
; } render() { - const borderRounding = this.props.styleProvider?.(this.layoutDoc, this.props, "borderRounding"); + 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"] : @@ -1127,7 +1128,7 @@ export class DocumentView extends DocComponent(Docu 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, "hideLinkButton") ? + this.Document.isLinkButton && !this.props.dontRegisterView && !this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.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/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index a1bb0604e..000c72e94 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -14,6 +14,7 @@ import { ScriptField } from '../../../fields/ScriptField'; import { Tooltip } from '@material-ui/core'; import { DragManager } from '../../util/DragManager'; import { GetEffectiveAcl } from '../../../fields/util'; +import { StyleProp } from '../StyleProvider'; const FontIconSchema = createSchema({ icon: "string", }); @@ -61,7 +62,7 @@ export class FontIconBox extends DocComponent( render() { const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); const color = StrCast(this.layoutDoc.color, this._foregroundColor); - const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, "backgroundColor"); + const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const shape = StrCast(this.layoutDoc.iconShape, label ? "round" : "circle"); const icon = StrCast(this.dataDoc.icon, "user") as any; const presSize = shape === 'round' ? 25 : 30; diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index dd751b802..bc2090a33 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -13,6 +13,7 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxBaseComponent } from '../DocComponent'; import { FieldView, FieldViewProps } from './FieldView'; import './LabelBox.scss'; +import { StyleProp } from '../StyleProvider'; const LabelSchema = createSchema({}); @@ -72,7 +73,7 @@ export class LabelBox extends ViewBoxBaseComponent this._mouseOver = false)} onMouseOver={action(() => this._mouseOver = true)} ref={this.createDropTarget} onContextMenu={this.specificContextMenu} - style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, "boxShadow") }}> + style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow) }}>
LinkDocPreview.LinkInfo = undefined)} onPointerEnter={action(e => LinkDocPreview.LinkInfo = { addDocTab: this.props.addDocTab, - linkSrc: this.props.ContainingCollectionDoc!, + linkSrc: linkSource, linkDoc: this.rootDoc, Location: [e.clientX, e.clientY + 20] })} onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu} ref={this._ref} style={{ - background: c, + background, left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`, top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`, transform: `scale(${anchorScale / this.props.ContentScaling()})` diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index b3fd13a77..a12a23dff 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -8,6 +8,7 @@ import { ViewBoxBaseComponent } from "../DocComponent"; import { FieldView, FieldViewProps } from './FieldView'; import "./LinkBox.scss"; import { Cast } from "../../../fields/Types"; +import { StyleProp } from "../StyleProvider"; type LinkDocument = makeInterface<[typeof documentSchema]>; const LinkDocument = makeInterface(documentSchema); @@ -17,7 +18,7 @@ export class LinkBox extends ViewBoxBaseComponent( public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkBox, fieldKey); } render() { return
+ style={{ background: this.props.styleProvider?.(this.props.Document, this.props, StyleProp.BackgroundColor) }} > e.stopPropagation()} - style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, "boxShadow") }}> + style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow) }}>
Opt; // bcz: hack: notifies the text document when the container has made a link. allows the text doc to react and setup a hyeprlink for any selected text @@ -1599,7 +1600,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const annotated = DocListCast(this.dataDoc[this.annotationKey]).filter(d => d?.author).length; return !this.props.isSelected() && !(annotated && !this.sidebarWidth()) ? (null) :
; } diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 45d943bff..3b6b0259d 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -22,6 +22,7 @@ import { undoBatch } from "../../util/UndoManager"; import { EditableView } from "../EditableView"; import { DocumentManager } from "../../util/DocumentManager"; import { DocumentViewProps } from "../nodes/DocumentView"; +import { StyleProp } from "../StyleProvider"; export const presSchema = createSchema({ presentationTargetDoc: Doc, @@ -78,7 +79,7 @@ export class PresElementBox extends ViewBoxBaseComponent Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); embedWidth = (): number => this.props.PanelWidth() - 35; styleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { - if (property === "opacity") return 1; + if (property === StyleProp.Opacity) return 1; return this.props.styleProvider?.(doc, props, property); } /** @@ -326,7 +327,7 @@ export class PresElementBox extends ViewBoxBaseComponent} {miniView ? (null) :
-- cgit v1.2.3-70-g09d2 From fafd62df0a918a14ecc90d99236e5a87918646e1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 11 Dec 2020 14:43:51 -0500 Subject: got rid of ChromeHeight and replaced with HeaderMargin in style provider. made text headers not overlap the tet itself. --- src/client/views/OverlayView.tsx | 1 - src/client/views/StyleProvider.tsx | 38 +++++---- .../views/collections/CollectionStackingView.tsx | 6 +- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 7 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 - src/client/views/nodes/DocumentView.tsx | 93 +++++++++++----------- src/client/views/nodes/LinkBox.tsx | 1 - .../views/nodes/formattedText/FormattedTextBox.tsx | 9 ++- 9 files changed, 79 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 124da6016..ee1af8b13 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -183,7 +183,6 @@ export class OverlayView extends React.Component { return
+ } {openIcon}
e.preventDefault()} />
e.preventDefault()} /> -- cgit v1.2.3-70-g09d2 From f3f93e61f3914bd9fd6e8098a99e552f7860bc5f Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 16:56:14 -0500 Subject: fixed displaying items (images,et) in treeViews to indent properly. Fixed bounds of contentfittingviews in treeViews to be correct. --- .../views/collections/CollectionTreeView.scss | 4 ++ src/client/views/collections/TreeView.scss | 9 ---- src/client/views/collections/TreeView.tsx | 60 ++++++++++------------ src/client/views/pdf/PDFViewer.tsx | 4 +- 4 files changed, 33 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index c5add7cfb..650fb019d 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -23,6 +23,10 @@ list-style: none; padding-left: 20px; margin-bottom: 1px; // otherwise vertical scrollbars may pop up for no apparent reason.... + .contentFittingDocumentView { + width: unset; + height: unset; + } } diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index cc6267f45..816dc0ffa 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -65,15 +65,6 @@ cursor: pointer; } -.treeView-borderoutline { - ul { - .contentFittingDocumentView { - width: unset; - height: unset; - } - } -} - .treeView-borderoutline, .treeView-border { display: flex; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 5982934ff..843bec6de 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -409,12 +409,13 @@ export class TreeView extends React.Component { [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView)} ; } else if (this.treeViewExpandedView === "fields") { - return
    - {this.expandedField} -
; - } else { - return this.renderEmbeddedDocument(false); + return
    +
    + {this.expandedField} +
    +
; } + return
    {this.renderEmbeddedDocument(false)}
; } get onCheckedClick() { return this.doc.type === DocumentType.COL ? undefined : this.props.onCheckedClick?.() ?? ScriptCast(this.doc.onCheckedClick); } @@ -583,15 +584,18 @@ export class TreeView extends React.Component { } renderBulletHeader = (contents: JSX.Element) => { - return
- {contents} -
; + return <> +
+ {contents} +
+ {this.renderBorder} + ; } // renders the text version of a document as the header (e.g., useful for Slide views where the "") @@ -668,24 +672,16 @@ export class TreeView extends React.Component { else this._editMaxWidth = ""; const hideTitle = this.doc.treeViewHideHeader || this.outlineMode; - return hideTitle && !StrCast(Doc.LayoutField(this.doc)).includes("CollectionView") ? - this.renderContent - : -
this.props.active(true) && SelectionManager.DeselectAll()} - onKeyDown={this.onKeyDown}> - {hideTitle ? -
  • - {this.renderBulletHeader(this.renderDocumentAsHeader)} - {this.renderBorder} -
  • : -
  • - {this.renderBulletHeader(this.renderTitleAsHeader)} - {this.renderBorder} -
  • - } -
    ; + return
    this.props.active(true) && SelectionManager.DeselectAll()} + onKeyDown={this.onKeyDown}> +
  • + {hideTitle && this.doc.type !== DocumentType.RTF ? + this.renderEmbeddedDocument(false) : + this.renderBulletHeader(hideTitle ? this.renderDocumentAsHeader : this.renderTitleAsHeader)} +
  • +
    ; } public static sortDocs(childDocs: Doc[], criterion: string | undefined) { diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 199b77408..6b7a93747 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -23,11 +23,10 @@ import { CompiledScript, CompileScript } from "../../util/Scripting"; import { SelectionManager } from "../../util/SelectionManager"; import { SharingManager } from "../../util/SharingManager"; import { SnappingManager } from "../../util/SnappingManager"; -import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; -import { CollectionView } from "../collections/CollectionView"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; +import { FieldViewProps } from "../nodes/FieldView"; import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; import { FormattedTextBoxComment } from "../nodes/formattedText/FormattedTextBoxComment"; import { LinkDocPreview } from "../nodes/LinkDocPreview"; @@ -36,7 +35,6 @@ import { PDFMenu } from "./PDFMenu"; import "./PDFViewer.scss"; const pdfjs = require('pdfjs-dist/es5/build/pdf.js'); import React = require("react"); -import { FieldViewProps } from "../nodes/FieldView"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); const _global = (window /* browser */ || global /* node */) as any; -- cgit v1.2.3-70-g09d2 From 0aa855ab36ead1e4669f25e2a3604e8941cf2075 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 18:38:04 -0500 Subject: fixed screenToLocal for documents within ContentFittingDoc collections. fixed embedding documents in texst docs. --- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/nodes/ContentFittingDocumentView.tsx | 16 ++++++++++++++-- src/client/views/nodes/DocumentView.tsx | 2 ++ src/client/views/nodes/formattedText/RichTextSchema.tsx | 3 ++- 4 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 9e81e108e..d3b83352e 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -69,7 +69,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b Doc.AreProtosEqual(documentView.props.Document, Doc.UserDoc())) { return bounds; } - const transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse(); + const transform = (documentView.props.ScreenToLocalTransform().scale(documentView.LocalScaling)).inverse(); var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); if (documentView.props.LayoutTemplateString?.includes("LinkAnchorBox")) { diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index e632f0e19..fed857c83 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -1,12 +1,13 @@ import React = require("react"); import { computed, observable, action } from "mobx"; import { observer } from "mobx-react"; -import { Doc } from "../../../fields/Doc"; +import { Doc, WidthSym, HeightSym } from "../../../fields/Doc"; import { TraceMobx } from "../../../fields/util"; import { emptyFunction, OmitKeys, returnVal, returnOne } from "../../../Utils"; import { DocumentView, DocumentViewProps } from "../nodes/DocumentView"; import "./ContentFittingDocumentView.scss"; import { StyleProp } from "../StyleProvider"; +import { StrCast } from "../../../fields/Types"; interface ContentFittingDocumentViewProps { dontCenter?: "x" | "y" | "xy"; @@ -39,8 +40,18 @@ export class ContentFittingDocumentView extends React.Component { + if (this.props.DataDoc) return 1; // this is intended to detect when a document is being rendered inside itself as part of a template, but not as a leaf node where nativeWidth & height would apply. + const layoutStr = (this.props.LayoutTemplateString || StrCast(this.layoutDoc.layout)); + if (this.nativeWidth || layoutStr.includes("FormattedTextBox")) return this.nativeScaling; + + const wscale = this.layoutDoc[WidthSym]() / this.props.PanelWidth(); + const hscale = this.layoutDoc[HeightSym]() / this.props.PanelHeight(); + return this.nativeScaling * Math.max(wscale, hscale); + } + private getTransform = () => this.props.ScreenToLocalTransform(). - translate(this.props.dontCenter?.includes("x") ? 0 : -this.centeringOffset, this.props.dontCenter?.includes("y") ? 0 : -this.centeringYOffset) + translate(this.props.dontCenter?.includes("x") ? 0 : -this.centeringOffset, this.props.dontCenter?.includes("y") ? 0 : -this.centeringYOffset).scale(1 / this.contentFittingScaling()) private get centeringOffset() { return this.nativeWidth && !this.props.Document._fitWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } private get centeringYOffset() { return this.nativeWidth && Math.abs(this.centeringOffset) < 0.001 && this.nativeHeight ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } @@ -64,6 +75,7 @@ export class ContentFittingDocumentView extends React.Component number; LayoutTemplate?: () => Opt; contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; @@ -128,6 +129,7 @@ export class DocumentView extends DocComponent(Docu (this.dataDoc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : undefined); } + @computed get LocalScaling() { return this.props.ContentScaling() * (this.props.contentFittingScaling?.() || 1); } @computed get topMost() { return this.props.renderDepth === 0; } @computed get freezeDimensions() { return this.props.freezeDimensions; } @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.dataDoc, this.freezeDimensions)); } diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx index bb544e5e8..e94829769 100644 --- a/src/client/views/nodes/formattedText/RichTextSchema.tsx +++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx @@ -14,6 +14,7 @@ import { DocumentView } from "../DocumentView"; import { FormattedTextBox } from "./FormattedTextBox"; import React = require("react"); import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; +import { DefaultStyleProvider } from "../../StyleProvider"; export class DashDocView { @@ -147,7 +148,7 @@ export class DashDocView { PanelWidth={finalLayout[WidthSym]} PanelHeight={finalLayout[HeightSym]} focus={this.outerFocus} - styleProvider={returnEmptyString} + styleProvider={DefaultStyleProvider} parentActive={returnFalse} whenActiveChanged={returnFalse} bringToFront={emptyFunction} -- cgit v1.2.3-70-g09d2 From 7f93d584dbd356f61c39cfe6c95647e4df003948 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 19:22:46 -0500 Subject: fixed hitting Esc in text to turn off text options in menu --- .../views/nodes/formattedText/FormattedTextBox.tsx | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 4be49ca47..0beea2bcd 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1530,24 +1530,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (state.selection.empty || !this._rules!.EnteringStyle) { this._rules!.EnteringStyle = false; } + e.stopPropagation(); if (e.key === "Escape") { this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); (document.activeElement as any).blur?.(); SelectionManager.DeselectAll(); - } - e.stopPropagation(); - if (e.key === "Tab" || e.key === "Enter") { - if (e.key === "Enter" && this.layoutDoc._timeStampOnEnter) { - this.insertTime(); + RichTextMenu.Instance.updateMenu(undefined, undefined, undefined); + } else { + if (e.key === "Tab" || e.key === "Enter") { + if (e.key === "Enter" && this.layoutDoc._timeStampOnEnter) { + this.insertTime(); + } + e.preventDefault(); } - e.preventDefault(); - } - if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) { - const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }); - this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark)); + if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) { + const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }); + this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark)); + } + this.startUndoTypingBatch(); } - - this.startUndoTypingBatch(); } ondrop = (eve: React.DragEvent) => { -- cgit v1.2.3-70-g09d2 From f56420c57f5f68af00d175fd81ee8a6b69ac39ae Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 19:49:13 -0500 Subject: fixed rtf sidebar to stay visibnle in outline treeview when inking is on. changed highlighting based on hover for anitmode buttons to test on msft duo w/ touch. --- src/client/views/collections/CollectionMenu.tsx | 6 ++++-- src/client/views/collections/TreeView.scss | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index b2b23115f..ef0c30ff4 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -657,8 +657,10 @@ export class CollectionFreeFormViewChrome extends React.Component {this._draw.map((icon, i) => {this._title[i]}
    } placement="bottom"> - )} diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 816dc0ffa..8468e27df 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -83,7 +83,7 @@ display: none; } .formattedTextBox-cont { - .formattedTextbox-sidebar { + .formattedTextbox-sidebar, .formattedTextbox-sidebar-inking { overflow: visible !important; border-left: unset; } -- cgit v1.2.3-70-g09d2 From d66d362c8baed297842cdcaf3dee0d9eda38dcea Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 20:35:05 -0500 Subject: another attempt to fix document decorations for documents nested in treeviews/stackingviews etc. --- src/client/views/nodes/ContentFittingDocumentView.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index fed857c83..7e5c254f9 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -44,10 +44,7 @@ export class ContentFittingDocumentView extends React.Component this.props.ScreenToLocalTransform(). -- cgit v1.2.3-70-g09d2 From 9ca004669a7882123277eb46cad8e86b28305266 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 22:00:10 -0500 Subject: cleaned up ContentFittingDocumentView --- .../views/nodes/ContentFittingDocumentView.tsx | 33 ++++++++++------------ src/client/views/nodes/DocumentView.tsx | 4 +-- 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 7e5c254f9..122231f47 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -17,9 +17,11 @@ interface ContentFittingDocumentViewProps { export class ContentFittingDocumentView extends React.Component { public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive public ContentRef = React.createRef(); + @observable public docView: DocumentView | undefined | null; + @computed get layoutDoc() { return Doc.Layout(this.props.Document, this.props.LayoutTemplate?.()); } - @computed get nativeWidth() { return !this.layoutDoc._fitWidth && returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } + @computed get nativeWidth() { return this.layoutDoc._fitWidth ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); } @computed get nativeScaling() { if (!this.nativeWidth || !this.nativeHeight) return 1; @@ -40,31 +42,26 @@ export class ContentFittingDocumentView extends React.Component { - if (this.props.DataDoc) return 1; // this is intended to detect when a document is being rendered inside itself as part of a template, but not as a leaf node where nativeWidth & height would apply. - const layoutStr = (this.props.LayoutTemplateString || StrCast(this.layoutDoc.layout)); - if (this.nativeWidth || layoutStr.includes("FormattedTextBox")) return this.nativeScaling; - return 1; - } - - private getTransform = () => this.props.ScreenToLocalTransform(). - translate(this.props.dontCenter?.includes("x") ? 0 : -this.centeringOffset, this.props.dontCenter?.includes("y") ? 0 : -this.centeringYOffset).scale(1 / this.contentFittingScaling()) - private get centeringOffset() { return this.nativeWidth && !this.props.Document._fitWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } - private get centeringYOffset() { return this.nativeWidth && Math.abs(this.centeringOffset) < 0.001 && this.nativeHeight ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } + @computed get Xshift() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } + @computed get YShift() { return this.nativeWidth && this.nativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } + @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } + @computed get centeringY() { return this.props.dontCenter?.includes("y") ? 0 : this.YShift; } PanelWidth = () => this.panelWidth; PanelHeight = () => this.panelHeight; + NativeScaling = () => this.nativeScaling; + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); render() { TraceMobx(); return (
    - {!this.props.Document || !this.props.PanelWidth ? (null) : ( + {!this.props.Document || !this.props.PanelWidth() ? (null) : (
    0.001 && this.nativeWidth ? `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), - width: Math.abs(this.centeringOffset) > 0.001 ? `${100 * (this.props.PanelWidth() - this.centeringOffset * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), + height: Math.abs(this.YShift) > 0.001 ? `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), + width: Math.abs(this.Xshift) > 0.001 ? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), }}> this.docView = r)} @@ -72,8 +69,8 @@ export class ContentFittingDocumentView extends React.Component diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 97937e3e0..c1ba1c73a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -58,7 +58,7 @@ export interface DocumentViewSharedProps { PanelHeight: () => number; NativeWidth?: () => number; NativeHeight?: () => number; - ContentScaling: () => number; + ContentScaling: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal layerProvider?: (doc: Doc, assign?: boolean) => boolean; styleProvider?: StyleProviderFunc; focus: DocFocusFunc; @@ -93,7 +93,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { dragDivName?: string; contentPointerEvents?: string; radialMenu?: String[]; - contentFittingScaling?: () => number; + contentFittingScaling?: () => number;// scaling done outside the document view (eg in ContentFittingDocumentView) to fit contents into panel (needed for ScreenToLocal but not needed by DocumentView to scale its content) LayoutTemplate?: () => Opt; contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; -- cgit v1.2.3-70-g09d2 From 890dd1c3d8d6a00cf3111972c20f7b5b9cb09085 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 22:52:26 -0500 Subject: made conentScaling a DocumentView-only prop --- src/client/views/MainView.tsx | 4 ---- src/client/views/StyleProvider.tsx | 12 ++++++++++-- src/client/views/TemplateMenu.tsx | 1 - src/client/views/collections/CollectionStackingView.tsx | 5 +++-- src/client/views/collections/TabDocView.tsx | 4 ++-- src/client/views/collections/TreeView.tsx | 9 +++++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 7 ++++--- src/client/views/nodes/AudioBox.tsx | 3 ++- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 3 ++- src/client/views/nodes/ColorBox.tsx | 2 +- src/client/views/nodes/ContentFittingDocumentView.tsx | 9 ++++----- src/client/views/nodes/DocumentView.tsx | 7 ++++--- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/KeyValuePair.tsx | 1 - src/client/views/nodes/LinkAnchorBox.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/ScreenshotBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 10 ++++------ src/client/views/nodes/formattedText/FormattedTextBox.tsx | 8 ++++---- src/client/views/pdf/PDFViewer.tsx | 5 ++--- src/client/views/presentationview/PresElementBox.tsx | 2 +- 22 files changed, 53 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index d55d43623..b8c7a1a73 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -465,7 +465,6 @@ export class MainView extends React.Component { removeDocument={this.remButtonDoc} onClick={undefined} ScreenToLocalTransform={this.buttonBarXf} - ContentScaling={returnOne} PanelWidth={this.flyoutWidthFunc} PanelHeight={this.getContentsHeight} renderDepth={0} @@ -529,7 +528,6 @@ export class MainView extends React.Component { styleProvider={DefaultStyleProvider} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} - ContentScaling={returnOne} PanelWidth={this.getPWidth} PanelHeight={this.getPHeight} renderDepth={0} @@ -568,7 +566,6 @@ export class MainView extends React.Component { focus={returnFalse} PanelWidth={() => 500} PanelHeight={() => 800} - ContentScaling={returnOne} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -634,7 +631,6 @@ export class MainView extends React.Component { focus={returnFalse} PanelWidth={() => 500} PanelHeight={() => 800} - ContentScaling={returnOne} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 6a534a979..128c3cb96 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -16,6 +16,7 @@ import React = require("react"); import Color = require('color'); import { listSpec } from '../../fields/Schema'; import { MainView } from './MainView'; +import { FieldViewProps } from './nodes/FieldView'; export enum StyleLayers { Background = "background" @@ -59,10 +60,17 @@ function toggleBackground(doc: Doc) { }), "toggleBackground"); } +export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentViewProps { + if (toBeDetermined.ContentScaling) { + return true; + } + return false; +} + // // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // -export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { +export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { switch (property.split(":")[0]) { case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return darkScheme() ? "lightgrey" : "dimgrey"; @@ -121,7 +129,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { dropAction={undefined} active={returnTrue} parentActive={returnFalse} - ContentScaling={returnOne} bringToFront={emptyFunction} focus={emptyFunction} whenActiveChanged={emptyFunction} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index e8165f673..510e47b20 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -29,6 +29,7 @@ import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewField import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; import { StyleProp } from "../StyleProvider"; +import { FieldViewProps } from "../nodes/FieldView"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -61,7 +62,7 @@ export class CollectionStackingView extends CollectionSubView Transform, width: () => number) { const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc; const height = () => this.getDocHeight(doc); - const styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + const styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === StyleProp.Opacity && doc) { if (this.props.childOpacity) { return this.props.childOpacity(); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 8b5143013..fe929abc5 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -33,6 +33,7 @@ import { List } from '../../../fields/List'; import { DocumentType } from '../../documents/DocumentTypes'; import Color = require('color'); import { StyleProp, DefaultStyleProvider, DefaultLayerProvider, StyleLayers } from '../StyleProvider'; +import { FieldViewProps } from '../nodes/FieldView'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -352,7 +353,6 @@ export class TabDocView extends React.Component { addDocument={returnFalse} moveDocument={returnFalse} removeDocument={returnFalse} - ContentScaling={returnOne} PanelWidth={this.returnMiniSize} PanelHeight={this.returnMiniSize} ScreenToLocalTransform={this.ScreenToLocalTransform} @@ -389,7 +389,7 @@ export class TabDocView extends React.Component { active = () => this._isActive; - public static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { + public static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (doc) { switch (property.split(":")[0]) { default: return DefaultStyleProvider(doc, props, property); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 843bec6de..11ff4ca3b 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -29,7 +29,8 @@ import { CollectionTreeView } from './CollectionTreeView'; import { CollectionView, CollectionViewType } from './CollectionView'; import "./TreeView.scss"; import React = require("react"); -import { StyleProp } from '../StyleProvider'; +import { StyleProp, testDocProps } from '../StyleProvider'; +import { FieldViewProps } from '../nodes/FieldView'; export interface TreeViewProps { document: Doc; @@ -497,13 +498,13 @@ export class TreeView extends React.Component { e.preventDefault(); } } - titleStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { + titleStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { if (!doc || doc !== this.doc) return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView switch (property.split(":")[0]) { case StyleProp.Opacity: return this.outlineMode ? undefined : 1; case StyleProp.BackgroundColor: return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); - case StyleProp.DocContents: return !props?.treeViewDoc ? (null) : + case StyleProp.DocContents: return testDocProps(props) && !props?.treeViewDoc ? (null) :
    { case StyleProp.Decorations: return (null); } } - embeddedStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { + embeddedStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { if (property.startsWith(StyleProp.Decorations)) return (null); return this.props?.treeView?.props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b8576681d..3f7eb24f8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -49,6 +49,7 @@ import React = require("react"); import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; import { StyleProp, StyleLayers } from "../../StyleProvider"; import { DocumentDecorations } from "../../DocumentDecorations"; +import { FieldViewProps } from "../../nodes/FieldView"; export const panZoomSchema = createSchema({ _panX: "number", @@ -116,7 +117,7 @@ export class CollectionFreeFormView extends CollectionSubView 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 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); } @computed get nativeHeight() { return this.fitToContent ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.Document)); } @@ -405,7 +406,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, property: string) => { + getClusterColor = (doc: Opt, props: Opt, property: string) => { let styleProp = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 if (property !== StyleProp.BackgroundColor) return styleProp; const cluster = NumCast(doc?.cluster); @@ -1277,7 +1278,7 @@ export class CollectionFreeFormView extends CollectionSubView { - Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); + Doc.toggleNativeDimensions(this.layoutDoc, 1, this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); } @undoBatch diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index b495cdd1b..7b721786f 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -539,7 +539,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox.RangeScript; labelScript = () => AudioBox.LabelScript; - static audioStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + static audioStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === StyleProp.BackgroundColor) return "transparent"; if (property === StyleProp.PointerEvents) return "none"; } @@ -554,6 +554,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; @@ -59,7 +60,7 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { + styleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children return this.props.styleProvider?.(doc, props, property); } diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index 4fb350b55..52236a648 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -57,7 +57,7 @@ export class ColorBox extends ViewBoxBaseComponent e.button === 0 && !e.ctrlKey && e.stopPropagation()} onClick={e => { (e.nativeEvent as any).stuff = true; e.stopPropagation(); }} - style={{ transform: `scale(${this.props.ContentScaling()})`, width: `${100 / this.props.ContentScaling()}%`, height: `${100 / this.props.ContentScaling()}%` }} > + style={{ width: `${100}%`, height: `${100}%` }} > boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; -export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; +export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; export interface DocumentViewSharedProps { renderDepth: number; Document: Doc; @@ -58,7 +59,6 @@ export interface DocumentViewSharedProps { PanelHeight: () => number; NativeWidth?: () => number; NativeHeight?: () => number; - ContentScaling: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal layerProvider?: (doc: Doc, assign?: boolean) => boolean; styleProvider?: StyleProviderFunc; focus: DocFocusFunc; @@ -93,6 +93,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { dragDivName?: string; contentPointerEvents?: string; radialMenu?: String[]; + ContentScaling: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal contentFittingScaling?: () => number;// scaling done outside the document view (eg in ContentFittingDocumentView) to fit contents into panel (needed for ScreenToLocal but not needed by DocumentView to scale its content) LayoutTemplate?: () => Opt; contextMenuItems?: () => { script: ScriptField, label: string }[]; @@ -972,7 +973,7 @@ export class DocumentView extends DocComponent(Docu hideLinkAnchor = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && (doc.hidden = true), true) anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; - anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { + anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { switch (property.split(":")[0]) { case StyleProp.BackgroundColor: return "transparent"; case StyleProp.HideLinkButton: return true; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 44df00709..374f964e3 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -67,7 +67,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { this._dropDisposer?.(); diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index aaf544c50..3c10cc5fe 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -76,7 +76,6 @@ export class KeyValuePair extends React.Component { PanelHeight: this.props.PanelHeight, addDocTab: returnFalse, pinToPres: returnZero, - ContentScaling: returnOne }; const contents = ; // let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")"; diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index abefc6561..d0048c67b 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -146,7 +146,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent {!this._editing && !this._forceOpen ? (null) : this._isOpen = true} onClose={action(() => this._isOpen = this._forceOpen = this._editing = false)}> diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index a2f3fb2d1..b34c7966b 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -183,7 +183,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 713511a94..456de7ede 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -167,7 +167,7 @@ export class ScreenshotBox extends ViewBoxBaseComponent [this.content]; render() { return (
    + style={{ width: `${100}%`, height: `${100}%` }} >
    [this.youtubeVideoId ? this.youtubeContent : this.content]; render() { return (
    {view}
    @@ -648,14 +648,12 @@ export class WebBox extends ViewBoxAnnotatableComponent this._marqueeing; scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); render() { - const scaling = Number.isFinite(this.props.ContentScaling()) ? this.props.ContentScaling() || 1 : 1; return (
    @@ -663,7 +661,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 0beea2bcd..feb5e63b2 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -581,7 +581,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @undoBatch @action toggleNativeDimensions = () => { - Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); + Doc.toggleNativeDimensions(this.layoutDoc, 1, this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); } public static get DefaultLayout(): Doc | string | undefined { @@ -1609,7 +1609,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp />; } - sidebarContentScaling = () => this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); + sidebarContentScaling = () => NumCast(this.layoutDoc._viewScale, 1); @computed get sidebarCollection() { const fitToBox = this.props.Document._fitToBox; const collectionProps: SubCollectionViewProps & collectionFreeformViewProps = { @@ -1647,13 +1647,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); - sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1)); + sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1)); @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } render() { TraceMobx(); const selected = this.props.isSelected(); const active = this.active(); - const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); + const scale = this.props.hideOnLeave ? 1 : NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = (Doc.GetSelectedTool() === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false); if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(() => FormattedTextBoxComment.Hide()); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 6b7a93747..fc547c60f 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -370,7 +370,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { if (scrollToAnnotation) { - const offset = (this.props.PanelHeight() / this.props.ContentScaling()) / 2; + const offset = this.props.PanelHeight() / 2; this._mainCont.current && smoothScroll(500, this._mainCont.current, NumCast(scrollToAnnotation.y) - offset); Doc.linkFollowHighlight(scrollToAnnotation); } @@ -737,7 +737,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent; } - @computed get contentScaling() { return this.props.ContentScaling(); } + @computed get contentScaling() { return 1; } @computed get standinViews() { return <> {this._showCover ? this.getCoverImage() : (null)} @@ -758,7 +758,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent 600) ? Doc.NativeWidth(this.props.Document) : `${100 / this.contentScaling}%`, height: !this.props.Document._fitWidth && (window.screen.width > 600) ? Doc.NativeHeight(this.props.Document) : `${100 / this.contentScaling}%`, - transform: `scale(${this.props.ContentScaling()})` }} > {this.pdfViewerDiv} {this.annotationLayer} diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 3b6b0259d..8615ba81d 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -78,7 +78,7 @@ export class PresElementBox extends ViewBoxBaseComponent this.props.PanelWidth(); // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); embedWidth = (): number => this.props.PanelWidth() - 35; - styleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { + styleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { if (property === StyleProp.Opacity) return 1; return this.props.styleProvider?.(doc, props, property); } -- cgit v1.2.3-70-g09d2 From 84849091ceaec757e545ab5ea69cd9d6ff46f6d2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Dec 2020 23:43:55 -0500 Subject: fixed resetting bookmark view to not set _currentFrame to 0 unless it already had a value. --- src/client/views/collections/CollectionMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index ef0c30ff4..833fc0007 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -177,7 +177,7 @@ export class CollectionViewBaseChrome extends React.Component { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; this.target._currentFrame = 0; }), + immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; this.target._currentFrame = (this.target._currentFrame === undefined ? undefined : 0); }), initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; button['target-currentFrame'] = this.target._currentFrame; }, }; _clusterCommand = { -- cgit v1.2.3-70-g09d2 From 043fe3cb67003ddd0bc309b85e2b0dad353ed629 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 13:58:56 -0500 Subject: more props cleanup. Got rid of ItemBackgroundColor in favor of having StyleProvider choose style based on whether it's givena DocViewProp or a FieldViewProp. --- src/client/views/DocComponent.tsx | 3 +- src/client/views/PropertiesView.tsx | 2 +- src/client/views/StyleProvider.tsx | 41 ++++++++++------------ .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 +- .../views/collections/CollectionTimeView.tsx | 2 +- src/client/views/collections/SchemaTable.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 7 ++-- .../collectionGrid/CollectionGridView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 2 +- .../CollectionMultirowView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 6 ++-- src/client/views/nodes/ComparisonBox.tsx | 9 +++-- src/client/views/nodes/DocHolderBox.tsx | 4 +-- src/client/views/nodes/DocumentContentsView.tsx | 19 +++++++++- src/client/views/nodes/DocumentView.tsx | 27 ++++++++------ src/client/views/nodes/FieldView.tsx | 1 - src/client/views/nodes/FilterBox.tsx | 1 - src/client/views/nodes/FontIconBox.tsx | 2 +- src/client/views/nodes/LinkAnchorBox.scss | 1 - src/client/views/nodes/LinkAnchorBox.tsx | 5 +-- src/client/views/nodes/LinkDocPreview.tsx | 3 +- .../views/nodes/formattedText/DashDocView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 +-- .../formattedText/FormattedTextBoxComment.tsx | 2 +- .../views/nodes/formattedText/RichTextSchema.tsx | 2 +- .../views/presentationview/PresElementBox.tsx | 2 +- 29 files changed, 92 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index d6116fd23..2c7d15ae0 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -14,6 +14,7 @@ import { GetEffectiveAcl, SharingPermissions, distributeAcls, denormalizeEmail } interface DocComponentProps { Document: Doc; LayoutTemplate?: () => Opt; + LayoutTemplateString?: string; } export function DocComponent

    (schemaCtor: (doc: Doc) => T) { class Component extends Touchable

    { @@ -22,7 +23,7 @@ export function DocComponent

    (schemaCtor: (doc: D // This is the "The Document" -- it encapsulates, data, layout, and any templates @computed get rootDoc() { return Cast(this.props.Document.rootDocument, Doc, null) || this.props.Document; } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info - @computed get layoutDoc() { return Doc.Layout(this.props.Document, this.props.LayoutTemplate?.()); } + @computed get layoutDoc() { return this.props.LayoutTemplateString ? this.props.Document : Doc.Layout(this.props.Document, this.props.LayoutTemplate?.()); } // This is the data part of a document -- ie, the data that is constant across all views of the document @computed get dataDoc() { return this.props.Document[DataSym] as Doc; } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index eb7df0248..24c6c6d71 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -271,7 +271,7 @@ export class PropertiesView extends React.Component { renderDepth={1} rootSelected={returnFalse} styleProvider={DefaultStyleProvider} - fitToBox={true} + fitDocToPanel={true} freezeDimensions={true} dontCenter={"y"} NativeWidth={layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 128c3cb96..28373952a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -30,13 +30,12 @@ export enum StyleProp { BorderRounding = "borderRounding", // border radius of the document view Color = "color", // foreground color of Document view items BackgroundColor = "backgroundColor", // background color of a document view - ItemBackgroundColor = "itemBackgroundColor", // background color for Box inside DocumentView - WidgetColor = "widgetColor", // color to display UI widgets on a document view -- used for the sidebar divider dragger on a text note - HideLinkButton = "hideLinkButton", // hides the blue-dot link button. used when a document acts like a button - LinkSource = "linkSource", // source document of a link -- used by LinkAnchorBox - 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 + WidgetColor = "widgetColor", // color to display UI widgets on a document view -- used for the sidebar divider dragger on a text note + HideLinkButton = "hideLinkButton", // hides the blue-dot link button. used when a document acts like a button + LinkSource = "linkSource", // source document of a link -- used by LinkAnchorBox + 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 } function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } @@ -61,22 +60,20 @@ function toggleBackground(doc: Doc) { } export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentViewProps { - if (toBeDetermined.ContentScaling) { - return true; - } - return false; + return (toBeDetermined?.ContentScaling) ? true : false; } // // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { + const docProps = testDocProps(props); 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.Color: - const backColor = props?.styleProvider?.(doc, props, StyleProp.ItemBackgroundColor) || "black"; + const backColor = props?.styleProvider?.(doc, props, StyleProp.BackgroundColor) || "black"; const col = Color(backColor).rgb(); const colsum = (col.red() + col.green() + col.blue()); if (colsum / col.alpha() > 600 || col.alpha() < 0.25) return "black"; @@ -84,17 +81,17 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); - if (docColor) return docColor; - if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; - switch (doc?.type) { - case DocumentType.FONTICON: return "black"; - case DocumentType.LINK: return "lightblue"; - } case StyleProp.BackgroundColor: { if (Doc.UserDoc().renderStyle === "comic") return "transparent"; let docColor: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); + if (!docProps) { + if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; + switch (doc?.type) { + case DocumentType.FONTICON: return docColor || "black"; + case DocumentType.LINK: return docColor || "lightblue"; + default: undefined; + } + } switch (doc?.type) { case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break; case DocumentType.PRES: docColor = docColor || (darkScheme() ? "#3e3e3e" : "white"); break; @@ -103,7 +100,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt doc) { doc) { @computed get contents() { return

    { ref="overlay"> { docFilters={CollectionDockingView.Instance.docFilters} docRangeFilters={CollectionDockingView.Instance.docRangeFilters} searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs} - fitToBox={true} + fitContentsToDoc={true} />
    diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 11ff4ca3b..c03041214 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -617,7 +617,7 @@ export class TreeView extends React.Component { PanelHeight={panelHeight} NativeWidth={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} NativeHeight={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined} - fitToBox={!asText && this.isCollectionDoc !== undefined} + fitDocToPanel={!asText && this.isCollectionDoc !== undefined} hideTitle={asText} LayoutTemplateString={asText ? FormattedTextBox.LayoutString("text") : undefined} focus={asText ? this.refocus : returnFalse} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 3f7eb24f8..403c20ba2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -76,6 +76,7 @@ export type collectionFreeformViewProps = { forceScaling?: boolean; // whether to force scaling of content (needed by ImageBox) viewDefDivClick?: ScriptField; childPointerEvents?: boolean; + fitContentsToDoc?: boolean; parentActive: (outsideReaction: boolean) => boolean; scaleField?: string; noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale) @@ -116,7 +117,7 @@ export class CollectionFreeFormView extends CollectionSubView 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 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); } @@ -998,7 +999,7 @@ export class CollectionFreeFormView extends CollectionSubView, bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica) diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 1a4eb8b7b..36ed72596 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -169,7 +169,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { PanelHeight={height} ContentScaling={returnOne} freezeDimensions={true} - fitToBox={true} + fitDocToPanel={true} ScreenToLocalTransform={dxf} onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index d4913a5ed..6ed7d1dd3 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -223,7 +223,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} - fitToBox={false} + fitDocToPanel={false} rootSelected={this.rootSelected} dropAction={StrCast(this.props.Document.childDropAction) as dropActionType} onClick={this.onChildClickHandler} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 9039090d1..a4a569cc9 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -223,7 +223,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} - fitToBox={false} + fitDocToPanel={false} rootSelected={this.rootSelected} dropAction={StrCast(this.props.Document.childDropAction) as dropActionType} onClick={this.onChildClickHandler} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3f473460f..6eb8dc8c9 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -27,7 +27,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { highlight?: boolean; jitterRotation: number; dataTransition?: string; - fitToBox?: boolean; + fitDocToPanel?: boolean; replica: string; } @@ -139,7 +139,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeWidth > 0 && !this.props.fitToBox && !this.freezeDimensions ? this.width / this.nativeWidth : 1; + contentScaling = () => this.nativeWidth > 0 && !this.props.fitDocToPanel && !this.freezeDimensions ? this.width / this.nativeWidth : 1; panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.()); panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.()); getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling()); @@ -190,7 +190,7 @@ export class CollectionFreeFormDocumentView extends DocComponent
    } - {this.props.fitToBox ? + {this.props.fitDocToPanel ? this._contentView = r)} /> : }
    ; diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 0ba53dee6..1b7084ffa 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -12,7 +12,7 @@ import "./ComparisonBox.scss"; import React = require("react"); import { ContentFittingDocumentView } from './ContentFittingDocumentView'; import { undoBatch } from '../../util/UndoManager'; -import { setupMoveUpEvents, emptyFunction } from '../../../Utils'; +import { setupMoveUpEvents, emptyFunction, returnOne } from '../../../Utils'; import { SnappingManager } from '../../util/SnappingManager'; import { DocumentViewProps } from './DocumentView'; @@ -74,7 +74,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { return
    e.stopPropagation()} // prevent triggering slider movement in registerSliding @@ -85,7 +84,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null); return whichDoc ? <> - + {clearButton(which)} : // placeholder image if doc is missing
    diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx index 1bc7bc8d7..5aab0a4c8 100644 --- a/src/client/views/nodes/DocHolderBox.tsx +++ b/src/client/views/nodes/DocHolderBox.tsx @@ -124,7 +124,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent, onInput: Opt): JsxBindings { + const docOnlyProps = [ // these are the properties in DocumentViewProps that need to be removed to pass on only DocumentSharedViewProps to the FieldViews + "freezeDimensions", + "hideTitle", + "fitDocToPanel", + "treeViewDoc", + "dragDivName", + "contentPointerEvents", + "radialMenu", + "LayoutTemplateString", + "LayoutTemplate", + "ContentScaling", + "contentFittingScaling", + "contextMenuItems", + "onDoubleClick", + "onPointerDown", + "onPointerUp", + ]; const list = { - ...OmitKeys(this.props, ['NativeWidth', 'NativeHeight'], "", (obj: any) => obj.active = this.props.parentActive).omit, + ...OmitKeys(this.props, [...docOnlyProps, 'NativeWidth', 'NativeHeight'], "", (obj: any) => obj.active = this.props.parentActive).omit, RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc, Document: this.layoutDoc, DataDoc: this.dataDoc, diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 10b406fd4..f766976d0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -42,7 +42,7 @@ import { RadialMenu } from './RadialMenu'; import { TaskCompletionBox } from './TaskCompletedBox'; import React = require("react"); import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; -import { StyleProp, StyleLayers } from "../StyleProvider"; +import { StyleProp, StyleLayers, testDocProps } from "../StyleProvider"; import { FieldViewProps } from "./FieldView"; export type DocAfterFocusFunc = (notFocused: boolean) => boolean; @@ -78,7 +78,6 @@ export interface DocumentViewSharedProps { bringToFront: (doc: Doc, sendToBack?: boolean) => void; onClick?: () => ScriptField; dropAction?: dropActionType; - LayoutTemplateString?: string; dontRegisterView?: boolean; ignoreAutoHeight?: boolean; pointerEvents?: string; @@ -88,14 +87,15 @@ export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView freezeDimensions?: boolean; hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings - fitToBox?: boolean; + fitDocToPanel?: boolean; treeViewDoc?: Doc; dragDivName?: string; - contentPointerEvents?: string; + contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents radialMenu?: String[]; + LayoutTemplateString?: string; + LayoutTemplate?: () => Opt; ContentScaling: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal contentFittingScaling?: () => number;// scaling done outside the document view (eg in ContentFittingDocumentView) to fit contents into panel (needed for ScreenToLocal but not needed by DocumentView to scale its content) - LayoutTemplate?: () => Opt; contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; @@ -934,7 +934,7 @@ export class DocumentView extends DocComponent(Docu makeLink={this.makeLink} focus={this.props.focus} dontRegisterView={this.props.dontRegisterView} - fitToBox={this.props.fitToBox} + fitDocToPanel={this.props.fitDocToPanel} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} moveDocument={this.props.moveDocument} @@ -974,11 +974,16 @@ export class DocumentView extends DocComponent(Docu anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { - switch (property.split(":")[0]) { - case StyleProp.BackgroundColor: return "transparent"; - case StyleProp.HideLinkButton: return true; - case StyleProp.PointerEvents: return "none"; - case StyleProp.LinkSource: return this.props.Document; + if (testDocProps(props)) { + switch (property.split(":")[0]) { + case StyleProp.BackgroundColor: return "transparent"; // background of linkanchor documentView is transparent since it covers the whole document + case StyleProp.HideLinkButton: return true; // don't want linkAnchor documentview to show its own link button + case StyleProp.PointerEvents: return "none"; // don't want linkAnchor documentView to handle events (since it covers the whole document). However, the linkAnchorBox itself is set to pointerEvent all + } + } else { + switch (property.split(":")[0]) { + case StyleProp.LinkSource: return this.props.Document; // pass the LinkSource to the LinkAnchorBox + } } return this.props.styleProvider?.(doc, props, property); } diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 057c7afae..fd2193bd8 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -16,7 +16,6 @@ import { VideoBox } from "./VideoBox"; export interface FieldViewProps extends DocumentViewSharedProps { // FieldView specific props that are not part of DocumentView props fieldKey: string; - fitToBox?: boolean; overflow?: boolean; // bcz: would like to think this can be avoided -- need to look at further active: (outsideReaction?: boolean) => boolean; select: (isCtrlPressed: boolean) => void; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index ffe1684d4..730ae8f10 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -204,7 +204,6 @@ export class FilterBox extends ViewBoxBaseComponent( render() { const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); - const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.ItemBackgroundColor); + const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const shape = StrCast(this.layoutDoc.iconShape, label ? "round" : "circle"); const icon = StrCast(this.dataDoc.icon, "user") as any; const presSize = shape === 'round' ? 25 : 30; diff --git a/src/client/views/nodes/LinkAnchorBox.scss b/src/client/views/nodes/LinkAnchorBox.scss index 62ee9513c..caff369df 100644 --- a/src/client/views/nodes/LinkAnchorBox.scss +++ b/src/client/views/nodes/LinkAnchorBox.scss @@ -23,7 +23,6 @@ padding-top: 1px; } .linkAnchorBox-button { - pointer-events: all; position: relative; display: inline-block; } diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index d0048c67b..f035fba33 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -119,7 +119,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent { : { position: "absolute", left: this.props.location[0], top: this.props.location[1], width: this.width() + 16, height: this.height() + 16, zIndex: 1000, + backgroundColor: "lightblue", border: "8px solid white", borderRadius: "7px", boxShadow: "3px 3px 1.5px grey", borderBottom: "8px solid white", borderRight: "8px solid white" diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 450f0b6bc..04e94391f 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -228,7 +228,7 @@ export class DashDocView extends React.Component { { @@ -1624,7 +1624,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp scaleField: this.annotationKey + "-scale", isAnnotationOverlay: true, fieldKey: this.annotationKey, - fitToBox: fitToBox, + fitContentsToDoc: fitToBox, select: emptyFunction, active: this.annotationsActive, ContentScaling: this.sidebarContentScaling, diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 1d7b7ec91..1ee217d03 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -297,7 +297,7 @@ export class FormattedTextBoxComment {
    Date: Sun, 13 Dec 2020 14:25:33 -0500 Subject: adding documentView as a fieldView prop to make contetnScaling available in PDFview --- src/client/views/nodes/DocumentView.tsx | 2 ++ src/client/views/nodes/PDFBox.tsx | 5 +++-- src/client/views/pdf/PDFViewer.tsx | 6 ++++-- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f766976d0..6ca3ffbee 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -52,6 +52,7 @@ export interface DocumentViewSharedProps { renderDepth: number; Document: Doc; DataDoc?: Doc; + DocumentView?: DocumentView; ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; @@ -913,6 +914,7 @@ export class DocumentView extends DocComponent(Docu }}> @@ -193,6 +192,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent; } + contentScaling = () => this.props.DocumentView?.props.ContentScaling() || 1; isChildActive = (outsideReaction?: boolean) => this._isChildActive; @computed get renderPdfView() { TraceMobx(); @@ -209,6 +209,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent {this.settingsPanel()}
    ; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index fc547c60f..7696167a7 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -60,6 +60,7 @@ interface IViewerProps extends FieldViewProps { loaded?: (nw: number, nh: number, np: number) => void; isChildActive: (outsideReaction?: boolean) => boolean; setPdfViewer: (view: PDFViewer) => void; + ContentScaling: () => number; } /** @@ -370,7 +371,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { if (scrollToAnnotation) { - const offset = this.props.PanelHeight() / 2; + const offset = (this.props.PanelHeight() / this.props.ContentScaling()) / 2; this._mainCont.current && smoothScroll(500, this._mainCont.current, NumCast(scrollToAnnotation.y) - offset); Doc.linkFollowHighlight(scrollToAnnotation); } @@ -737,7 +738,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent; } - @computed get contentScaling() { return 1; } + @computed get contentScaling() { return this.props.ContentScaling(); } @computed get standinViews() { return <> {this._showCover ? this.getCoverImage() : (null)} @@ -758,6 +759,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent 600) ? Doc.NativeWidth(this.props.Document) : `${100 / this.contentScaling}%`, height: !this.props.Document._fitWidth && (window.screen.width > 600) ? Doc.NativeHeight(this.props.Document) : `${100 / this.contentScaling}%`, + transform: `scale(${this.props.ContentScaling()})` }} > {this.pdfViewerDiv} {this.annotationLayer} -- cgit v1.2.3-70-g09d2 From dc98dae527236651f69a9bbd94e6f68296e417cd Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 17:07:12 -0500 Subject: converted TabDocView to just use a ContentFittingDocumentView. Fixed schemView to use a styleProvider --- .../views/collections/CollectionSchemaView.tsx | 3 + src/client/views/collections/TabDocView.tsx | 143 ++++++++------------- src/client/views/collections/TreeView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 1 - .../views/nodes/ContentFittingDocumentView.tsx | 27 ++-- src/client/views/nodes/DocumentView.tsx | 5 +- src/client/views/nodes/FieldView.tsx | 1 + 7 files changed, 76 insertions(+), 105 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 973cd5d3c..e87fdef1e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -24,6 +24,7 @@ import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView" import "./CollectionSchemaView.scss"; import { CollectionSubView } from "./CollectionSubView"; import { SchemaTable } from "./SchemaTable"; +import { DefaultStyleProvider } from "../StyleProvider"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 export enum ColumnType { @@ -401,6 +402,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { Document={this.previewDocument} DataDoc={undefined} fitDocToPanel={true} + fitContentsToDoc={true} freezeDimensions={true} dontCenter={"y"} focus={emptyFunction} @@ -412,6 +414,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { docFilters={this.docFilters} docRangeFilters={this.docRangeFilters} searchFilterDocs={this.searchFilterDocs} + styleProvider={DefaultStyleProvider} ContainingCollectionDoc={this.props.CollectionView?.props.Document} ContainingCollectionView={this.props.CollectionView} moveDocument={this.props.moveDocument} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index fc2f7c522..9c77792a0 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -34,6 +34,7 @@ import { DocumentType } from '../../documents/DocumentTypes'; import Color = require('color'); import { StyleProp, DefaultStyleProvider, DefaultLayerProvider, StyleLayers } from '../StyleProvider'; import { FieldViewProps } from '../nodes/FieldView'; +import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -50,7 +51,17 @@ export class TabDocView extends React.Component { @observable private _panelHeight = 0; @observable private _isActive: boolean = false; @observable private _document: Doc | undefined; - @observable private _view: DocumentView | undefined; + @observable private _view: ContentFittingDocumentView | undefined; + + @computed get layoutDoc() { return this._document && Doc.Layout(this._document); } + @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); } + @computed get renderBounds() { + const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0]; + const xbounds = bounds[2] - bounds[0]; + const ybounds = bounds[3] - bounds[1]; + const dim = Math.max(xbounds, ybounds); + return { l: bounds[0] + xbounds / 2 - dim / 2, t: bounds[1] + ybounds / 2 - dim / 2, cx: bounds[0] + xbounds / 2, cy: bounds[1] + ybounds / 2, dim }; + } get stack() { return (this.props as any).glContainer.parent.parent; } get tab() { return (this.props as any).glContainer.tab; } @@ -106,14 +117,15 @@ export class TabDocView extends React.Component { }; // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected - titleEle.onpointerdown = (e: any) => { - if (e.target.className !== "lm_close_tab" && this.view) { - SelectionManager.SelectDoc(this.view, false); + titleEle.onpointerdown = action((e: any) => { + if (e.target.className !== "lm_close_tab") { + if (this.view?.docView) SelectionManager.SelectDoc(this.view.docView, false); + else this._activated = true; if (Date.now() - titleEle.lastClick < 1000) titleEle.select(); titleEle.lastClick = Date.now(); (document.activeElement !== titleEle) && titleEle.focus(); } - }; + }); tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.topMost && v.props.Document === doc), action((selected) => { if (selected) this._activated = true; @@ -128,7 +140,7 @@ export class TabDocView extends React.Component { const stack = tab.contentItem.parent; const dragHdl = document.createElement("div"); dragHdl.className = "lm_drag_tab"; - tab._disposers.buttonDisposer = reaction(() => this.view, view => + tab._disposers.buttonDisposer = reaction(() => this.view?.docView, view => view && [ReactDOM.render( [view]} Stack={stack} />, dragHdl), tab._disposers.buttonDisposer?.()], { fireImmediately: true }); tab.reactComponents = [dragHdl]; @@ -240,48 +252,6 @@ export class TabDocView extends React.Component { } } - NativeAspect = () => this.nativeAspect; - PanelWidth = () => this.panelWidth; - PanelHeight = () => this.panelHeight; - nativeWidth = () => this._nativeWidth; - nativeHeight = () => this._nativeHeight; - ContentScaling = () => this.contentScaling; - - ScreenToLocalTransform = () => { - if (this._mainCont?.children) { - const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0]?.firstChild as HTMLElement); - const scale = Utils.GetScreenTransform(this._mainCont).scale; - return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.ContentScaling() / scale); - } - return Transform.Identity(); - } - @computed get nativeAspect() { - return this.nativeWidth() ? this.nativeWidth() / this.nativeHeight() : 0; - } - @computed get panelHeight() { - return this.NativeAspect() && this.NativeAspect() > this._panelWidth / this._panelHeight ? this._panelWidth / this.NativeAspect() : this._panelHeight; - } - @computed get panelWidth() { - return this.layoutDoc?.maxWidth ? Math.min(Math.max(NumCast(this.layoutDoc._width), Doc.NativeWidth(this.layoutDoc)), this._panelWidth) : - (this.NativeAspect() && this.NativeAspect() < this._panelWidth / this._panelHeight ? this._panelHeight * this.NativeAspect() : this._panelWidth); - } - @computed get _nativeWidth() { return !this.layoutDoc?._fitWidth ? Doc.NativeWidth(this.layoutDoc) || this._panelWidth : 0; } - @computed get _nativeHeight() { return !this.layoutDoc?._fitWidth ? Doc.NativeHeight(this.layoutDoc) || this._panelHeight : 0; } - @computed get contentScaling() { - const nativeW = Doc.NativeWidth(this.layoutDoc); - const nativeH = Doc.NativeHeight(this.layoutDoc); - let scaling = 1; - if (nativeW && (this.layoutDoc?._fitWidth || this._panelHeight / nativeH > this._panelWidth / nativeW)) { - scaling = this._panelWidth / nativeW; // width-limited or fitWidth - } else if (nativeW && nativeH) { - scaling = this._panelHeight / nativeH; // height-limited - } - return scaling; - } - @computed get previewPanelCenteringOffset() { return this.nativeWidth() ? (this._panelWidth - this.nativeWidth() * this.ContentScaling()) / 2 : 0; } - @computed get widthpercent() { return this.nativeWidth() ? `${(this.nativeWidth() * this.ContentScaling()) / this._panelWidth * 100}% ` : undefined; } - @computed get layoutDoc() { return this._document && Doc.Layout(this._document); } - // adds a tab to the layout based on the locaiton parameter which can be: // close[:{left,right,top,bottom}] - e.g., "close" will close the tab, "close:left" will close the left tab, // add[:{left,right,top,bottom}] - e.g., "add" will add a tab to the current stack, "add:right" will add a tab on the right @@ -304,14 +274,6 @@ export class TabDocView extends React.Component { } } - @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); } - @computed get renderBounds() { - const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0]; - const xbounds = bounds[2] - bounds[0]; - const ybounds = bounds[3] - bounds[1]; - const dim = Math.max(xbounds, ybounds); - return { l: bounds[0] + xbounds / 2 - dim / 2, t: bounds[1] + ybounds / 2 - dim / 2, cx: bounds[0] + xbounds / 2, cy: bounds[1] + ybounds / 2, dim }; - } childLayoutTemplate = () => Cast(this._document?.childLayoutTemplate, Doc, null); returnMiniSize = () => NumCast(this._document?._miniMapSize, 150); miniDown = (e: React.PointerEvent) => { @@ -355,7 +317,7 @@ export class TabDocView extends React.Component { removeDocument={returnFalse} PanelWidth={this.returnMiniSize} PanelHeight={this.returnMiniSize} - ScreenToLocalTransform={this.ScreenToLocalTransform} + ScreenToLocalTransform={Transform.Identity} renderDepth={0} whenActiveChanged={emptyFunction} focus={emptyFunction} @@ -387,9 +349,14 @@ export class TabDocView extends React.Component { afterFocus?.(false); } active = () => this._isActive; + ScreenToLocalTransform = () => { + const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont?.children?.[0]?.firstChild as HTMLElement); + return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY); + } + PanelWidth = () => this._panelWidth; + PanelHeight = () => this._panelHeight; - - public static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { + static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (doc) { switch (property.split(":")[0]) { default: return DefaultStyleProvider(doc, props, property); @@ -406,33 +373,33 @@ export class TabDocView extends React.Component { @computed get layerProvider() { return this._document && DefaultLayerProvider(this._document); } @computed get docView() { TraceMobx(); + console.log("" + this._document?.title + " " + (!this._activated || !this._document || this._document._viewType === CollectionViewType.Docking)) return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : - <> this._view = r)} + <> console.log(this._view = r))} + renderDepth={0} Document={this._document} DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined} - bringToFront={emptyFunction} - rootSelected={returnTrue} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} + PanelWidth={this.PanelWidth} + PanelHeight={this.PanelHeight} layerProvider={this.layerProvider} + styleProvider={DefaultStyleProvider} + docFilters={CollectionDockingView.Instance.docFilters} + docRangeFilters={CollectionDockingView.Instance.docRangeFilters} + searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs} addDocument={undefined} removeDocument={undefined} - ContentScaling={this.ContentScaling} - PanelWidth={this.PanelWidth} - PanelHeight={this.PanelHeight} - NativeHeight={this.nativeHeight() ? this.nativeHeight : undefined} - NativeWidth={this.nativeWidth() ? this.nativeWidth : undefined} + addDocTab={this.addDocTab} ScreenToLocalTransform={this.ScreenToLocalTransform} - renderDepth={0} + ContentScaling={returnOne} + dontCenter={"y"} + rootSelected={returnTrue} parentActive={this.active} whenActiveChanged={emptyFunction} focus={this.focusFunc} - styleProvider={DefaultStyleProvider} - addDocTab={this.addDocTab} - pinToPres={TabDocView.PinDoc} - docFilters={CollectionDockingView.Instance.docFilters} - docRangeFilters={CollectionDockingView.Instance.docRangeFilters} - searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} /> + bringToFront={emptyFunction} + pinToPres={TabDocView.PinDoc} /> {this._document._viewType !== CollectionViewType.Freeform ? (null) : <>{this._document.hideMinimap ? (null) : this.renderMiniMap()} {"toggle minimap"}
    }> @@ -445,18 +412,16 @@ export class TabDocView extends React.Component { } render() { - return (
    { - if (this._mainCont = ref) { - (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document); - DocServer.GetRefField(this.props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document))); - } - }} - style={{ - transform: `translate(${this.previewPanelCenteringOffset}px, 0px)`, - height: this.layoutDoc?._fitWidth ? undefined : "100%", - width: this.widthpercent - }}> - {this.docView} -
    ); + console.log("tab", this._document) + return ( +
    { + if (this._mainCont = ref) { + (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document); + DocServer.GetRefField(this.props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document))); + } + }} > + {this.docView} +
    + ); } } \ No newline at end of file diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index c03041214..dd6f21998 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -618,6 +618,7 @@ export class TreeView extends React.Component { NativeWidth={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} NativeHeight={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined} fitDocToPanel={!asText && this.isCollectionDoc !== undefined} + fitContentsToDoc={true} hideTitle={asText} LayoutTemplateString={asText ? FormattedTextBox.LayoutString("text") : undefined} focus={asText ? this.refocus : returnFalse} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 403c20ba2..6d5f97367 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -76,7 +76,6 @@ export type collectionFreeformViewProps = { forceScaling?: boolean; // whether to force scaling of content (needed by ImageBox) viewDefDivClick?: ScriptField; childPointerEvents?: boolean; - fitContentsToDoc?: boolean; parentActive: (outsideReaction: boolean) => boolean; scaleField?: string; noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale) diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index f2540dfa7..098e422b8 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -7,11 +7,9 @@ import { emptyFunction, OmitKeys, returnOne, returnVal } from "../../../Utils"; import { DocumentView, DocumentViewProps } from "../nodes/DocumentView"; import { StyleProp } from "../StyleProvider"; import "./ContentFittingDocumentView.scss"; - interface ContentFittingDocumentViewProps { dontCenter?: "x" | "y" | "xy"; } - @observer export class ContentFittingDocumentView extends React.Component { public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive @@ -20,23 +18,27 @@ export class ContentFittingDocumentView extends React.Component this.props.PanelHeight()) { - return hscale || 1; + const nativeW = this.nativeWidth; + const nativeH = this.nativeHeight; + let scaling = 1; + if (nativeW && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / nativeH > this.props.PanelWidth() / nativeW)) { + scaling = this.props.PanelWidth() / nativeW; // width-limited or fitWidth + } else if (nativeW && nativeH) { + scaling = this.props.PanelHeight() / nativeH; // height-limited } - return wscale || 1; + return scaling; } @computed get panelWidth() { return this.nativeWidth ? this.nativeWidth * this.nativeScaling : this.props.PanelWidth(); } @computed get panelHeight() { if (this.nativeHeight) { - if (this.props.Document._fitWidth) return Math.min(this.props.PanelHeight(), this.panelWidth / Doc.NativeAspect(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 1); - return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); + if (this.props.Document._fitWidth) + return Math.min(this.props.PanelHeight(), this.panelWidth / Doc.NativeAspect(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 1); + else return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); } return this.props.PanelHeight(); } @@ -67,8 +69,7 @@ export class ContentFittingDocumentView extends React.Component; + fitContentsToDoc?: boolean; ContainingCollectionDoc: Opt; CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; PanelWidth: () => number; @@ -96,7 +97,6 @@ export interface DocumentViewProps extends DocumentViewSharedProps { LayoutTemplateString?: string; LayoutTemplate?: () => Opt; ContentScaling: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal - contentFittingScaling?: () => number;// scaling done outside the document view (eg in ContentFittingDocumentView) to fit contents into panel (needed for ScreenToLocal but not needed by DocumentView to scale its content) contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; @@ -131,7 +131,7 @@ export class DocumentView extends DocComponent(Docu (this.dataDoc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : undefined); } - @computed get LocalScaling() { return this.props.ContentScaling() * (this.props.contentFittingScaling?.() || 1); } + @computed get LocalScaling() { return this.props.ContentScaling(); } @computed get topMost() { return this.props.renderDepth === 0; } @computed get freezeDimensions() { return this.props.freezeDimensions; } @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.dataDoc, this.freezeDimensions)); } @@ -917,6 +917,7 @@ export class DocumentView extends DocComponent(Docu DocumentView={this} Document={this.props.Document} DataDoc={this.props.DataDoc} + fitContentsToDoc={this.props.fitContentsToDoc} ContainingCollectionView={this.props.ContainingCollectionView} ContainingCollectionDoc={this.props.ContainingCollectionDoc} NativeWidth={this.NativeWidth} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index fd2193bd8..2e79ba7b0 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -17,6 +17,7 @@ export interface FieldViewProps extends DocumentViewSharedProps { // FieldView specific props that are not part of DocumentView props fieldKey: string; overflow?: boolean; // bcz: would like to think this can be avoided -- need to look at further + active: (outsideReaction?: boolean) => boolean; select: (isCtrlPressed: boolean) => void; isSelected: (outsideReaction?: boolean) => boolean; -- cgit v1.2.3-70-g09d2 From 7f39c20eefaa25b5e82d09c7cedd8ebd1b24af3f Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 17:10:28 -0500 Subject: from last --- src/client/views/nodes/DocumentView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 56472625b..3dd15d541 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -54,7 +54,7 @@ export interface DocumentViewSharedProps { DataDoc?: Doc; DocumentView?: DocumentView; ContainingCollectionView: Opt; - fitContentsToDoc?: boolean; + fitContentsToDoc?: boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document ContainingCollectionDoc: Opt; CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; PanelWidth: () => number; @@ -89,7 +89,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView freezeDimensions?: boolean; hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings - fitDocToPanel?: boolean; + fitDocToPanel?: boolean; // makes the document view fit the panel available to it (if it has native dimensions, then only one dimension will be fit) treeViewDoc?: Doc; dragDivName?: string; contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents -- cgit v1.2.3-70-g09d2 From 9af7025b7c9e6181843594f5179166556041234c Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 18:05:45 -0500 Subject: removed ContentScaling={returnOne} from a lot of places --- src/client/views/DocumentDecorations.tsx | 8 ++++---- src/client/views/GestureOverlay.tsx | 1 - src/client/views/MainView.tsx | 3 --- src/client/views/OverlayView.tsx | 1 - src/client/views/Palette.tsx | 1 - src/client/views/PropertiesView.tsx | 1 - src/client/views/StyleProvider.tsx | 4 ++-- .../views/collections/CollectionLinearView.tsx | 1 - .../views/collections/CollectionSchemaView.tsx | 1 - .../views/collections/CollectionStackingView.tsx | 1 - .../views/collections/CollectionTreeView.tsx | 1 - src/client/views/collections/SchemaTable.tsx | 3 +-- src/client/views/collections/TabDocView.tsx | 1 - src/client/views/collections/TreeView.tsx | 2 -- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 +-- .../collectionGrid/CollectionGridView.tsx | 1 - .../CollectionMulticolumnView.tsx | 1 - .../CollectionMultirowView.tsx | 1 - src/client/views/linking/LinkMenu.tsx | 2 +- src/client/views/nodes/AudioBox.tsx | 2 -- .../views/nodes/CollectionFreeFormDocumentView.tsx | 12 +++++------ src/client/views/nodes/ComparisonBox.tsx | 1 - src/client/views/nodes/DocHolderBox.tsx | 4 +--- src/client/views/nodes/DocumentContentsView.tsx | 1 + src/client/views/nodes/DocumentIcon.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 24 ++++++++-------------- src/client/views/nodes/FieldView.tsx | 1 + src/client/views/nodes/LinkDocPreview.tsx | 1 - src/client/views/nodes/PDFBox.tsx | 2 +- .../formattedText/FormattedTextBoxComment.tsx | 1 - .../views/presentationview/PresElementBox.tsx | 1 - src/mobile/AudioUpload.tsx | 1 - src/mobile/MobileInterface.tsx | 1 - 33 files changed, 28 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d3b83352e..bce73c60e 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -136,8 +136,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b onBackgroundMove = (dragTitle: boolean, e: PointerEvent): boolean => { const dragDocView = SelectionManager.SelectedDocuments()[0]; const dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); - const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0); - dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top); + const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.LocalScaling).inverse().transformPoint(0, 0); + dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.LocalScaling).transformDirection(e.x - left, e.y - top); dragData.moveDocument = dragDocView.props.moveDocument; dragData.isSelectionMove = true; dragData.canEmbed = dragTitle; @@ -445,7 +445,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b const width = (doc._width || 0); let height = (doc._height || (nheight / nwidth * width)); height = !height || isNaN(height) ? 20 : height; - const scale = docView.props.ScreenToLocalTransform().Scale * docView.props.ContentScaling(); + const scale = docView.props.ScreenToLocalTransform().Scale * docView.LocalScaling; if (nwidth && nheight) { if (nwidth / nheight !== width / height && !dragBottom) { height = nheight / nwidth * width; @@ -504,7 +504,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b onPointerUp = (e: PointerEvent): void => { SelectionManager.SelectedDocuments().map(dv => { if (NumCast(dv.layoutDoc._delayAutoHeight) < this._dragHeights.get(dv.layoutDoc)!) { - dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.props.ContentScaling(), dv.props.PanelWidth(), dv.props.PanelHeight()); + dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.LocalScaling, dv.props.PanelWidth(), dv.props.PanelHeight()); dv.layoutDoc._autoHeight = true; } dv.layoutDoc._delayAutoHeight = undefined; diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index c60060095..aaa914fa4 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -896,7 +896,6 @@ export class GestureOverlay extends Touchable { onClick={undefined} removeDocument={undefined} ScreenToLocalTransform={this.screenToLocalTransform} - ContentScaling={returnOne} PanelWidth={this.return300} PanelHeight={this.return300} renderDepth={0} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index b8c7a1a73..960b50f43 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -250,7 +250,6 @@ export class MainView extends React.Component { onClick={undefined} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} - ContentScaling={returnOne} PanelWidth={this.getPWidth} PanelHeight={this.getPHeight} focus={emptyFunction} @@ -313,7 +312,6 @@ export class MainView extends React.Component { removeDocument={returnFalse} onClick={undefined} ScreenToLocalTransform={this.mainContainerXf} - ContentScaling={returnOne} PanelWidth={this.flyoutWidthFunc} PanelHeight={this.getContentsHeight} renderDepth={0} @@ -345,7 +343,6 @@ export class MainView extends React.Component { removeDocument={returnFalse} onClick={undefined} ScreenToLocalTransform={this.sidebarScreenToLocal} - ContentScaling={returnOne} PanelWidth={this.menuPanelWidth} PanelHeight={this.getContentsHeight} renderDepth={0} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index ee1af8b13..cb7ff20b2 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -187,7 +187,6 @@ export class OverlayView extends React.Component { bringToFront={emptyFunction} addDocument={undefined} removeDocument={undefined} - ContentScaling={returnOne} PanelWidth={returnOne} PanelHeight={returnOne} ScreenToLocalTransform={Transform.Identity} diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index b31cfd7d2..4d0368424 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -47,7 +47,6 @@ export default class Palette extends React.Component { removeDocument={undefined} onClick={undefined} ScreenToLocalTransform={Transform.Identity} - ContentScaling={returnOne} PanelWidth={() => window.screen.width} PanelHeight={() => window.screen.height} renderDepth={0} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 24c6c6d71..fdc470103 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -293,7 +293,6 @@ export class PropertiesView extends React.Component { addDocTab={returnFalse} pinToPres={emptyFunction} bringToFront={returnFalse} - ContentScaling={returnOne} dontRegisterView={true} dropAction={undefined} /> diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 28373952a..386e03f37 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -60,7 +60,7 @@ function toggleBackground(doc: Doc) { } export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentViewProps { - return (toBeDetermined?.ContentScaling) ? true : false; + return (toBeDetermined?.select) ? false : true; } // @@ -126,7 +126,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc) { addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} - ContentScaling={returnOne} />}
    ; } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index f64186728..3af145788 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -235,7 +235,6 @@ export class CollectionStackingView extends CollectionSubView; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 0fd263402..8ea7c3723 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -182,7 +182,6 @@ export class CollectionTreeView extends CollectionSubView
    ; } diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index 58adff6b9..1747c8a89 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -588,8 +588,7 @@ export class SchemaTable extends React.Component { whenActiveChanged={emptyFunction} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} - bringToFront={returnFalse} - ContentScaling={returnOne}> + bringToFront={returnFalse}>
    }
    ; diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 9c77792a0..40e7bc7ce 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -392,7 +392,6 @@ export class TabDocView extends React.Component { removeDocument={undefined} addDocTab={this.addDocTab} ScreenToLocalTransform={this.ScreenToLocalTransform} - ContentScaling={returnOne} dontCenter={"y"} rootSelected={returnTrue} parentActive={this.active} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index dd6f21998..bf77bddeb 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -554,7 +554,6 @@ export class TreeView extends React.Component { moveDocument={this.move} removeDocument={this.props.removeDoc} ScreenToLocalTransform={this.getTransform} - ContentScaling={returnOne} PanelWidth={this.truncateTitleWidth} PanelHeight={returnZero} contextMenuItems={this.contextMenuItems} @@ -640,7 +639,6 @@ export class TreeView extends React.Component { addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} - ContentScaling={returnOne} />; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 6d5f97367..740fc0658 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -322,7 +322,7 @@ export class CollectionFreeFormView extends CollectionSubView DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!); const de = new DragManager.DocumentDragData(eles); de.moveDocument = this.props.moveDocument; - const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0); + const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].LocalScaling).inverse().transformPoint(0, 0); de.offset = this.getTransform().transformDirection(ptsParent.clientX - left, ptsParent.clientY - top); de.dropAction = e.ctrlKey || e.altKey ? "alias" : undefined; DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, ptsParent.clientX, ptsParent.clientY, { hideSource: !de.dropAction }); @@ -1011,7 +1011,6 @@ export class CollectionFreeFormView extends CollectionSubView; } /** diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index a4a569cc9..b634e2307 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -243,7 +243,6 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) addDocTab={this.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse} - ContentScaling={returnOne} />; } /** diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 54b597f59..6277f7ecc 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -75,7 +75,7 @@ export class LinkMenu extends React.Component { @computed get position() { const docView = this.props.docView; - const transform = (docView.props.ScreenToLocalTransform().scale(docView.props.ContentScaling())).inverse(); + const transform = (docView.props.ScreenToLocalTransform().scale(docView.LocalScaling)).inverse(); const [sptX, sptY] = transform.transformPoint(0, 0); const [bptX, bptY] = transform.transformPoint(docView.props.PanelWidth(), docView.props.PanelHeight()); return { x: sptX, y: sptY, r: bptX, b: bptY }; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 7b721786f..2d0441cac 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -554,7 +554,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent, property: string) => { if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children @@ -139,10 +138,9 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeWidth > 0 && !this.props.fitDocToPanel && !this.freezeDimensions ? this.width / this.nativeWidth : 1; panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.()); panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.()); - getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling()); + getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y); focusDoc = (doc: Doc) => this.props.focus(doc, false); NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; @@ -192,7 +190,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this._contentView = r)} /> : - } + }
    ; } } diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 1b7084ffa..9511668d5 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -85,7 +85,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx index 5aab0a4c8..0eefb231f 100644 --- a/src/client/views/nodes/DocHolderBox.tsx +++ b/src/client/views/nodes/DocHolderBox.tsx @@ -142,8 +142,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent : + bringToFront={returnFalse} /> : ; return contents; } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 2c3e9bc88..a3048e32f 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -108,6 +108,7 @@ export class HTMLtag extends React.Component { export class DocumentContentsView extends React.Component boolean, select: (ctrl: boolean) => void, + scaling?: () => number, layoutKey: string, hideOnLeave?: boolean, makeLink?: () => Opt, // function to call when a link is made diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx index fb54f18e8..f2838981d 100644 --- a/src/client/views/nodes/DocumentIcon.tsx +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -9,7 +9,7 @@ import { Field } from "../../../fields/Doc"; export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> { render() { const view = this.props.view; - const transform = view.props.ScreenToLocalTransform().scale(view.props.ContentScaling()).inverse(); + const transform = view.props.ScreenToLocalTransform().scale(view.LocalScaling).inverse(); const { x, y, width, height } = transform.transformBounds(0, 0, view.props.PanelWidth(), view.props.PanelHeight()); return ( diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3dd15d541..ec730dbf6 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -52,7 +52,6 @@ export interface DocumentViewSharedProps { renderDepth: number; Document: Doc; DataDoc?: Doc; - DocumentView?: DocumentView; ContainingCollectionView: Opt; fitContentsToDoc?: boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document ContainingCollectionDoc: Opt; @@ -96,7 +95,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { radialMenu?: String[]; LayoutTemplateString?: string; LayoutTemplate?: () => Opt; - ContentScaling: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal + ContentScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; @@ -131,11 +130,10 @@ export class DocumentView extends DocComponent(Docu (this.dataDoc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : undefined); } - @computed get LocalScaling() { return this.props.ContentScaling(); } + @computed get LocalScaling() { return this.props.ContentScaling?.() || 1; } @computed get topMost() { return this.props.renderDepth === 0; } - @computed get freezeDimensions() { return this.props.freezeDimensions; } - @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.dataDoc, this.freezeDimensions)); } - @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.dataDoc, this.freezeDimensions)); } + @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)); } @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() ?? (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) ?? this.Document.onDoubleClick); } @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ?? ScriptCast(this.Document.onPointerDown); } @@ -247,8 +245,8 @@ export class DocumentView extends DocComponent(Docu startDragging(x: number, y: number, dropAction: dropActionType) { if (this._mainCont.current) { const dragData = new DragManager.DocumentDragData([this.props.Document]); - const [left, top] = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(0, 0); - dragData.offset = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).transformDirection(x - left, y - top); + const [left, top] = this.props.ScreenToLocalTransform().scale(this.LocalScaling).inverse().transformPoint(0, 0); + dragData.offset = this.props.ScreenToLocalTransform().scale(this.LocalScaling).transformDirection(x - left, y - top); dragData.dropAction = dropAction; dragData.removeDocument = this.props.removeDocument; dragData.moveDocument = this.props.moveDocument; @@ -497,7 +495,7 @@ export class DocumentView extends DocComponent(Docu let nheight = Doc.NativeHeight(layoutDoc); const width = (layoutDoc._width || 0); const height = (layoutDoc._height || (nheight / nwidth * width)); - const scale = this.props.ScreenToLocalTransform().Scale * this.props.ContentScaling(); + const scale = this.props.ScreenToLocalTransform().Scale * this.LocalScaling; const actualdW = Math.max(width + (dW * scale), 20); const actualdH = Math.max(height + (dH * scale), 20); doc.x = (doc.x || 0) + dX * (actualdW - width); @@ -721,7 +719,7 @@ export class DocumentView extends DocComponent(Docu @undoBatch @action toggleNativeDimensions = () => { - Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.PanelWidth(), this.props.PanelHeight()); + Doc.toggleNativeDimensions(this.layoutDoc, this.LocalScaling, this.props.PanelWidth(), this.props.PanelHeight()); } @undoBatch @@ -899,7 +897,6 @@ export class DocumentView extends DocComponent(Docu return this.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; } panelHeight = () => this.props.PanelHeight() - this.headerMargin; - childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling()); @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; @@ -914,7 +911,6 @@ export class DocumentView extends DocComponent(Docu }}> (Docu NativeHeight={this.NativeHeight} PanelWidth={this.props.PanelWidth} PanelHeight={this.props.PanelHeight} + scaling={this.props.ContentScaling || returnOne} layerProvider={this.props.layerProvider} styleProvider={this.props.styleProvider} LayoutTemplateString={this.props.LayoutTemplateString} @@ -946,7 +943,6 @@ export class DocumentView extends DocComponent(Docu ScreenToLocalTransform={this.screenToLocal} ignoreAutoHeight={this.props.ignoreAutoHeight} bringToFront={this.props.bringToFront} - ContentScaling={this.childScaling} isSelected={this.isSelected} select={this.select} rootSelected={this.rootSelected} @@ -1008,7 +1004,6 @@ export class DocumentView extends DocComponent(Docu Document={d} PanelWidth={this.anchorPanelWidth} PanelHeight={this.anchorPanelHeight} - ContentScaling={returnOne} dontRegisterView={false} styleProvider={this.anchorStyleProvider} removeDocument={this.hideLinkAnchor} @@ -1034,7 +1029,6 @@ export class DocumentView extends DocComponent(Docu styleProvider={this.captionStyleProvider} dontRegisterView={true} LayoutTemplateString={``} - ContentScaling={returnOne} isSelected={this.isSelected} select={this.select} onClick={this.onClickFunc} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 2e79ba7b0..1b4119210 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -21,6 +21,7 @@ export interface FieldViewProps extends DocumentViewSharedProps { active: (outsideReaction?: boolean) => boolean; select: (isCtrlPressed: boolean) => void; isSelected: (outsideReaction?: boolean) => boolean; + scaling?: () => number; // properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React) pointerEvents?: string; diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 508d85e14..b842c1f10 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -115,7 +115,6 @@ export class LinkDocPreview extends React.Component { focus={emptyFunction} whenActiveChanged={returnFalse} bringToFront={returnFalse} - ContentScaling={returnOne} styleProvider={this.props.styleProvider} />; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 18ded4f3b..262e61c9b 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -192,7 +192,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent; } - contentScaling = () => this.props.DocumentView?.props.ContentScaling() || 1; + contentScaling = () => this.props.scaling?.() || 1; isChildActive = (outsideReaction?: boolean) => this._isChildActive; @computed get renderPdfView() { TraceMobx(); diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 1ee217d03..d517dba1e 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -318,7 +318,6 @@ export class FormattedTextBoxComment { focus={emptyFunction} whenActiveChanged={returnFalse} bringToFront={returnFalse} - ContentScaling={returnOne} NativeWidth={Doc.NativeWidth(target) ? (() => Doc.NativeWidth(target)) : undefined} NativeHeight={Doc.NativeHeight(target) ? (() => Doc.NativeHeight(target)) : undefined} /> diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 6d51df01d..f8f244c35 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -113,7 +113,6 @@ export class PresElementBox extends ViewBoxBaseComponent
    ; diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx index 21c156ac0..bd24efe66 100644 --- a/src/mobile/AudioUpload.tsx +++ b/src/mobile/AudioUpload.tsx @@ -91,7 +91,6 @@ export class AudioUpload extends React.Component { searchFilterDocs={returnEmptyDoclist} onClick={undefined} ScreenToLocalTransform={Transform.Identity} - ContentScaling={returnOne} PanelWidth={() => 600} PanelHeight={() => 400} renderDepth={0} diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 3d5c70ff7..68246e52a 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -209,7 +209,6 @@ export class MobileInterface extends React.Component { removeDocument={undefined} onClick={undefined} ScreenToLocalTransform={Transform.Identity} - ContentScaling={returnOne} PanelWidth={this.returnWidth} PanelHeight={this.returnHeight} renderDepth={0} -- cgit v1.2.3-70-g09d2 From f9f0d6ca06e850e0ea68d7b7b701de46d9449169 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 20:49:48 -0500 Subject: trying to fix PDFs for fitWidth and otherwise in ContentFitting and CollectionFreeFormDoc containers. --- src/client/views/collections/TabDocView.tsx | 2 -- .../views/nodes/CollectionFreeFormDocumentView.tsx | 17 +++++++++++------ .../views/nodes/ContentFittingDocumentView.tsx | 20 +++++++++++++++----- src/client/views/nodes/DocumentView.tsx | 7 ++++++- src/client/views/nodes/PDFBox.tsx | 3 +-- src/client/views/nodes/VideoBox.tsx | 7 +++++-- src/client/views/pdf/PDFViewer.tsx | 8 ++++---- 7 files changed, 42 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 40e7bc7ce..65b793adb 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -373,7 +373,6 @@ export class TabDocView extends React.Component { @computed get layerProvider() { return this._document && DefaultLayerProvider(this._document); } @computed get docView() { TraceMobx(); - console.log("" + this._document?.title + " " + (!this._activated || !this._document || this._document._viewType === CollectionViewType.Docking)) return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : <> console.log(this._view = r))} renderDepth={0} @@ -411,7 +410,6 @@ export class TabDocView extends React.Component { } render() { - console.log("tab", this._document) return (
    { if (this._mainCont = ref) { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index b148fad12..0e790d8db 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -58,6 +58,10 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children @@ -140,15 +144,12 @@ export class CollectionFreeFormDocumentView extends DocComponent (this.sizeProvider?.width || this.props.PanelWidth?.()); panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.()); - getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y); + screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.Scaling()); focusDoc = (doc: Doc) => this.props.focus(doc, false); NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; returnThis = () => this; - @computed get pointerEvents() { - if (this.props.pointerEvents === "none") return "none"; - return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (!this._contentView?.docView?.isSelected() ? ":selected" : "")); - } + Scaling = () => this.Document._fitWidth ? this.props.PanelWidth() / this.NativeWidth() : 1; render() { TraceMobx(); const backgroundColor = this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor); @@ -159,12 +160,16 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeWidth; + NativeHeight = () => this.nativeHeight; PanelWidth = () => this.panelWidth; PanelHeight = () => this.panelHeight; NativeScaling = () => this.nativeScaling; - screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); + screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.nativeScaling); render() { TraceMobx(); + if (this.props.Document.type === DocumentType.PDF) { + console.log("PanelHeight = " + this.panelHeight); + } return (
    {!this.props.Document || !this.props.PanelWidth() ? (null) : (
    0.001 ? `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), width: Math.abs(this.Xshift) > 0.001 ? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), + height: Math.abs(this.YShift) > 0.001 ? this.props.Document._fitWidth ? `${this.panelHeight}px` : `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), }}> this.docView = r)} LayoutTemplate={this.props.LayoutTemplate} PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} + NativeWidth={this.NativeWidth} + NativeHeight={this.NativeHeight} ContentScaling={this.NativeScaling} ScreenToLocalTransform={this.screenToLocalTransform} focus={this.props.focus || emptyFunction} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ec730dbf6..147740ae3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -902,8 +902,13 @@ export class DocumentView extends DocComponent(Docu @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; + @computed get contents() { TraceMobx(); + if (this.props.Document.type === DocumentType.PDF) { + console.log("Scaling = " + this.contentScaling()); + } return (
    (Docu NativeHeight={this.NativeHeight} PanelWidth={this.props.PanelWidth} PanelHeight={this.props.PanelHeight} - scaling={this.props.ContentScaling || returnOne} + scaling={this.contentScaling} layerProvider={this.props.layerProvider} styleProvider={this.props.styleProvider} LayoutTemplateString={this.props.LayoutTemplateString} diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 262e61c9b..ec9a75302 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -192,7 +192,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent; } - contentScaling = () => this.props.scaling?.() || 1; isChildActive = (outsideReaction?: boolean) => this._isChildActive; @computed get renderPdfView() { TraceMobx(); @@ -209,7 +208,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent {this.settingsPanel()}
    ; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 893236857..b446dab22 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -23,6 +23,7 @@ import { SnappingManager } from "../../util/SnappingManager"; import { SelectionManager } from "../../util/SelectionManager"; import { LinkDocPreview } from "./LinkDocPreview"; import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment"; +import { Transform } from "../../util/Transform"; const path = require('path'); export const timeSchema = createSchema({ @@ -413,7 +414,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.contentScaling; contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content]; render() { return (
    void; isChildActive: (outsideReaction?: boolean) => boolean; setPdfViewer: (view: PDFViewer) => void; - ContentScaling: () => number; + ContentScaling?: () => number; } /** @@ -371,7 +371,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { if (scrollToAnnotation) { - const offset = (this.props.PanelHeight() / this.props.ContentScaling()) / 2; + const offset = (this.props.PanelHeight() / this.contentScaling) / 2; this._mainCont.current && smoothScroll(500, this._mainCont.current, NumCast(scrollToAnnotation.y) - offset); Doc.linkFollowHighlight(scrollToAnnotation); } @@ -738,7 +738,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent; } - @computed get contentScaling() { return this.props.ContentScaling(); } + @computed get contentScaling() { return this.props.ContentScaling?.() || 1; } @computed get standinViews() { return <> {this._showCover ? this.getCoverImage() : (null)} @@ -759,7 +759,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent 600) ? Doc.NativeWidth(this.props.Document) : `${100 / this.contentScaling}%`, height: !this.props.Document._fitWidth && (window.screen.width > 600) ? Doc.NativeHeight(this.props.Document) : `${100 / this.contentScaling}%`, - transform: `scale(${this.props.ContentScaling()})` + transform: `scale(${this.contentScaling})` }} > {this.pdfViewerDiv} {this.annotationLayer} -- cgit v1.2.3-70-g09d2 From 1cc523907d05be7975dabb1901b91b3485083616 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 21:06:38 -0500 Subject: now working on video and web box's to fix their annotation registration with doc decorations. --- src/client/views/nodes/VideoBox.tsx | 5 +++-- src/client/views/nodes/WebBox.tsx | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index b446dab22..06a305515 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -414,8 +414,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.contentScaling; + screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.scaling()); contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content]; render() { return (
    this._marqueeX; marqueeY = () => this._marqueeY; marqueeing = () => this._marqueeing; - scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); + @computed get contentScaling() { return this.props.scaling?.() || 1; } + scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)).scale(1 / this.contentScaling); + scaling = () => this.contentScaling; + screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.scaling()) render() { return (
    -- cgit v1.2.3-70-g09d2 From 4749b1a3132f00c7f11a404e612d9c1ce848579f Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 21:25:35 -0500 Subject: fixed webbox --- src/client/views/nodes/WebBox.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index d1d734255..0fffdf693 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -457,7 +457,7 @@ export class WebBox extends ViewBoxAnnotatableComponent
    {view}
    @@ -647,16 +647,16 @@ export class WebBox extends ViewBoxAnnotatableComponent this._marqueeY; marqueeing = () => this._marqueeing; @computed get contentScaling() { return this.props.scaling?.() || 1; } - scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)).scale(1 / this.contentScaling); + scrollXf = () => this.props.ScreenToLocalTransform().scale(1 / this.contentScaling).translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); scaling = () => this.contentScaling; - screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.scaling()) render() { return (
    @@ -664,7 +664,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { -- cgit v1.2.3-70-g09d2 From fb8dc280679981fcaa9a03220f866b446c854399 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 13 Dec 2020 22:37:03 -0500 Subject: fixed comparisonBox's --- src/client/views/nodes/ComparisonBox.tsx | 11 ++++++----- src/client/views/nodes/ContentFittingDocumentView.tsx | 10 +++------- src/client/views/nodes/DocumentView.tsx | 3 --- 3 files changed, 9 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 9511668d5..1bf448bff 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from "mobx-react"; -import { Doc } from '../../../fields/Doc'; +import { Doc, WidthSym, HeightSym } from '../../../fields/Doc'; import { documentSchema } from '../../../fields/documentSchemas'; import { createSchema, makeInterface } from '../../../fields/Schema'; import { NumCast, Cast, StrCast } from '../../../fields/Types'; @@ -12,7 +12,7 @@ import "./ComparisonBox.scss"; import React = require("react"); import { ContentFittingDocumentView } from './ContentFittingDocumentView'; import { undoBatch } from '../../util/UndoManager'; -import { setupMoveUpEvents, emptyFunction, returnOne } from '../../../Utils'; +import { setupMoveUpEvents, emptyFunction, returnOne, OmitKeys } from '../../../Utils'; import { SnappingManager } from '../../util/SnappingManager'; import { DocumentViewProps } from './DocumentView'; @@ -84,10 +84,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null); return whichDoc ? <> - + parentActive={this.props.active} /> {clearButton(which)} : // placeholder image if doc is missing
    diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index a673725dd..396f3807f 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -2,13 +2,12 @@ import React = require("react"); import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; +import { NumCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, OmitKeys, returnOne, returnVal } from "../../../Utils"; +import { emptyFunction, OmitKeys, returnVal } from "../../../Utils"; import { DocumentView, DocumentViewProps } from "../nodes/DocumentView"; import { StyleProp } from "../StyleProvider"; import "./ContentFittingDocumentView.scss"; -import { DocumentType } from "../../documents/DocumentTypes"; -import { NumCast } from "../../../fields/Types"; interface ContentFittingDocumentViewProps { dontCenter?: "x" | "y" | "xy"; } @@ -56,13 +55,10 @@ export class ContentFittingDocumentView extends React.Component this.panelWidth; PanelHeight = () => this.panelHeight; NativeScaling = () => this.nativeScaling; - screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.nativeScaling); + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); render() { TraceMobx(); - if (this.props.Document.type === DocumentType.PDF) { - console.log("PanelHeight = " + this.panelHeight); - } return (
    {!this.props.Document || !this.props.PanelWidth() ? (null) : (
    (Docu @computed get contents() { TraceMobx(); - if (this.props.Document.type === DocumentType.PDF) { - console.log("Scaling = " + this.contentScaling()); - } return (
    Date: Sun, 13 Dec 2020 22:47:23 -0500 Subject: fixed displaying comparison box in treeview. --- src/client/views/collections/CollectionTreeView.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index 650fb019d..f774af74f 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -23,7 +23,7 @@ list-style: none; padding-left: 20px; margin-bottom: 1px; // otherwise vertical scrollbars may pop up for no apparent reason.... - .contentFittingDocumentView { + > .contentFittingDocumentView { width: unset; height: unset; } -- cgit v1.2.3-70-g09d2 From 37d9d2cad93a08518cec6c95c8bc941dd5f5ddaa Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 14 Dec 2020 02:01:57 -0500 Subject: more changes to ContentScaling to get web/video/image boxes to work with annotation/DocDecorations in contentfitting and freeform views. --- src/client/views/GlobalKeyHandler.ts | 11 +- src/client/views/StyleProvider.tsx | 12 +- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/linking/LinkMenuItem.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 3 - .../views/nodes/ContentFittingDocumentView.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 164 ++++++++------------- src/client/views/nodes/ImageBox.tsx | 33 +++-- src/client/views/nodes/ScreenshotBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 4 +- src/client/views/nodes/WebBox.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- .../formattedText/FormattedTextBoxComment.tsx | 2 +- 13 files changed, 102 insertions(+), 143 deletions(-) (limited to 'src') 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, props: Opt, 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, props: Opt 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)) ?
    toggleBackground(doc)}> 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 { @computed get docView() { TraceMobx(); return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : - <> console.log(this._view = r))} + <> 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 { 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 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; fitContentsToDoc?: boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document + ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; 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(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); } @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(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(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(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(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(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(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(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(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(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(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(Docu this.Document.isLinkButton = true; } - @action onCopy = () => { const alias = Doc.MakeAlias(this.props.Document); @@ -876,34 +859,20 @@ export class DocumentView extends DocComponent(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 (
    (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(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) : - } + {this.hideLinkButton ? (null) : }
    ); } @@ -971,7 +940,7 @@ export class DocumentView extends DocComponent(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, props: Opt, property: string): any => { @@ -993,7 +962,7 @@ export class DocumentView extends DocComponent(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(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(Docu onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} />
    ); - const titleView = (!this.ShowTitle ? (null) : + const titleView = (!showTitle ? (null) :
    (Docu pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : undefined, }}> 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; })} />
    ); - return this.props.hideTitle || (!this.ShowTitle && !showCaption) ? + return this.props.hideTitle || (!showTitle && !showCaption) ? this.contents :
    {!this.headerMargin ? <> {this.contents} {titleView} : <> {titleView} {this.contents} } {captionView}
    ; } - @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(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 ??
    (Docu }}> {this.innards} {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
    : (null)} - {this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Decorations + (this.isSelected() ? ":selected" : "")) || (null)} + {this.widgetDecorations ?? null}
    ; } 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(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 { this._dropDisposer?.(); @@ -400,9 +400,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent 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 (
    + whenActiveChanged={this.whenActiveChanged}> {this.contentFunc}
    ); 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 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 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 (
    @@ -700,7 +700,7 @@ export class WebBox extends ViewBoxAnnotatableComponent 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); } } } -- cgit v1.2.3-70-g09d2 From 8d9b38b64e61f2afb2b698004bcef7017d454078 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 14 Dec 2020 14:22:44 -0500 Subject: got rid of fitDocToPanel. made collectionFreeFormDocView always use a ContentFittingDocView. fixed up web box selections. --- src/client/util/DragManager.ts | 33 ++++++++------- src/client/views/PropertiesView.tsx | 1 - .../views/collections/CollectionSchemaView.tsx | 1 - .../views/collections/CollectionStackingView.tsx | 1 - src/client/views/collections/SchemaTable.tsx | 1 - src/client/views/collections/TreeView.tsx | 1 - .../collectionFreeForm/CollectionFreeFormView.tsx | 2 - .../collectionGrid/CollectionGridView.tsx | 1 - .../CollectionMulticolumnView.tsx | 1 - .../CollectionMultirowView.tsx | 1 - .../views/nodes/CollectionFreeFormDocumentView.tsx | 18 +++------ .../views/nodes/ContentFittingDocumentView.tsx | 2 +- src/client/views/nodes/DocHolderBox.tsx | 2 - src/client/views/nodes/DocumentContentsView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 7 +--- src/client/views/nodes/ImageBox.tsx | 18 ++++----- src/client/views/nodes/LinkDocPreview.tsx | 1 - src/client/views/nodes/VideoBox.tsx | 13 +++--- src/client/views/nodes/WebBox.scss | 1 + src/client/views/nodes/WebBox.tsx | 47 +++++++++++----------- .../views/nodes/formattedText/DashDocView.tsx | 1 - .../formattedText/FormattedTextBoxComment.tsx | 1 - .../views/nodes/formattedText/RichTextSchema.tsx | 1 - .../views/presentationview/PresElementBox.tsx | 1 - 24 files changed, 63 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index e3019d288..db371416c 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -342,12 +342,11 @@ export namespace DragManager { dragLabel.style.zIndex = "100001"; dragLabel.style.fontSize = "10px"; dragLabel.style.position = "absolute"; - // dragLabel.innerText = "press 'a' to embed on drop"; // bcz: need to move this to a status bar + dragLabel.innerText = "press 'a' to embed on drop"; // bcz: need to move this to a status bar dragDiv.appendChild(dragLabel); DragManager.Root().appendChild(dragDiv); } dragDiv.hidden = false; - dragLabel.style.display = ""; const scaleXs: number[] = []; const scaleYs: number[] = []; const xs: number[] = []; @@ -416,13 +415,22 @@ export namespace DragManager { }); const hideSource = options?.hideSource ? true : false; - eles.forEach(ele => { - if (ele.parentElement && ele.parentElement?.className === dragData.dragDivName) { - ele.parentElement.hidden = hideSource; - } else { - ele.hidden = hideSource; - } - }); + const hideDragShowOriginalElements = (hide: boolean) => { + dragLabel.style.display = hide ? "" : "none"; + !hide && dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); + eles.forEach(ele => { + if (ele.parentElement?.className === dragData.dragDivName) { + ele.parentElement!.hidden = hide; + } else if (ele.parentElement?.parentElement?.className === dragData.dragDivName) { + ele.parentElement!.parentElement!.hidden = hide; + } else if (ele.parentElement?.parentElement?.parentElement?.className === dragData.dragDivName) { + ele.parentElement!.parentElement!.parentElement!.hidden = hide; + } else { + ele.hidden = hide; + } + }); + }; + hideDragShowOriginalElements(hideSource); SnappingManager.SetIsDragging(true); let lastX = downX; @@ -517,13 +525,8 @@ export namespace DragManager { ); }; - const hideDragShowOriginalElements = () => { - dragLabel.style.display = "none"; - dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); - eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.hidden = ele.parentElement.hidden = false) : (ele.hidden = false)); - }; const endDrag = action(() => { - hideDragShowOriginalElements(); + hideDragShowOriginalElements(false); document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); SnappingManager.SetIsDragging(false); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index fdc470103..46d3b201b 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -271,7 +271,6 @@ export class PropertiesView extends React.Component { renderDepth={1} rootSelected={returnFalse} styleProvider={DefaultStyleProvider} - fitDocToPanel={true} freezeDimensions={true} dontCenter={"y"} NativeWidth={layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index b2aa0d6ea..81ee16f63 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -401,7 +401,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { { ref="overlay"> { PanelHeight={panelHeight} NativeWidth={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} NativeHeight={!asText && this.layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined} - fitDocToPanel={!asText && this.isCollectionDoc !== undefined} fitContentsToDoc={true} hideTitle={asText} LayoutTemplateString={asText ? FormattedTextBox.LayoutString("text") : undefined} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 740fc0658..bda3757e3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -998,7 +998,6 @@ export class CollectionFreeFormView extends CollectionSubView, bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica) diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 55467696d..093a4c770 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -168,7 +168,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { PanelWidth={width} PanelHeight={height} freezeDimensions={true} - fitDocToPanel={true} ScreenToLocalTransform={dxf} onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index e3c6ed3ea..fe1595644 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -223,7 +223,6 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} - fitDocToPanel={false} rootSelected={this.rootSelected} dropAction={StrCast(this.props.Document.childDropAction) as dropActionType} onClick={this.onChildClickHandler} diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index b634e2307..ca712b521 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -223,7 +223,6 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) renderDepth={this.props.renderDepth + 1} PanelWidth={width} PanelHeight={height} - fitDocToPanel={false} rootSelected={this.rootSelected} dropAction={StrCast(this.props.Document.childDropAction) as dropActionType} onClick={this.onChildClickHandler} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index bfdb7d98e..667962889 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -7,8 +7,7 @@ import { listSpec } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { numberRange, returnVal } from "../../../Utils"; -import { DocumentType } from "../../documents/DocumentTypes"; +import { numberRange, returnVal, returnOne } from "../../../Utils"; import { Transform } from "../../util/Transform"; import { DocComponent } from "../DocComponent"; import { InkingStroke } from "../InkingStroke"; @@ -27,7 +26,6 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { highlight?: boolean; jitterRotation: number; dataTransition?: string; - fitDocToPanel?: boolean; replica: string; } @@ -58,10 +56,7 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children @@ -144,12 +139,11 @@ export class CollectionFreeFormDocumentView extends DocComponent (this.sizeProvider?.width || this.props.PanelWidth?.()); panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.()); - screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.Scaling()); + screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y); focusDoc = (doc: Doc) => this.props.focus(doc, false); NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; returnThis = () => this; - Scaling = () => this.Document._fitWidth ? this.props.PanelWidth() / this.NativeWidth() : 1; render() { TraceMobx(); const backgroundColor = this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor); @@ -161,7 +155,7 @@ export class CollectionFreeFormDocumentView extends DocComponent
    } - {this.props.fitDocToPanel ? - this._contentView = r)} /> : - } + this._contentView = r)} />
    ; } } diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 5111fa041..db9366390 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -31,6 +31,7 @@ export class ContentFittingDocumentView extends React.Component 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; @@ -88,7 +87,6 @@ export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView freezeDimensions?: boolean; hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings - fitDocToPanel?: boolean; // makes the document view fit the panel available to it (if it has native dimensions, then only one dimension will be fit) treeViewDoc?: Doc; dragDivName?: string; contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents @@ -868,12 +866,13 @@ export class DocumentView extends DocComponent(Docu panelHeight = () => this.props.PanelHeight() - this.headerMargin; 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; + contentScaling = () => this.LocalScaling; @observable contentsActive: () => boolean = returnFalse; @action setContentsActive = (setActive: () => boolean) => this.contentsActive = setActive; @computed get contents() { + console.log(this.props.Document.title + " " + this.LocalScaling + " " + this.contentScaling()) TraceMobx(); return (
    (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} @@ -906,7 +904,6 @@ export class DocumentView extends DocComponent(Docu makeLink={this.makeLink} focus={this.props.focus} dontRegisterView={this.props.dontRegisterView} - fitDocToPanel={this.props.fitDocToPanel} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} moveDocument={this.props.moveDocument} diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5fba273fb..403b12f0d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -67,8 +67,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent { this._dropDisposer?.(); ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); @@ -264,7 +262,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { const remoteUrl = this.dataDoc.googlePhotosUrl; return !remoteUrl ? (null) : ( window.open(remoteUrl)} @@ -289,7 +287,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { const { dataDoc } = this; @@ -400,26 +398,24 @@ export class ImageBox extends ViewBoxAnnotatableComponent this.contentScaling; - screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.ycenter).scale(1 / this.contentScaling); + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.ycenter); contentFunc = () => [this.content]; render() { TraceMobx(); return (
    { : this.contentScaling; - screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(1 / this.scaling()); + screenToLocalTransform = () => this.props.ScreenToLocalTransform(); contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content]; render() { return (
    {view}
    @@ -646,26 +650,23 @@ export class WebBox extends ViewBoxAnnotatableComponent this._marqueeX; marqueeY = () => this._marqueeY; marqueeing = () => this._marqueeing; - @computed get contentScaling() { return this.props.scaling?.() || 1; } - scrollXf = () => this.props.ScreenToLocalTransform().scale(this.props.contentFittingXf?.() ? 1 : 1 / this.contentScaling).translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); - scaling = () => this.contentScaling; + scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); render() { + const inactiveLayer = this.props.layerProvider?.(this.layoutDoc) === false; + const scale = this.props.scaling?.() || 1; + console.log("Scale = " + scale); return (
    {this.content}
    { const target = this._outerRef.current; @@ -687,22 +688,22 @@ export class WebBox extends ViewBoxAnnotatableComponent
    + setPreviewCursor={this.setPreviewCursor} + select={emptyFunction} + active={this.active} + whenActiveChanged={this.whenActiveChanged}>
    diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 04e94391f..c15eb2dac 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -228,7 +228,6 @@ export class DashDocView extends React.Component { Date: Mon, 14 Dec 2020 14:31:55 -0500 Subject: got rid of setting width/height properties within CollecitonFreeFormDocView becuase they get set now in ContentFittingDocView --- .../views/nodes/CollectionFreeFormDocumentView.tsx | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 667962889..b124263e7 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -31,6 +31,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { @observer export class CollectionFreeFormDocumentView extends DocComponent(Document) { + static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; // fields that are configured to be animatable using animation frames @observable _animPos: number[] | undefined = undefined; @observable _contentView: ContentFittingDocumentView | undefined | null; random(min: number, max: number) { // min should not be equal to max @@ -47,15 +48,8 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { @@ -63,7 +57,6 @@ export class CollectionFreeFormDocumentView extends DocComponent { p[val] = Cast(`${val}-indexed`, listSpec("number"), [NumCast(doc[val])]).reduce((p, v, i) => (i <= Math.round(time) && v !== undefined) || p === undefined ? v : p, undefined as any as number); @@ -141,8 +134,6 @@ export class CollectionFreeFormDocumentView extends DocComponent (this.sizeProvider?.height || this.props.PanelHeight?.()); screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y); focusDoc = (doc: Doc) => this.props.focus(doc, false); - NativeWidth = () => this.nativeWidth; - NativeHeight = () => this.nativeHeight; returnThis = () => this; render() { TraceMobx(); @@ -152,24 +143,20 @@ export class CollectionFreeFormDocumentView extends DocComponent Date: Mon, 14 Dec 2020 18:46:22 -0500 Subject: renamed ContentFittingDocumentView as DocumentView. Renamed DocmentView as DocumentViewInternal --- src/client/util/DictationManager.ts | 14 +- src/client/util/DocumentManager.ts | 4 +- src/client/util/DragManager.ts | 13 +- src/client/util/SelectionManager.ts | 6 +- src/client/util/SharingManager.tsx | 12 +- src/client/views/.DS_Store | Bin 10244 -> 10244 bytes src/client/views/DocumentDecorations.tsx | 60 ++-- src/client/views/GestureOverlay.tsx | 8 +- src/client/views/GlobalKeyHandler.ts | 2 +- src/client/views/MainView.tsx | 6 +- src/client/views/OverlayView.tsx | 14 +- src/client/views/Palette.tsx | 2 +- src/client/views/PropertiesButtons.tsx | 16 +- src/client/views/PropertiesView.tsx | 13 +- src/client/views/TemplateMenu.tsx | 24 +- .../views/collections/CollectionCarousel3DView.tsx | 6 +- .../views/collections/CollectionCarouselView.tsx | 21 +- .../views/collections/CollectionLinearView.tsx | 6 +- src/client/views/collections/CollectionMenu.tsx | 2 +- .../views/collections/CollectionSchemaView.tsx | 8 +- .../views/collections/CollectionStackingView.tsx | 17 +- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/SchemaTable.tsx | 20 +- src/client/views/collections/TabDocView.tsx | 22 +- src/client/views/collections/TreeView.tsx | 15 +- .../CollectionFreeFormLinkView.tsx | 12 +- .../CollectionFreeFormLinksView.tsx | 7 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 12 +- .../collectionGrid/CollectionGridView.tsx | 6 +- .../CollectionMulticolumnView.tsx | 10 +- .../CollectionMultirowView.tsx | 24 +- src/client/views/linking/LinkMenu.tsx | 7 +- src/client/views/linking/LinkMenuItem.tsx | 4 +- src/client/views/nodes/AudioBox.tsx | 4 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 18 +- src/client/views/nodes/ComparisonBox.tsx | 17 +- .../views/nodes/ContentFittingDocumentView.scss | 25 -- .../views/nodes/ContentFittingDocumentView.tsx | 86 ----- src/client/views/nodes/DocHolderBox.tsx | 9 +- src/client/views/nodes/DocumentContentsView.tsx | 2 +- src/client/views/nodes/DocumentIcon.tsx | 5 +- src/client/views/nodes/DocumentView.scss | 23 ++ src/client/views/nodes/DocumentView.tsx | 390 +++++++++++++-------- src/client/views/nodes/LinkDocPreview.tsx | 9 +- src/client/views/nodes/WebBox.tsx | 1 - .../views/nodes/formattedText/DashDocView.tsx | 10 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 3 +- .../formattedText/FormattedTextBoxComment.tsx | 7 +- .../views/nodes/formattedText/RichTextSchema.tsx | 10 +- .../views/presentationview/PresElementBox.tsx | 29 +- src/fields/Doc.ts | 19 +- src/mobile/AudioUpload.tsx | 28 +- src/mobile/MobileInterface.tsx | 1 - 53 files changed, 533 insertions(+), 560 deletions(-) delete mode 100644 src/client/views/nodes/ContentFittingDocumentView.scss delete mode 100644 src/client/views/nodes/ContentFittingDocumentView.tsx (limited to 'src') diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 231e1fa8d..34e274699 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -1,17 +1,17 @@ -import { SelectionManager } from "./SelectionManager"; -import { DocumentView } from "../views/nodes/DocumentView"; -import { UndoManager } from "./UndoManager"; import * as interpreter from "words-to-numbers"; -import { DocumentType } from "../documents/DocumentTypes"; import { Doc, Opt } from "../../fields/Doc"; import { List } from "../../fields/List"; -import { Docs } from "../documents/Documents"; -import { Cast, CastCtor } from "../../fields/Types"; +import { RichTextField } from "../../fields/RichTextField"; import { listSpec } from "../../fields/Schema"; +import { Cast, CastCtor } from "../../fields/Types"; import { AudioField, ImageField } from "../../fields/URLField"; import { Utils } from "../../Utils"; -import { RichTextField } from "../../fields/RichTextField"; +import { Docs } from "../documents/Documents"; +import { DocumentType } from "../documents/DocumentTypes"; import { DictationOverlay } from "../views/DictationOverlay"; +import { DocumentView } from "../views/nodes/DocumentView"; +import { SelectionManager } from "./SelectionManager"; +import { UndoManager } from "./UndoManager"; /** * This namespace provides a singleton instance of a manager that diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index eaccbdb63..6258cc0ab 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -7,10 +7,10 @@ import { DocumentType } from '../documents/DocumentTypes'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; import { CollectionView } from '../views/collections/CollectionView'; import { DocumentView } from '../views/nodes/DocumentView'; +import { FormattedTextBoxComment } from '../views/nodes/formattedText/FormattedTextBoxComment'; +import { LinkDocPreview } from '../views/nodes/LinkDocPreview'; import { LinkManager } from './LinkManager'; import { Scripting } from './Scripting'; -import { LinkDocPreview } from '../views/nodes/LinkDocPreview'; -import { FormattedTextBoxComment } from '../views/nodes/formattedText/FormattedTextBoxComment'; export type CreateViewFunc = (doc: Doc, followLinkLocation: string, finished?: () => void) => void; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index db371416c..4704d9e71 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -125,7 +125,6 @@ export namespace DragManager { } draggedDocuments: Doc[]; droppedDocuments: Doc[]; - dragDivName?: string; treeViewDoc?: Doc; offset: number[]; canEmbed?: boolean; @@ -418,17 +417,7 @@ export namespace DragManager { const hideDragShowOriginalElements = (hide: boolean) => { dragLabel.style.display = hide ? "" : "none"; !hide && dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); - eles.forEach(ele => { - if (ele.parentElement?.className === dragData.dragDivName) { - ele.parentElement!.hidden = hide; - } else if (ele.parentElement?.parentElement?.className === dragData.dragDivName) { - ele.parentElement!.parentElement!.hidden = hide; - } else if (ele.parentElement?.parentElement?.parentElement?.className === dragData.dragDivName) { - ele.parentElement!.parentElement!.parentElement!.hidden = hide; - } else { - ele.hidden = hide; - } - }); + eles.forEach(ele => ele.hidden = hide); }; hideDragShowOriginalElements(hideSource); diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 34e88c7b0..728a4bce1 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,9 +1,9 @@ -import { observable, action, runInAction, ObservableMap } from "mobx"; -import { Doc, Opt } from "../../fields/Doc"; -import { DocumentView } from "../views/nodes/DocumentView"; +import { action, observable, ObservableMap } from "mobx"; import { computedFn } from "mobx-utils"; +import { Doc, Opt } from "../../fields/Doc"; import { CollectionSchemaView } from "../views/collections/CollectionSchemaView"; import { CollectionViewType } from "../views/collections/CollectionView"; +import { DocumentView } from "../views/nodes/DocumentView"; export namespace SelectionManager { diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 062852e36..646926bb7 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -1,13 +1,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, observable, runInAction, computed } from "mobx"; +import { intersection } from "lodash"; +import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import Select from "react-select"; import * as RequestPromise from "request-promise"; -import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly, DocListCastAsync } from "../../fields/Doc"; +import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; import { List } from "../../fields/List"; import { Cast, StrCast } from "../../fields/Types"; -import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx, normalizeEmail } from "../../fields/util"; +import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from "../../fields/util"; import { Utils } from "../../Utils"; import { DocServer } from "../DocServer"; import { CollectionView } from "../views/collections/CollectionView"; @@ -15,13 +16,12 @@ import { DictationOverlay } from "../views/DictationOverlay"; import { MainViewModal } from "../views/MainViewModal"; import { DocumentView } from "../views/nodes/DocumentView"; import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox"; +import { SearchBox } from "../views/search/SearchBox"; import { DocumentManager } from "./DocumentManager"; import { GroupManager, UserOptions } from "./GroupManager"; import { GroupMemberView } from "./GroupMemberView"; -import "./SharingManager.scss"; import { SelectionManager } from "./SelectionManager"; -import { intersection } from "lodash"; -import { SearchBox } from "../views/search/SearchBox"; +import "./SharingManager.scss"; export interface User { email: string; diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store index 60b336584..14e9f6680 100644 Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index bce73c60e..1d0c5dac0 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -3,29 +3,29 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from '@material-ui/core'; import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { AclAdmin, AclEdit, DataSym, Doc, Field, WidthSym, HeightSym } from "../../fields/Doc"; +import { AclAdmin, AclEdit, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc"; import { Document } from '../../fields/documentSchemas'; import { HtmlField } from '../../fields/HtmlField'; import { InkField } from "../../fields/InkField"; import { ScriptField } from '../../fields/ScriptField'; import { Cast, NumCast } from "../../fields/Types"; import { GetEffectiveAcl } from '../../fields/util'; -import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick, returnVal } from "../../Utils"; -import { DocUtils, Docs } from "../documents/Documents"; +import { emptyFunction, returnFalse, returnVal, setupMoveUpEvents } from "../../Utils"; +import { Docs, DocUtils } from "../documents/Documents"; import { DocumentType } from '../documents/DocumentTypes'; -import { DragManager, dropActionType } from "../util/DragManager"; +import { CurrentUserUtils } from '../util/CurrentUserUtils'; +import { DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { SnappingManager } from '../util/SnappingManager'; import { undoBatch, UndoManager } from "../util/UndoManager"; import { CollectionDockingView } from './collections/CollectionDockingView'; import { DocumentButtonBar } from './DocumentButtonBar'; import './DocumentDecorations.scss'; +import { KeyManager } from './GlobalKeyHandler'; +import { InkStrokeProperties } from './InkStrokeProperties'; import { DocumentView } from "./nodes/DocumentView"; import React = require("react"); import e = require('express'); -import { CurrentUserUtils } from '../util/CurrentUserUtils'; -import { InkStrokeProperties } from './InkStrokeProperties'; -import { KeyManager } from './GlobalKeyHandler'; @observer export class DocumentDecorations extends React.Component<{ boundsLeft: number, boundsTop: number }, { value: string }> { @@ -62,31 +62,15 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @computed get Bounds(): { x: number, y: number, b: number, r: number } { - return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { - if (documentView.props.renderDepth === 0 || - documentView.props.treeViewDoc || - !documentView.ContentDiv || - Doc.AreProtosEqual(documentView.props.Document, Doc.UserDoc())) { - return bounds; - } - const transform = (documentView.props.ScreenToLocalTransform().scale(documentView.LocalScaling)).inverse(); - var [sptX, sptY] = transform.transformPoint(0, 0); - let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); - if (documentView.props.LayoutTemplateString?.includes("LinkAnchorBox")) { - const docuBox = documentView.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); - if (docuBox.length) { - const rect = docuBox[0].getBoundingClientRect(); - sptX = rect.left; - sptY = rect.top; - bptX = rect.right; - bptY = rect.bottom; - } - } - return { - x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y), - r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) - }; - }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); + return SelectionManager.SelectedDocuments().map(dv => dv.getBounds()).reduce((bounds, rect) => + !rect ? bounds : + { + x: Math.min(rect.left, bounds.x), + y: Math.min(rect.top, bounds.y), + r: Math.max(rect.right, bounds.r), + b: Math.max(rect.bottom, bounds.b) + }, + { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); } titleBlur = action((commit: boolean) => { @@ -136,8 +120,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b onBackgroundMove = (dragTitle: boolean, e: PointerEvent): boolean => { const dragDocView = SelectionManager.SelectedDocuments()[0]; const dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); - const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.LocalScaling).inverse().transformPoint(0, 0); - dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.LocalScaling).transformDirection(e.x - left, e.y - top); + const { left, top } = dragDocView.getBounds() || { left: 0, top: 0 }; + dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.ContentScale()).transformDirection(e.x - left, e.y - top); dragData.moveDocument = dragDocView.props.moveDocument; dragData.isSelectionMove = true; dragData.canEmbed = dragTitle; @@ -440,12 +424,12 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b if (e.ctrlKey && !Doc.NativeHeight(docView.props.Document)) docView.toggleNativeDimensions(); if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { const doc = Document(docView.rootDoc); - let nwidth = returnVal(docView.NativeWidth?.(), Doc.NativeWidth(doc)); - let nheight = returnVal(docView.NativeHeight?.(), Doc.NativeHeight(doc)); + let nwidth = docView.nativeWidth; + let nheight = docView.nativeHeight; const width = (doc._width || 0); let height = (doc._height || (nheight / nwidth * width)); height = !height || isNaN(height) ? 20 : height; - const scale = docView.props.ScreenToLocalTransform().Scale * docView.LocalScaling; + const scale = docView.props.ScreenToLocalTransform().Scale * docView.ContentScale(); if (nwidth && nheight) { if (nwidth / nheight !== width / height && !dragBottom) { height = nheight / nwidth * width; @@ -504,7 +488,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b onPointerUp = (e: PointerEvent): void => { SelectionManager.SelectedDocuments().map(dv => { if (NumCast(dv.layoutDoc._delayAutoHeight) < this._dragHeights.get(dv.layoutDoc)!) { - dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.LocalScaling, dv.props.PanelWidth(), dv.props.PanelHeight()); + dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.ContentScale(), dv.props.PanelWidth(), dv.props.PanelHeight()); dv.layoutDoc._autoHeight = true; } dv.layoutDoc._delayAutoHeight = undefined; diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index aaa914fa4..b32acce62 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -1,4 +1,5 @@ import React = require("react"); +import * as fitCurve from 'fit-curve'; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../fields/Doc"; @@ -7,7 +8,7 @@ import { Cast, FieldValue, NumCast } from "../../fields/Types"; import MobileInkOverlay from "../../mobile/MobileInkOverlay"; import { GestureUtils } from "../../pen-gestures/GestureUtils"; import { MobileInkOverlayContent } from "../../server/Message"; -import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter, setupMoveUpEvents, returnEmptyDoclist } from "../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from "../../Utils"; import { CognitiveServices } from "../cognitive_services/CognitiveServices"; import { DocUtils } from "../documents/Documents"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; @@ -15,15 +16,14 @@ import { InteractionUtils } from "../util/InteractionUtils"; import { LinkManager } from "../util/LinkManager"; import { Scripting } from "../util/Scripting"; import { Transform } from "../util/Transform"; +import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu"; import "./GestureOverlay.scss"; -import { ActiveInkBezierApprox, ActiveArrowStart, ActiveArrowEnd, ActiveFillColor, ActiveInkColor, ActiveInkWidth, InkingStroke, SetActiveInkColor, SetActiveInkWidth, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "./InkingStroke"; +import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, SetActiveArrowEnd, SetActiveArrowStart, SetActiveDash, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "./InkingStroke"; import { DocumentView } from "./nodes/DocumentView"; import { RadialMenu } from "./nodes/RadialMenu"; import HorizontalPalette from "./Palette"; import { Touchable } from "./Touchable"; import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu"; -import * as fitCurve from 'fit-curve'; -import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu"; @observer export class GestureOverlay extends Touchable { diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 50a8e71f9..a727e58a4 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -22,11 +22,11 @@ import { DocumentDecorations } from "./DocumentDecorations"; import { InkStrokeProperties } from "./InkStrokeProperties"; import { MainView } from "./MainView"; import { DocumentLinksButton } from "./nodes/DocumentLinksButton"; -import { DocumentView } from "./nodes/DocumentView"; import { PDFMenu } from "./pdf/PDFMenu"; import { SnappingManager } from "../util/SnappingManager"; import { SearchBox } from "./search/SearchBox"; import { random } from "lodash"; +import { DocumentView } from "./nodes/DocumentView"; const modifiers = ["control", "meta", "shift", "alt"]; type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 960b50f43..17f2e0d89 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -13,7 +13,7 @@ import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; import { BoolCast, PromiseValue, StrCast } from '../../fields/Types'; import { TraceMobx } from '../../fields/util'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils'; import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; import { Docs } from '../documents/Documents'; @@ -46,7 +46,7 @@ import { LinkMenu } from './linking/LinkMenu'; import "./MainView.scss"; import { AudioBox } from './nodes/AudioBox'; import { DocumentLinksButton } from './nodes/DocumentLinksButton'; -import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; +import { DocumentView } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup'; import { LinkDocPreview } from './nodes/LinkDocPreview'; @@ -58,7 +58,7 @@ import { PDFMenu } from './pdf/PDFMenu'; import { PreviewCursor } from './PreviewCursor'; import { PropertiesView } from './PropertiesView'; import { SearchBox } from './search/SearchBox'; -import { DefaultStyleProvider, StyleProp } from './StyleProvider'; +import { DefaultStyleProvider } from './StyleProvider'; const _global = (window /* browser */ || global /* node */) as any; @observer diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index cb7ff20b2..78053be92 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -2,20 +2,18 @@ import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import ReactLoading from 'react-loading'; -import { Doc, DocListCast, Opt } from "../../fields/Doc"; +import { Doc } from "../../fields/Doc"; import { Id } from "../../fields/FieldSymbols"; -import { NumCast, Cast } from "../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, Utils, setupMoveUpEvents, returnEmptyFilter, returnEmptyDoclist } from "../../Utils"; +import { Cast, NumCast } from "../../fields/Types"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, setupMoveUpEvents, Utils } from "../../Utils"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; +import { DragManager } from "../util/DragManager"; +import { Scripting } from "../util/Scripting"; import { Transform } from "../util/Transform"; import { CollectionFreeFormLinksView } from "./collections/collectionFreeForm/CollectionFreeFormLinksView"; import { DocumentView } from "./nodes/DocumentView"; import './OverlayView.scss'; -import { Scripting } from "../util/Scripting"; import { ScriptingRepl } from './ScriptingRepl'; -import { DragManager } from "../util/DragManager"; -import { List } from "../../fields/List"; -import { CurrentUserUtils } from "../util/CurrentUserUtils"; -import { TabDocView } from "./collections/TabDocView"; import { DefaultStyleProvider } from "./StyleProvider"; export type OverlayDisposer = () => void; diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index 4d0368424..304687123 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { Doc } from "../../fields/Doc"; import { NumCast } from "../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyString, returnZero, returnFalse, returnOne, returnTrue, returnEmptyFilter, returnEmptyDoclist } from "../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue } from "../../Utils"; import { Transform } from "../util/Transform"; import { DocumentView } from "./nodes/DocumentView"; import "./Palette.scss"; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 9de4f9c67..1731d715a 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -187,7 +187,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @action @undoBatch onLock = () => { - SelectionManager.SelectedDocuments().forEach(dv => dv.toggleLockPosition()); + SelectionManager.SelectedDocuments().forEach(dv => dv.docView?.toggleLockPosition()); } @computed @@ -327,18 +327,18 @@ export class PropertiesButtons extends React.Component<{}, {}> { SelectionManager.SelectedDocuments().forEach(dv => { if (value === "nothing") { - dv.noOnClick(); + dv.docView?.noOnClick(); } else if (value === "enterPortal") { - dv.noOnClick(); - dv.makeIntoPortal(); + dv.docView?.noOnClick(); + dv.docView?.makeIntoPortal(); } else if (value === "toggleDetail") { - dv.noOnClick(); - dv.toggleDetail(); + dv.docView?.noOnClick(); + dv.docView?.toggleDetail(); } else if (value === "linkInPlace") { - dv.noOnClick(); + dv.docView?.noOnClick(); dv.toggleFollowLink("inPlace", true, false); } else if (value === "linkOnRight") { - dv.noOnClick(); + dv.docView?.noOnClick(); dv.toggleFollowLink("add:right", false, false); } }); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 46d3b201b..1c14bc721 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -5,13 +5,13 @@ import { intersection } from "lodash"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { ColorState, SketchPicker } from "react-color"; -import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, WidthSym, Opt } from "../../fields/Doc"; +import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc"; import { Id } from "../../fields/FieldSymbols"; import { InkField } from "../../fields/InkField"; import { ComputedField } from "../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../fields/Types"; -import { GetEffectiveAcl, SharingPermissions, denormalizeEmail } from "../../fields/util"; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne } from "../../Utils"; +import { denormalizeEmail, GetEffectiveAcl, SharingPermissions } from "../../fields/util"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse } from "../../Utils"; import { DocumentType } from "../documents/DocumentTypes"; import { DocumentManager } from "../util/DocumentManager"; import { SelectionManager } from "../util/SelectionManager"; @@ -19,16 +19,15 @@ import { SharingManager } from "../util/SharingManager"; import { Transform } from "../util/Transform"; import { undoBatch, UndoManager } from "../util/UndoManager"; import { CollectionDockingView } from "./collections/CollectionDockingView"; +import { CollectionViewType } from "./collections/CollectionView"; import { EditableView } from "./EditableView"; import { InkStrokeProperties } from "./InkStrokeProperties"; -import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; +import { DocumentView, StyleProviderFunc } from "./nodes/DocumentView"; import { KeyValueBox } from "./nodes/KeyValueBox"; import { PresBox } from "./nodes/PresBox"; import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; -import { CollectionViewType } from "./collections/CollectionView"; -import { DocumentViewProps, StyleProviderFunc } from "./nodes/DocumentView"; import { DefaultStyleProvider } from "./StyleProvider"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -265,7 +264,7 @@ export class PropertiesView extends React.Component { const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight; const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth; return
    - , template: string) => void }> { diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 67f73d44a..9b1e3b80d 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -8,9 +8,9 @@ import { Id } from '../../../fields/FieldSymbols'; import { makeInterface } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; -import { returnFalse, Utils, OmitKeys } from '../../../Utils'; +import { OmitKeys, returnFalse, Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; -import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; +import { DocumentView } from '../nodes/DocumentView'; import "./CollectionCarousel3DView.scss"; import { CollectionSubView } from './CollectionSubView'; @@ -42,7 +42,7 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume const displayDoc = (childPair: { layout: Doc, data: Doc }) => { const script = ScriptField.MakeScript("child._showCaption = 'caption'", { child: Doc.name }, { child: childPair.layout }); const onChildClick = script && (() => script); - return ; const CarouselDocument = makeInterface(documentSchema, collectionSchema); @@ -50,7 +47,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) return !(curDoc?.layout instanceof Doc) ? (null) : <>
    - - { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 81ee16f63..f153f1cca 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -11,7 +11,7 @@ import { listSpec } from "../../../fields/Schema"; import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; import { Cast, NumCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, returnFalse, returnOne, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils"; import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; @@ -20,11 +20,11 @@ import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globa import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import '../DocumentDecorations.scss'; -import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; +import { DocumentView } from "../nodes/DocumentView"; +import { DefaultStyleProvider } from "../StyleProvider"; import "./CollectionSchemaView.scss"; import { CollectionSubView } from "./CollectionSubView"; import { SchemaTable } from "./SchemaTable"; -import { DefaultStyleProvider } from "../StyleProvider"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 export enum ColumnType { @@ -398,7 +398,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { get previewPanel() { return
    {!this.previewDocument ? (null) : - ; @@ -201,7 +200,7 @@ export class CollectionStackingView extends CollectionSubView { background: "dimGray", display: "block", top: 0, left: 0, transform: `translate(${this._showDocPos[0]}px, ${this._showDocPos[1] - 180}px)` }} - ref="overlay"> { addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} bringToFront={returnFalse}> - +
    }
    ; } diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 1f00b3a02..a4ab201bc 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -6,14 +6,15 @@ import { clamp } from 'lodash'; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; -import { DataSym, Doc, DocListCast, Opt, DocListCastAsync, StrListCast, WidthSym, HeightSym } from "../../../fields/Doc"; +import { DataSym, Doc, DocListCast, DocListCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; import { Id } from '../../../fields/FieldSymbols'; import { FieldId } from "../../../fields/RefField"; import { listSpec } from '../../../fields/Schema'; -import { Cast, NumCast, StrCast, BoolCast } from "../../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils"; +import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; +import { DocumentType } from '../../documents/DocumentTypes'; import { CurrentUserUtils } from '../../util/CurrentUserUtils'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from "../../util/DragManager"; @@ -22,19 +23,16 @@ import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { DocumentView, DocAfterFocusFunc, DocumentViewProps } from "../nodes/DocumentView"; +import { FieldViewProps } from '../nodes/FieldView'; import { PresBox, PresMovement } from '../nodes/PresBox'; +import { DefaultLayerProvider, DefaultStyleProvider, StyleLayers, StyleProp } from '../StyleProvider'; import { CollectionDockingView } from './CollectionDockingView'; import { CollectionDockingViewMenu } from './CollectionDockingViewMenu'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionViewType } from './CollectionView'; import "./TabDocView.scss"; import React = require("react"); -import { List } from '../../../fields/List'; -import { DocumentType } from '../../documents/DocumentTypes'; import Color = require('color'); -import { StyleProp, DefaultStyleProvider, DefaultLayerProvider, StyleLayers } from '../StyleProvider'; -import { FieldViewProps } from '../nodes/FieldView'; -import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -51,7 +49,7 @@ export class TabDocView extends React.Component { @observable private _panelHeight = 0; @observable private _isActive: boolean = false; @observable private _document: Doc | undefined; - @observable private _view: ContentFittingDocumentView | undefined; + @observable private _view: DocumentView | undefined; @computed get layoutDoc() { return this._document && Doc.Layout(this._document); } @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); } @@ -119,7 +117,7 @@ export class TabDocView extends React.Component { // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected titleEle.onpointerdown = action((e: any) => { if (e.target.className !== "lm_close_tab") { - if (this.view?.docView) SelectionManager.SelectDoc(this.view.docView, false); + if (this.view) SelectionManager.SelectDoc(this.view, false); else this._activated = true; if (Date.now() - titleEle.lastClick < 1000) titleEle.select(); titleEle.lastClick = Date.now(); @@ -140,7 +138,7 @@ export class TabDocView extends React.Component { const stack = tab.contentItem.parent; const dragHdl = document.createElement("div"); dragHdl.className = "lm_drag_tab"; - tab._disposers.buttonDisposer = reaction(() => this.view?.docView, view => + tab._disposers.buttonDisposer = reaction(() => this.view, view => view && [ReactDOM.render( [view]} Stack={stack} />, dragHdl), tab._disposers.buttonDisposer?.()], { fireImmediately: true }); tab.reactComponents = [dragHdl]; @@ -374,7 +372,7 @@ export class TabDocView extends React.Component { @computed get docView() { TraceMobx(); return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : - <> this._view = r)} + <> 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/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 2c2498e0b..31a1a2b99 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, trace } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { DataSym, Doc, DocListCast, DocListCastOrNull, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; @@ -9,7 +9,7 @@ import { listSpec } from '../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from '../../util/CurrentUserUtils'; @@ -20,17 +20,16 @@ import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from '../../util/UndoManager'; import { EditableView } from "../EditableView"; -import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView'; import { DocumentView, DocumentViewProps, StyleProviderFunc } from '../nodes/DocumentView'; +import { FieldViewProps } from '../nodes/FieldView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { KeyValueBox } from '../nodes/KeyValueBox'; +import { StyleProp, testDocProps } from '../StyleProvider'; import { CollectionTreeView } from './CollectionTreeView'; import { CollectionView, CollectionViewType } from './CollectionView'; import "./TreeView.scss"; import React = require("react"); -import { StyleProp, testDocProps } from '../StyleProvider'; -import { FieldViewProps } from '../nodes/FieldView'; export interface TreeViewProps { document: Doc; @@ -84,7 +83,7 @@ export class TreeView extends React.Component { private _uniqueId = Utils.GenerateGuid(); private _editMaxWidth: number | string = 0; - @observable _dref: ContentFittingDocumentView | undefined | null; + @observable _dref: DocumentView | undefined | null; @computed get doc() { TraceMobx(); return this.props.document; } get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); } get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive @@ -609,7 +608,7 @@ export class TreeView extends React.Component { renderEmbeddedDocument = (asText: boolean) => { const panelWidth = asText || StrCast(Doc.LayoutField(this.layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.expandPanelWidth; const panelHeight = asText ? this.rtfOutlineHeight : StrCast(Doc.LayoutField(this.layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.expandPanelHeight; - return this._dref = r)} + return this._dref = r)} Document={this.doc} DataDoc={undefined} PanelWidth={panelWidth} @@ -671,7 +670,7 @@ export class TreeView extends React.Component { else this._editMaxWidth = ""; const hideTitle = this.doc.treeViewHideHeader || this.outlineMode; - return
    this.props.active(true) && SelectionManager.DeselectAll()} onKeyDown={this.onKeyDown}> diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 473363292..ae5688b48 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,14 +1,14 @@ +import { action, computed, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../../fields/Doc"; -import { Utils, setupMoveUpEvents, emptyFunction, returnFalse } from '../../../../Utils'; +import { Id } from "../../../../fields/FieldSymbols"; +import { NumCast, StrCast } from "../../../../fields/Types"; +import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { DocumentType } from "../../../documents/DocumentTypes"; +import { SnappingManager } from "../../../util/SnappingManager"; import { DocumentView } from "../../nodes/DocumentView"; import "./CollectionFreeFormLinkView.scss"; import React = require("react"); -import { DocumentType } from "../../../documents/DocumentTypes"; -import { observable, action, reaction, IReactionDisposer, trace, computed } from "mobx"; -import { StrCast, Cast, NumCast } from "../../../../fields/Types"; -import { Id } from "../../../../fields/FieldSymbols"; -import { SnappingManager } from "../../../util/SnappingManager"; export interface CollectionFreeFormLinkViewProps { A: DocumentView; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 260b257c5..4dab8f15b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -1,15 +1,14 @@ -import { computed, trace } from "mobx"; +import { computed } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; +import { Utils } from "../../../../Utils"; +import { DocumentType } from "../../../documents/DocumentTypes"; import { DocumentManager } from "../../../util/DocumentManager"; import { DocumentView } from "../../nodes/DocumentView"; import "./CollectionFreeFormLinksView.scss"; import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView"; import React = require("react"); -import { Utils, emptyFunction } from "../../../../Utils"; -import { DocumentType } from "../../../documents/DocumentTypes"; -import { SnappingManager } from "../../../util/SnappingManager"; @observer export class CollectionFreeFormLinksView extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index bda3757e3..67ad2b769 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -119,8 +119,8 @@ export class CollectionFreeFormView extends CollectionSubView 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 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); } - @computed get nativeHeight() { return this.fitToContent ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.Document)); } + @computed get nativeWidth() { return this.fitToContent ? 0 : Doc.NativeWidth(this.Document); } + @computed get nativeHeight() { return this.fitToContent ? 0 : Doc.NativeHeight(this.Document); } 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; } @@ -322,7 +322,7 @@ export class CollectionFreeFormView extends CollectionSubView DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!); const de = new DragManager.DocumentDragData(eles); de.moveDocument = this.props.moveDocument; - const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].LocalScaling).inverse().transformPoint(0, 0); + const { left, top } = clusterDocs[0].getBounds() || { left: 0, top: 0 }; de.offset = this.getTransform().transformDirection(ptsParent.clientX - left, ptsParent.clientY - top); de.dropAction = e.ctrlKey || e.altKey ? "alias" : undefined; DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, ptsParent.clientX, ptsParent.clientY, { hideSource: !de.dropAction }); @@ -1275,7 +1275,7 @@ export class CollectionFreeFormView extends CollectionSubView { - Doc.toggleNativeDimensions(this.layoutDoc, 1, this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); + Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight); } @undoBatch @@ -1499,8 +1499,8 @@ export class CollectionFreeFormView extends CollectionSubView Transform, width: () => number, height: () => number) { - return ; const MulticolumnDocument = makeInterface(documentSchema); @@ -213,7 +213,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu return this.props.addDocTab(doc, where); } getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) { - return ; const MultirowDocument = makeInterface(documentSchema); @@ -213,7 +213,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) return this.props.addDocTab(doc, where); } getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) { - return { @computed get position() { - const docView = this.props.docView; - const transform = (docView.props.ScreenToLocalTransform().scale(docView.LocalScaling)).inverse(); - const [sptX, sptY] = transform.transformPoint(0, 0); - const [bptX, bptY] = transform.transformPoint(docView.props.PanelWidth(), docView.props.PanelHeight()); - return { x: sptX, y: sptY, r: bptX, b: bptY }; + const docView = this.props.docView.getBounds(); + return { x: docView?.left || 0, y: docView?.top || 0, r: docView?.right || 0, b: docView?.bottom || 0 }; } render() { diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 9ecf3d0fb..8e0004c87 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -1,4 +1,5 @@ -import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontawesome'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; import { action, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; @@ -18,7 +19,6 @@ import { DocumentView } from '../nodes/DocumentView'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import './LinkMenuItem.scss'; import React = require("react"); -import { IconProp } from '@fortawesome/fontawesome-svg-core'; interface LinkMenuItemProps { diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 2d0441cac..4b3c328b0 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -13,7 +13,7 @@ import { createSchema, listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; import { Cast, DateCast, NumCast } from "../../../fields/Types"; import { AudioField, nullAudio } from "../../../fields/URLField"; -import { emptyFunction, formatTime, returnFalse, returnOne, returnTrue, setupMoveUpEvents, Utils, numberRange } from "../../../Utils"; +import { emptyFunction, formatTime, numberRange, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils"; import { Docs, DocUtils } from "../../documents/Documents"; import { Networking } from "../../Network"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; @@ -23,13 +23,13 @@ import { SnappingManager } from "../../util/SnappingManager"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; +import { StyleProp } from "../StyleProvider"; import "./AudioBox.scss"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment"; import { LinkAnchorBox } from "./LinkAnchorBox"; import { LinkDocPreview } from "./LinkDocPreview"; -import { StyleProp } from "../StyleProvider"; declare class MediaRecorder { // whatever MediaRecorder has diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index b124263e7..828b76d3d 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,22 +1,21 @@ import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { Doc, Opt } from "../../../fields/Doc"; import { Document } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { listSpec } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { numberRange, returnVal, returnOne } from "../../../Utils"; +import { numberRange, returnOne } from "../../../Utils"; import { Transform } from "../../util/Transform"; import { DocComponent } from "../DocComponent"; import { InkingStroke } from "../InkingStroke"; +import { StyleProp } from "../StyleProvider"; import "./CollectionFreeFormDocumentView.scss"; -import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; import { DocumentView, DocumentViewProps } from "./DocumentView"; -import React = require("react"); -import { StyleProp } from "../StyleProvider"; import { FieldViewProps } from "./FieldView"; +import React = require("react"); export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; @@ -33,7 +32,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { export class CollectionFreeFormDocumentView extends DocComponent(Document) { static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; // fields that are configured to be animatable using animation frames @observable _animPos: number[] | undefined = undefined; - @observable _contentView: ContentFittingDocumentView | undefined | null; + @observable _contentView: DocumentView | undefined | null; random(min: number, max: number) { // min should not be equal to max const mseed = Math.abs(this.X * this.Y); const seed = (mseed * 9301 + 49297) % 233280; @@ -50,7 +49,7 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children @@ -148,9 +147,8 @@ export class CollectionFreeFormDocumentView extends DocComponent
    } - this._contentView = r)} /> + this._contentView = r)} />
    ; } } diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 1bf448bff..b1bbc9506 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -1,20 +1,19 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from "mobx-react"; -import { Doc, WidthSym, HeightSym } from '../../../fields/Doc'; +import { Doc } from '../../../fields/Doc'; import { documentSchema } from '../../../fields/documentSchemas'; import { createSchema, makeInterface } from '../../../fields/Schema'; -import { NumCast, Cast, StrCast } from '../../../fields/Types'; +import { Cast, NumCast, StrCast } from '../../../fields/Types'; +import { emptyFunction, OmitKeys, setupMoveUpEvents } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; +import { SnappingManager } from '../../util/SnappingManager'; +import { undoBatch } from '../../util/UndoManager'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; -import { FieldView, FieldViewProps } from './FieldView'; import "./ComparisonBox.scss"; +import { DocumentView } from './DocumentView'; +import { FieldView, FieldViewProps } from './FieldView'; import React = require("react"); -import { ContentFittingDocumentView } from './ContentFittingDocumentView'; -import { undoBatch } from '../../util/UndoManager'; -import { setupMoveUpEvents, emptyFunction, returnOne, OmitKeys } from '../../../Utils'; -import { SnappingManager } from '../../util/SnappingManager'; -import { DocumentViewProps } from './DocumentView'; export const comparisonSchema = createSchema({}); @@ -84,7 +83,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null); return whichDoc ? <> - { - public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive - public ContentRef = React.createRef(); - - @observable public docView: DocumentView | undefined | null; - - @computed get layoutDoc() { return Doc.Layout(this.props.Document, this.props.LayoutTemplate?.()); } - - @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } - @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); } - @computed get nativeScaling() { - const nativeW = this.nativeWidth; - const nativeH = this.nativeHeight; - let scaling = 1; - if (nativeW && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / nativeH > this.props.PanelWidth() / nativeW)) { - scaling = this.props.PanelWidth() / nativeW; // width-limited or fitWidth - } else if (nativeW && nativeH) { - scaling = this.props.PanelHeight() / nativeH; // height-limited - } - console.log(this.props.Document.title + " " + scaling) - return scaling; - } - - @computed get panelWidth() { return this.nativeWidth ? this.nativeWidth * this.nativeScaling : this.props.PanelWidth(); } - @computed get panelHeight() { - if (this.nativeHeight) { - if (this.props.Document._fitWidth) { - return Math.min(this.props.PanelHeight(), NumCast(this.props.Document.scrollHeight, this.props.PanelHeight())); - } - else return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); - } - return this.props.PanelHeight(); - } - - @computed get Xshift() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } - @computed get YShift() { return this.nativeWidth && this.nativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } - @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } - @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.YShift; } - - NativeWidth = () => this.nativeWidth; - NativeHeight = () => this.nativeHeight; - PanelWidth = () => this.panelWidth; - PanelHeight = () => this.panelHeight; - NativeScaling = () => this.nativeScaling; - screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); - - render() { - TraceMobx(); - return (
    - {!this.props.Document || !this.props.PanelWidth() ? (null) : ( -
    0.001 ? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), - height: Math.abs(this.YShift) > 0.001 ? this.props.Document._fitWidth ? `${this.panelHeight}px` : `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), - }}> - this.docView = r)} - PanelWidth={this.PanelWidth} - PanelHeight={this.PanelHeight} - NativeWidth={this.NativeWidth} - NativeHeight={this.NativeHeight} - ContentScaling={this.NativeScaling} - ScreenToLocalTransform={this.screenToLocalTransform} - focus={this.props.focus || emptyFunction} - bringToFront={emptyFunction} - /> -
    )} -
    ); - } -} \ No newline at end of file diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx index b5c068b08..533a4931a 100644 --- a/src/client/views/nodes/DocHolderBox.tsx +++ b/src/client/views/nodes/DocHolderBox.tsx @@ -3,23 +3,22 @@ import { action, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc, Field } from "../../../fields/Doc"; import { collectionSchema, documentSchema } from "../../../fields/documentSchemas"; -import { makeInterface, listSpec } from "../../../fields/Schema"; +import { listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { emptyPath, returnFalse, returnOne, returnZero } from "../../../Utils"; +import { returnFalse } from "../../../Utils"; import { DocumentType } from "../../documents/DocumentTypes"; import { DragManager } from "../../util/DragManager"; import { undoBatch } from "../../util/UndoManager"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; -import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; +import { StyleProp } from "../StyleProvider"; import "./DocHolderBox.scss"; import { DocumentView } from "./DocumentView"; import { FieldView, FieldViewProps } from "./FieldView"; import React = require("react"); -import { StyleProp } from "../StyleProvider"; type DocHolderBoxSchema = makeInterface<[typeof documentSchema, typeof collectionSchema]>; const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); @@ -142,7 +141,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent : - obj.active = this.props.parentActive).omit, + ...OmitKeys(this.props, [...docOnlyProps], "", (obj: any) => obj.active = this.props.parentActive).omit, RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc, Document: this.layoutDoc, DataDoc: this.dataDoc, diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx index f2838981d..123212608 100644 --- a/src/client/views/nodes/DocumentIcon.tsx +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -9,13 +9,12 @@ import { Field } from "../../../fields/Doc"; export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> { render() { const view = this.props.view; - const transform = view.props.ScreenToLocalTransform().scale(view.LocalScaling).inverse(); - const { x, y, width, height } = transform.transformBounds(0, 0, view.props.PanelWidth(), view.props.PanelHeight()); + const { left, top, right, bottom } = view.getBounds() || { left: 0, top: 0, right: 0, bottom: 0 }; return (

    d{this.props.index}

    diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 8dadd2467..6f041e5ef 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -142,4 +142,27 @@ opacity: 1; } } +} +.contentFittingDocumentView { + position: relative; + display: flex; + width: 100%; + height: 100%; + + .contentFittingDocumentView-previewDoc { + position: relative; + display: inline; + } + + .contentFittingDocumentView-input { + position: absolute; + max-width: 150px; + width: 100%; + bottom: 0px; + } + + .documentView-node:first-child { + position: relative; + background: "#B59B66"; //$light-color; + } } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 010a270e6..61e17082a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -10,7 +10,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { emptyFunction, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; +import { emptyFunction, OmitKeys, returnFalse, Utils, returnVal } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -57,8 +57,6 @@ export interface DocumentViewSharedProps { CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; PanelWidth: () => number; PanelHeight: () => number; - NativeWidth?: () => number; - NativeHeight?: () => number; layerProvider?: (doc: Doc, assign?: boolean) => boolean; styleProvider?: StyleProviderFunc; focus: DocFocusFunc; @@ -88,10 +86,12 @@ export interface DocumentViewProps extends DocumentViewSharedProps { freezeDimensions?: boolean; hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings treeViewDoc?: Doc; - dragDivName?: string; contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents radialMenu?: String[]; LayoutTemplateString?: string; + dontCenter?: "x" | "y" | "xy"; + NativeWidth?: () => number; + NativeHeight?: () => number; LayoutTemplate?: () => Opt; ContentScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal contextMenuItems?: () => { script: ScriptField, label: string }[]; @@ -100,9 +100,16 @@ export interface DocumentViewProps extends DocumentViewSharedProps { onPointerUp?: () => ScriptField; } +export interface DocumentViewInternalProps { + NativeWidth: () => number; + NativeHeight: () => number; + isSelected: (outsideReaction?: boolean) => boolean; + select: (ctrlPressed: boolean) => void; + DocumentView: any; +} + @observer -export class DocumentView extends DocComponent(Document) { - public static ROOT_DIV = "documentView-effectsWrapper"; +export class DocumentViewInternal extends DocComponent(Document) { @observable _animateScalingTo = 0; private _downX: number = 0; private _downY: number = 0; @@ -118,37 +125,32 @@ export class DocumentView extends DocComponent(Docu private _holdDisposer?: InteractionUtils.MultiTouchEventDisposer; protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer; - private get active() { return this.isSelected(true) || this.props.parentActive(true); } + private get topMost() { return this.props.renderDepth === 0; } + private get active() { return this.props.isSelected(true) || this.props.parentActive(true); } 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 this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.ShowTitle) as (Opt); } - @computed get LocalScaling() { return this.props.ContentScaling?.() || 1; } - @computed get topMost() { return this.props.renderDepth === 0; } + @computed get ContentScale() { return this.props.ContentScaling?.() || 1; } @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 hideLinkButton() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkButton + (this.props.isSelected() ? ":selected" : "")); } + @computed get widgetDecorations() { return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Decorations + (this.props.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 pointerEvents() { return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (this.props.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 nativeWidth() { return this.props.NativeWidth(); } + @computed get nativeHeight() { return this.props.NativeHeight(); } @computed get onClickHandler() { return this.props.onClick?.() ?? Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); } @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() ?? (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) ?? this.Document.onDoubleClick); } @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ?? ScriptCast(this.Document.onPointerDown); } @computed get onPointerUpHandler() { return this.props.onPointerUp?.() ?? ScriptCast(this.Document.onPointerUp); } - NativeWidth = () => this.nativeWidth; - NativeHeight = () => this.nativeHeight; - onClickFunc = () => this.onClickHandler; - onDoubleClickFunc = () => this.onDoubleClickHandler; constructor(props: any) { super(props); - props.getView?.(this); } handle1PointerHoldStart = (e: Event, me: InteractionUtils.MultiTouchEvent): any => { @@ -210,9 +212,6 @@ export class DocumentView extends DocComponent(Docu @action componentDidMount() { this.componentDidUpdate(); - if (!BoolCast(this.rootDoc.dontRegisterView, this.props.dontRegisterView)) { - DocumentManager.Instance.AddView(this); - } } @action @@ -236,47 +235,20 @@ export class DocumentView extends DocComponent(Docu this._multiTouchDisposer?.(); this._holdDisposer?.(); Doc.UnBrushDoc(this.props.Document); - !this.props.dontRegisterView && DocumentManager.Instance.RemoveView(this); } startDragging(x: number, y: number, dropAction: dropActionType) { if (this._mainCont.current) { const dragData = new DragManager.DocumentDragData([this.props.Document]); - const [left, top] = this.props.ScreenToLocalTransform().scale(this.LocalScaling).inverse().transformPoint(0, 0); - dragData.offset = this.props.ScreenToLocalTransform().scale(this.LocalScaling).transformDirection(x - left, y - top); + const [left, top] = this.props.ScreenToLocalTransform().scale(this.ContentScale).inverse().transformPoint(0, 0); + dragData.offset = this.props.ScreenToLocalTransform().scale(this.ContentScale).transformDirection(x - left, y - top); dragData.dropAction = dropAction; dragData.removeDocument = this.props.removeDocument; dragData.moveDocument = this.props.moveDocument; - dragData.dragDivName = this.props.dragDivName; dragData.treeViewDoc = this.props.treeViewDoc; DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.layoutDoc.onDragStart }); } } - - @undoBatch @action - public static FloatDoc(topDocView: DocumentView) { - const { Document: topDoc, ContainingCollectionView: container } = topDocView.props; - const screenXf = container?.screenToLocalTransform(); - if (screenXf) { - SelectionManager.DeselectAll(); - 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]; - topDocView.props.removeDocument?.(topDoc); - topDocView.props.addDocTab(topDoc, "inParent"); - } else { - const spt = topDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - const fpt = screenXf.transformPoint(spt[0], spt[1]); - topDoc.z = 1; - topDoc.x = fpt[0]; - topDoc.y = fpt[1]; - } - setTimeout(() => SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); - } - } - onKeyDown = (e: React.KeyboardEvent) => { if (e.altKey && !e.nativeEvent.cancelBubble) { e.stopPropagation(); @@ -355,48 +327,14 @@ export class DocumentView extends DocComponent(Docu 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); + this.props.select(e.ctrlKey || e.shiftKey); } preventDefault = false; } stopPropagate && e.stopPropagation(); preventDefault && e.preventDefault(); } - }); - - // follows a link - if the target is on screen, it highlights/pans to it. - // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place - // depending on the followLinkLocation property of the source (or the link itself as a fallback); - public static followLinkClick = async (linkDoc: Opt, sourceDoc: Doc, docView: { - focus: DocFocusFunc, - addDocTab: (doc: Doc, where: string) => boolean, - ContainingCollectionDoc?: Doc - }, 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>) => { - const targetFocusAfterDocFocus = () => { - const where = StrCast(sourceDoc.followLinkLocation) || followLoc; - const hackToCallFinishAfterFocus = () => { - finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. - return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false - }; - const addTab = docView.addDocTab(doc, where); - addTab && setTimeout(() => { - const targDocView = DocumentManager.Instance.getFirstDocumentView(doc); - targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, false), undefined, hackToCallFinishAfterFocus); - }); // add the target and focus on it. - return where !== "inPlace" || addTab; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) - }; - if (!sourceDoc.followLinkZoom) { - targetFocusAfterDocFocus(); - } else { - // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target - docView.focus(sourceDoc, BoolCast(sourceDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); - } - }; - await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); - } + }).bind(this); handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent) => { SelectionManager.DeselectAll(); @@ -421,7 +359,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { this.removeMoveListeners(); } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { + else if (!e.cancelBubble && (this.props.isSelected(true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { const touch = me.touchEvent.changedTouches.item(0); if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { @@ -436,7 +374,7 @@ export class DocumentView extends DocComponent(Docu } handle2PointersDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent) => { - if (!e.nativeEvent.cancelBubble && !this.isSelected()) { + if (!e.nativeEvent.cancelBubble && !this.props.isSelected()) { e.stopPropagation(); e.preventDefault(); @@ -447,17 +385,6 @@ export class DocumentView extends DocComponent(Docu } } - public iconify() { - const layoutKey = Cast(this.props.Document.layoutKey, "string", null); - 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); - this.switchViews(deiconifyLayout ? true : false, deiconifyLayout); - this.props.Document.deiconifyLayout = undefined; - } - } @action handle2PointersMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent) => { @@ -480,7 +407,7 @@ export class DocumentView extends DocComponent(Docu let nheight = Doc.NativeHeight(layoutDoc); const width = (layoutDoc._width || 0); const height = (layoutDoc._height || (nheight / nwidth * width)); - const scale = this.props.ScreenToLocalTransform().Scale * this.LocalScaling; + const scale = this.props.ScreenToLocalTransform().Scale * this.ContentScale; const actualdW = Math.max(width + (dW * scale), 20); const actualdH = Math.max(height + (dH * scale), 20); doc.x = (doc.x || 0) + dX * (actualdW - width); @@ -523,7 +450,7 @@ export class DocumentView extends DocComponent(Docu if (!(InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE) || Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) { if (!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { e.stopPropagation(); - if (SelectionManager.IsSelected(this, true) && this.props.Document._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it + if (SelectionManager.IsSelected(this.props.DocumentView, true) && this.props.Document._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it // TODO: check here for panning/inking } return; @@ -538,7 +465,7 @@ export class DocumentView extends DocComponent(Docu (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { e.stopPropagation(); - if (SelectionManager.IsSelected(this, true) && this.layoutDoc._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it + if (SelectionManager.IsSelected(this.props.DocumentView, true) && this.layoutDoc._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it } document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -555,7 +482,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView) } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this.props.DocumentView, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); @@ -702,7 +629,7 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleNativeDimensions = () => { - Doc.toggleNativeDimensions(this.layoutDoc, this.LocalScaling, this.props.PanelWidth(), this.props.PanelHeight()); + Doc.toggleNativeDimensions(this.layoutDoc, this.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); } @undoBatch @@ -736,7 +663,7 @@ export class DocumentView extends DocComponent(Docu if (e && this.rootDoc._hideContextMenu && Doc.UserDoc().noviceMode) { e.preventDefault(); e.stopPropagation(); - !this.isSelected(true) && SelectionManager.SelectDoc(this, false); + !this.props.isSelected(true) && SelectionManager.SelectDoc(this.props.DocumentView, false); } // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 if (e) { @@ -818,7 +745,7 @@ export class DocumentView extends DocComponent(Docu const more = cm.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; if (!Doc.IsSystem(this.rootDoc)) { - (this.rootDoc._viewType !== CollectionViewType.Docking || !Doc.UserDoc().noviceMode) && moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "users" }); + (this.rootDoc._viewType !== CollectionViewType.Docking || !Doc.UserDoc().noviceMode) && moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this.props.DocumentView), icon: "users" }); //moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); @@ -853,26 +780,25 @@ export class DocumentView extends DocComponent(Docu e?.stopPropagation(); // DocumentViews should stop propagation of this event } cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); - !this.isSelected(true) && setTimeout(() => SelectionManager.SelectDoc(this, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectDoc(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. }); } - isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction); - select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }; rootSelected = (outsideReaction?: boolean) => { - return this.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; + return this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; } panelHeight = () => this.props.PanelHeight() - this.headerMargin; parentActive = (outsideReaction: boolean) => this.props.layerProvider?.(this.layoutDoc) === false ? this.props.parentActive(outsideReaction) : false; screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin); - contentScaling = () => this.LocalScaling; + contentScaling = () => this.ContentScale; + onClickFunc = () => this.onClickHandler; + onDoubleClickFunc = () => this.onDoubleClickHandler; @observable contentsActive: () => boolean = returnFalse; @action setContentsActive = (setActive: () => boolean) => this.contentsActive = setActive; @computed get contents() { - console.log(this.props.Document.title + " " + this.LocalScaling + " " + this.contentScaling()) TraceMobx(); return (
    (Docu fitContentsToDoc={this.props.fitContentsToDoc} ContainingCollectionView={this.props.ContainingCollectionView} ContainingCollectionDoc={this.props.ContainingCollectionDoc} - NativeWidth={this.NativeWidth} - NativeHeight={this.NativeHeight} PanelWidth={this.props.PanelWidth} PanelHeight={this.props.PanelHeight} scaling={this.contentScaling} @@ -912,14 +836,16 @@ export class DocumentView extends DocComponent(Docu ScreenToLocalTransform={this.screenToLocal} ignoreAutoHeight={this.props.ignoreAutoHeight} bringToFront={this.props.bringToFront} - isSelected={this.isSelected} - select={this.select} + isSelected={this.props.isSelected} + select={this.props.select} rootSelected={this.rootSelected} scriptContext={this.props.scriptContext} onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} - {this.hideLinkButton ? (null) : } + {this.hideLinkButton ? + (null) : + }
    ); } @@ -933,8 +859,7 @@ export class DocumentView extends DocComponent(Docu return anchor.type === DocumentType.AUDIO && NumCast(ept) ? false : true; } - @observable _link: Opt; // see DocumentButtonBar for explanation of how this works - 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. + makeLink = () => this.props.DocumentView._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, doc) => flg && (doc.hidden = true), true) @@ -998,8 +923,6 @@ export class DocumentView extends DocComponent(Docu styleProvider={this.captionStyleProvider} dontRegisterView={true} LayoutTemplateString={``} - isSelected={this.isSelected} - select={this.select} onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} />
    ); @@ -1027,21 +950,7 @@ export class DocumentView extends DocComponent(Docu {captionView}
    ; } - @undoBatch - @action - setCustomView = (custom: boolean, layout: string): void => { - Doc.setNativeView(this.props.Document); - custom && DocUtils.makeCustomViewClicked(this.props.Document, Docs.Create.StackingDocument, layout, undefined); - } - switchViews = action((custom: boolean, view: string) => { - this._animateScalingTo = 0.1; // shrink doc - setTimeout(action(() => { - this.setCustomView(custom, view); - this._animateScalingTo = 1; // expand it - setTimeout(action(() => this._animateScalingTo = 0), 400); - }), 400); - }); @computed get renderDoc() { TraceMobx(); @@ -1077,7 +986,7 @@ export class DocumentView extends DocComponent(Docu onContextMenu={this.onContextMenu} onKeyDown={this.onKeyDown} onPointerDown={this.onPointerDown} - onClick={this.onClick} + onClick={this.onClick.bind(this)} onPointerEnter={action(e => !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))} onPointerLeave={action(e => { let entered = false; @@ -1106,3 +1015,210 @@ Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(otherKey !== "layout", otherKey.replace("layout_", "")); else dv?.switchViews(true, layoutKey.replace("layout_", "")); }); + +@observer +export class DocumentView extends React.Component { + public static ROOT_DIV = "documentView-effectsWrapper"; + public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive + public ContentRef = React.createRef(); + + @observable _link: Opt; // see DocumentButtonBar for explanation of how this works + @observable public docView: DocumentViewInternal | undefined | null; + + get rootDoc() { return this.docView?.rootDoc || this.Document; } + get dataDoc() { return this.docView?.dataDoc || this.Document; } + get finalLayoutKey() { return this.docView?.finalLayoutKey || "layout"; } + get ContentDiv() { return this.docView?.ContentDiv; } + get allLinks() { return this.docView?.allLinks || []; } + get LayoutFieldKey() { return this.docView?.LayoutFieldKey || "layout"; } + toggleFollowLink = (location: Opt, zoom: boolean, setPushpin: boolean) => this.docView?.toggleFollowLink(location, zoom, setPushpin); + toggleNativeDimensions = () => this.docView?.toggleNativeDimensions(); + contentsActive = () => this.docView?.contentsActive(); + + + // follows a link - if the target is on screen, it highlights/pans to it. + // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place + // depending on the followLinkLocation property of the source (or the link itself as a fallback); + public static followLinkClick = async (linkDoc: Opt, sourceDoc: Doc, docView: { + focus: DocFocusFunc, + addDocTab: (doc: Doc, where: string) => boolean, + ContainingCollectionDoc?: Doc + }, 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>) => { + const targetFocusAfterDocFocus = () => { + const where = StrCast(sourceDoc.followLinkLocation) || followLoc; + const hackToCallFinishAfterFocus = () => { + finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. + return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false + }; + const addTab = docView.addDocTab(doc, where); + addTab && setTimeout(() => { + const targDocView = DocumentManager.Instance.getFirstDocumentView(doc); + targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, false), undefined, hackToCallFinishAfterFocus); + }); // add the target and focus on it. + return where !== "inPlace" || addTab; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) + }; + if (!sourceDoc.followLinkZoom) { + targetFocusAfterDocFocus(); + } else { + // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target + docView.focus(sourceDoc, BoolCast(sourceDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); + } + }; + await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); + } + + @undoBatch @action + public static FloatDoc(topDocView: DocumentView) { + const { Document: topDoc, ContainingCollectionView: container } = topDocView.props; + const screenXf = container?.screenToLocalTransform(); + if (screenXf) { + SelectionManager.DeselectAll(); + 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]; + topDocView.props.removeDocument?.(topDoc); + topDocView.props.addDocTab(topDoc, "inParent"); + } else { + const spt = topDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const fpt = screenXf.transformPoint(spt[0], spt[1]); + topDoc.z = 1; + topDoc.x = fpt[0]; + topDoc.y = fpt[1]; + } + setTimeout(() => SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); + } + } + + get Document() { return this.props.Document; } + get topMost() { return this.props.renderDepth === 0; } + @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } + + @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } + @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); } + @computed get nativeScaling() { + const nativeW = this.nativeWidth; + const nativeH = this.nativeHeight; + let scaling = 1; + if (nativeW && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / nativeH > this.props.PanelWidth() / nativeW)) { + scaling = this.props.PanelWidth() / nativeW; // width-limited or fitWidth + } else if (nativeW && nativeH) { + scaling = this.props.PanelHeight() / nativeH; // height-limited + } + return scaling; + } + + @computed get panelWidth() { return this.nativeWidth ? this.nativeWidth * this.nativeScaling : this.props.PanelWidth(); } + @computed get panelHeight() { + if (this.nativeHeight) { + if (this.props.Document._fitWidth) { + return Math.min(this.props.PanelHeight(), NumCast(this.props.Document.scrollHeight, this.props.PanelHeight())); + } + else return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); + } + return this.props.PanelHeight(); + } + + @computed get Xshift() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } + @computed get YShift() { return this.nativeWidth && this.nativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } + @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } + @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.YShift; } + + getBounds = () => { + if (!this.docView || + !this.docView.ContentDiv || + this.docView.props.renderDepth === 0 || + this.docView.props.treeViewDoc || + Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { + return undefined; + } + const xf = this.docView?.props.ScreenToLocalTransform(); + const transform = (xf.scale(this.nativeScaling)).inverse(); + var [left, top] = transform.transformPoint(0, 0); + let [right, bottom] = transform.transformPoint(this.PanelWidth(), this.PanelHeight()); + if (this.docView.props.LayoutTemplateString?.includes("LinkAnchorBox")) { + const docuBox = this.docView.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); + if (docuBox.length) { + return docuBox[0].getBoundingClientRect(); + } + } + return { left, top, right, bottom }; + } + + public iconify() { + const layoutKey = Cast(this.Document.layoutKey, "string", null); + if (layoutKey !== "layout_icon") { + this.switchViews(true, "icon"); + if (layoutKey && layoutKey !== "layout" && layoutKey !== "layout_icon") this.Document.deiconifyLayout = layoutKey.replace("layout_", ""); + } else { + const deiconifyLayout = Cast(this.Document.deiconifyLayout, "string", null); + this.switchViews(deiconifyLayout ? true : false, deiconifyLayout); + this.Document.deiconifyLayout = undefined; + } + } + @undoBatch + @action + setCustomView = (custom: boolean, layout: string): void => { + Doc.setNativeView(this.props.Document); + custom && DocUtils.makeCustomViewClicked(this.props.Document, Docs.Create.StackingDocument, layout, undefined); + } + switchViews = action((custom: boolean, view: string) => { + this.docView && (this.docView._animateScalingTo = 0.1); // shrink doc + setTimeout(action(() => { + this.setCustomView(custom, view); + this.docView && (this.docView._animateScalingTo = 1); // expand it + setTimeout(action(() => this.docView && (this.docView._animateScalingTo = 0)), 400); + }), 400); + }); + + isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction); + select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed); + NativeWidth = () => this.nativeWidth; + NativeHeight = () => this.nativeHeight; + PanelWidth = () => this.panelWidth; + PanelHeight = () => this.panelHeight; + ContentScale = () => this.nativeScaling; + screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); + + componentDidMount() { + if (!BoolCast(this.props.Document.dontRegisterView, this.props.dontRegisterView)) { + DocumentManager.Instance.AddView(this); + } + } + componentWillUnmount() { + !this.props.dontRegisterView && DocumentManager.Instance.RemoveView(this); + } + + render() { + TraceMobx(); + return (
    + {!this.props.Document || !this.props.PanelWidth() ? (null) : ( +
    0.001 ? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), + height: Math.abs(this.YShift) > 0.001 ? this.props.Document._fitWidth ? `${this.panelHeight}px` : `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), + }}> + this.docView = r)} + PanelWidth={this.PanelWidth} + PanelHeight={this.PanelHeight} + NativeWidth={this.NativeWidth} + NativeHeight={this.NativeHeight} + isSelected={this.isSelected} + select={this.select} + ContentScaling={this.ContentScale} + ScreenToLocalTransform={this.screenToLocalTransform} + focus={this.props.focus || emptyFunction} + bringToFront={emptyFunction} + /> +
    )} +
    ); + } +} diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index fd2425950..c69fb5b33 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -2,17 +2,16 @@ import { action, computed, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; import wiki from "wikijs"; import { Doc, DocCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { Id } from '../../../fields/FieldSymbols'; import { Cast, FieldValue, NumCast } from "../../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero, returnEmptyDoclist } from "../../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; import { Transform } from "../../util/Transform"; import { ContextMenu } from '../ContextMenu'; -import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; import { DocumentLinksButton } from './DocumentLinksButton'; +import { DocumentView, StyleProviderFunc } from "./DocumentView"; import React = require("react"); -import { StyleProviderFunc } from './DocumentView'; -import { Id } from '../../../fields/FieldSymbols'; interface Props { linkDoc?: Doc; @@ -92,7 +91,7 @@ export class LinkDocPreview extends React.Component {
    : -
    { - Doc.toggleNativeDimensions(this.layoutDoc, 1, this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); + alert("need to fix"); + // Doc.toggleNativeDimensions(this.layoutDoc, 1, this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0); } public static get DefaultLayout(): Doc | string | undefined { diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 447ff5865..c6be25dc2 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -6,16 +6,15 @@ import { EditorState, Plugin } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import * as ReactDOM from 'react-dom'; import wiki from "wikijs"; -import { Doc, DocCastAsync, Opt, DocListCast } from "../../../../fields/Doc"; +import { Doc, DocCastAsync, DocListCast, Opt } from "../../../../fields/Doc"; import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, Utils } from "../../../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; import { Docs } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; import { LinkManager } from "../../../util/LinkManager"; import { Transform } from "../../../util/Transform"; import { undoBatch } from "../../../util/UndoManager"; -import { ContentFittingDocumentView } from "../ContentFittingDocumentView"; import { DocumentLinksButton } from "../DocumentLinksButton"; import { DocumentView } from "../DocumentView"; import { LinkDocPreview } from "../LinkDocPreview"; @@ -295,7 +294,7 @@ export class FormattedTextBoxComment {
    - - Date: Mon, 14 Dec 2020 20:49:31 -0500 Subject: minor cleanup --- src/client/views/GlobalKeyHandler.ts | 2 +- src/client/views/StyleProvider.tsx | 6 +- src/client/views/collections/CollectionMenu.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/DocumentLinksButton.tsx | 12 +-- src/client/views/nodes/DocumentView.tsx | 89 ++++++++++------------ .../views/nodes/formattedText/DashDocView.tsx | 1 - .../views/nodes/formattedText/RichTextSchema.tsx | 5 +- 9 files changed, 52 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index a727e58a4..a391bb550 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -180,7 +180,7 @@ export class KeyManager { case "Æ’": case "f": const dv = SelectionManager.SelectedDocuments()?.[0]; - dv && DocumentView.FloatDoc(dv); + UndoManager.RunInBatch(() => dv?.float(), "float"); } return { diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index d22f34cd0..9ed8a2924 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -61,14 +61,14 @@ function toggleBackground(doc: Doc) { } export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentViewProps { - return (toBeDetermined?.select) ? false : true; + return (toBeDetermined?.active) ? undefined : toBeDetermined; } // // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { - const docProps = testDocProps(props); + const docProps = testDocProps(props) ? props : undefined; const selected = property.includes(":selected"); switch (property.split(":")[0]) { case StyleProp.DocContents: return undefined; @@ -133,7 +133,7 @@ export function DefaultStyleProvider(doc: Opt, props: OptToggle Overlay Layer
    } placement="bottom"> } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 31a1a2b99..e289f24a9 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -503,7 +503,7 @@ export class TreeView extends React.Component { switch (property.split(":")[0]) { case StyleProp.Opacity: return this.outlineMode ? undefined : 1; case StyleProp.BackgroundColor: return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); - case StyleProp.DocContents: return testDocProps(props) && !props?.treeViewDoc ? (null) : + case StyleProp.DocContents: return testDocProps(props) && props?.treeViewDoc ? (null) :
    this.props.View._link = linkDoc); - setTimeout(action(() => this.props.View._link = undefined), 0); + runInAction(() => this.props.View.LinkBeingCreated = linkDoc); + setTimeout(action(() => this.props.View.LinkBeingCreated = undefined), 0); } linkDrag?.end(); }, @@ -164,11 +164,11 @@ export class DocumentLinksButton extends React.Component { - DocumentLinksButton.StartLinkView && (DocumentLinksButton.StartLinkView._link = undefined); - endLinkView._link = undefined; + DocumentLinksButton.StartLinkView && (DocumentLinksButton.StartLinkView.LinkBeingCreated = undefined); + endLinkView.LinkBeingCreated = undefined; }), 0); } LinkManager.currentLink = linkDoc; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 61e17082a..9405b1ed5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -90,17 +90,17 @@ export interface DocumentViewProps extends DocumentViewSharedProps { radialMenu?: String[]; LayoutTemplateString?: string; dontCenter?: "x" | "y" | "xy"; + ContentScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal NativeWidth?: () => number; NativeHeight?: () => number; LayoutTemplate?: () => Opt; - ContentScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal contextMenuItems?: () => { script: ScriptField, label: string }[]; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; onPointerUp?: () => ScriptField; } -export interface DocumentViewInternalProps { +export interface DocumentViewInternalProps extends DocumentViewProps { NativeWidth: () => number; NativeHeight: () => number; isSelected: (outsideReaction?: boolean) => boolean; @@ -109,7 +109,7 @@ export interface DocumentViewInternalProps { } @observer -export class DocumentViewInternal extends DocComponent(Document) { +export class DocumentViewInternal extends DocComponent(Document) { @observable _animateScalingTo = 0; private _downX: number = 0; private _downY: number = 0; @@ -134,7 +134,7 @@ export class DocumentViewInternal extends DocComponent
    ); } - captionStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + captionStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (property === StyleProp.Color) return "white"; if (property === StyleProp.BackgroundColor) return "rgba(0,0,0 ,0.4)"; return this.props?.styleProvider?.(doc, props, property); @@ -951,7 +951,6 @@ export class DocumentViewInternal extends DocComponent; } - @computed get renderDoc() { TraceMobx(); if (!(this.props.Document instanceof Doc) || GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate || this.hidden) return null; @@ -996,6 +995,7 @@ export class DocumentViewInternal extends DocComponent { public static ROOT_DIV = "documentView-effectsWrapper"; public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive public ContentRef = React.createRef(); - @observable _link: Opt; // see DocumentButtonBar for explanation of how this works + @observable LinkBeingCreated: Opt; // see DocumentLinksButton for explanation of how this works @observable public docView: DocumentViewInternal | undefined | null; get rootDoc() { return this.docView?.rootDoc || this.Document; } @@ -1035,7 +1029,6 @@ export class DocumentView extends React.Component { toggleNativeDimensions = () => this.docView?.toggleNativeDimensions(); contentsActive = () => this.docView?.contentsActive(); - // follows a link - if the target is on screen, it highlights/pans to it. // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place // depending on the followLinkLocation property of the source (or the link itself as a fallback); @@ -1070,9 +1063,8 @@ export class DocumentView extends React.Component { await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); } - @undoBatch @action - public static FloatDoc(topDocView: DocumentView) { - const { Document: topDoc, ContainingCollectionView: container } = topDocView.props; + @action public float = () => { + const { Document: topDoc, ContainingCollectionView: container } = this.props; const screenXf = container?.screenToLocalTransform(); if (screenXf) { SelectionManager.DeselectAll(); @@ -1081,10 +1073,10 @@ export class DocumentView extends React.Component { topDoc.z = 0; topDoc.x = spt[0]; topDoc.y = spt[1]; - topDocView.props.removeDocument?.(topDoc); - topDocView.props.addDocTab(topDoc, "inParent"); + this.props.removeDocument?.(topDoc); + this.props.addDocTab(topDoc, "inParent"); } else { - const spt = topDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const spt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); const fpt = screenXf.transformPoint(spt[0], spt[1]); topDoc.z = 1; topDoc.x = fpt[0]; @@ -1129,22 +1121,14 @@ export class DocumentView extends React.Component { @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.YShift; } getBounds = () => { - if (!this.docView || - !this.docView.ContentDiv || - this.docView.props.renderDepth === 0 || - this.docView.props.treeViewDoc || - Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { + if (!this.docView || !this.docView.ContentDiv || this.docView.props.renderDepth === 0 || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { return undefined; } - const xf = this.docView?.props.ScreenToLocalTransform(); - const transform = (xf.scale(this.nativeScaling)).inverse(); - var [left, top] = transform.transformPoint(0, 0); - let [right, bottom] = transform.transformPoint(this.PanelWidth(), this.PanelHeight()); + const xf = (this.docView?.props.ScreenToLocalTransform().scale(this.nativeScaling)).inverse(); + const [[left, top], [right, bottom]] = [xf.transformPoint(0, 0), xf.transformPoint(this.panelWidth, this.panelHeight)]; if (this.docView.props.LayoutTemplateString?.includes("LinkAnchorBox")) { const docuBox = this.docView.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); - if (docuBox.length) { - return docuBox[0].getBoundingClientRect(); - } + if (docuBox.length) return docuBox[0].getBoundingClientRect(); } return { left, top, right, bottom }; } @@ -1185,9 +1169,7 @@ export class DocumentView extends React.Component { screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); componentDidMount() { - if (!BoolCast(this.props.Document.dontRegisterView, this.props.dontRegisterView)) { - DocumentManager.Instance.AddView(this); - } + !BoolCast(this.props.Document.dontRegisterView, this.props.dontRegisterView) && DocumentManager.Instance.AddView(this); } componentWillUnmount() { !this.props.dontRegisterView && DocumentManager.Instance.RemoveView(this); @@ -1195,30 +1177,37 @@ export class DocumentView extends React.Component { render() { TraceMobx(); + const internalProps = { + ...this.props, + DocumentView: this, + PanelWidth: this.PanelWidth, + PanelHeight: this.PanelHeight, + NativeWidth: this.NativeWidth, + NativeHeight: this.NativeHeight, + isSelected: this.isSelected, + select: this.select, + ContentScaling: this.ContentScale, + ScreenToLocalTransform: this.screenToLocalTransform, + focus: this.props.focus || emptyFunction, + bringToFront: emptyFunction, + } return (
    {!this.props.Document || !this.props.PanelWidth() ? (null) : (
    0.001 ? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), height: Math.abs(this.YShift) > 0.001 ? this.props.Document._fitWidth ? `${this.panelHeight}px` : `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), }}> - this.docView = r)} - PanelWidth={this.PanelWidth} - PanelHeight={this.PanelHeight} - NativeWidth={this.NativeWidth} - NativeHeight={this.NativeHeight} - isSelected={this.isSelected} - select={this.select} - ContentScaling={this.ContentScale} - ScreenToLocalTransform={this.screenToLocalTransform} - focus={this.props.focus || emptyFunction} - bringToFront={emptyFunction} - /> + this.docView = r)} />
    )}
    ); } } + + +Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string = "layout") { + const dv = DocumentManager.Instance.getDocumentView(doc); + if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(otherKey !== "layout", otherKey.replace("layout_", "")); + else dv?.switchViews(true, layoutKey.replace("layout_", "")); +}); \ No newline at end of file diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index d834276c7..1fbd3af5c 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -246,7 +246,6 @@ export class DashDocView extends React.Component { searchFilterDocs={this.props.tbox?.props.searchFilterDocs || returnEmptyDoclist} ContainingCollectionView={this._textBox.props.ContainingCollectionView} ContainingCollectionDoc={this._textBox.props.ContainingCollectionDoc} - ContentScaling={this.contentScaling} />
    diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx index 2f180a228..d272b6b8c 100644 --- a/src/client/views/nodes/formattedText/RichTextSchema.tsx +++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx @@ -26,11 +26,9 @@ export class DashDocView { //moved getDocTransform = () => { const { scale, translateX, translateY } = Utils.GetScreenTransform(this._outer); - return new Transform(-translateX, -translateY, 1).scale(1 / this.contentScaling() / scale); + return new Transform(-translateX, -translateY, 1).scale(1 / scale); } - //moved - contentScaling = () => Doc.NativeWidth(this._dashDoc) > 0 ? this._dashDoc![WidthSym]() / Doc.NativeWidth(this._dashDoc) : 1; //moved outerFocus = (target: Doc) => this._textBox.props.focus(this._textBox.props.Document); // ideally, this would scroll to show the focus target @@ -155,7 +153,6 @@ export class DashDocView { searchFilterDocs={this._textBox.props.searchFilterDocs} ContainingCollectionView={this._textBox.props.ContainingCollectionView} ContainingCollectionDoc={this._textBox.props.ContainingCollectionDoc} - ContentScaling={this.contentScaling} />, this._dashSpan); if (node.attrs.width !== dashDoc._width + "px" || node.attrs.height !== dashDoc._height + "px") { -- cgit v1.2.3-70-g09d2 From 740345491f401dfd194152f0954fe1c3bc16242b Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 14 Dec 2020 21:09:16 -0500 Subject: fixed text boxes to be scalable with ctrl --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index bf0832211..f619909de 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1610,7 +1610,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp />; } - sidebarContentScaling = () => NumCast(this.layoutDoc._viewScale, 1); + sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); @computed get sidebarCollection() { const fitToBox = this.props.Document._fitToBox; const collectionProps: SubCollectionViewProps & collectionFreeformViewProps = { @@ -1648,13 +1648,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); - sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1)); + sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / (this.props.scaling?.() || 1), 0).scale(1 / NumCast(this.layoutDoc._viewScale, 1)); @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); } render() { TraceMobx(); const selected = this.props.isSelected(); const active = this.active(); - const scale = this.props.hideOnLeave ? 1 : NumCast(this.layoutDoc._viewScale, 1); + const scale = this.props.hideOnLeave ? 1 : (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = (Doc.GetSelectedTool() === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false); if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(() => FormattedTextBoxComment.Hide()); -- cgit v1.2.3-70-g09d2 From 189b6c30f69f8cf461d962a63c966232235187df Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 14 Dec 2020 22:04:55 -0500 Subject: moved onClick into DocumentViewProps from shared props. --- src/client/views/GestureOverlay.tsx | 1 - src/client/views/MainView.tsx | 5 ----- src/client/views/Palette.tsx | 1 - src/client/views/collections/CollectionLinearView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 4 ++-- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 9 +-------- src/mobile/AudioUpload.tsx | 1 - src/mobile/MobileInterface.tsx | 1 - 8 files changed, 3 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index b32acce62..3f57d3eb9 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -893,7 +893,6 @@ export class GestureOverlay extends Touchable { addDocTab={returnFalse} rootSelected={returnTrue} pinToPres={emptyFunction} - onClick={undefined} removeDocument={undefined} ScreenToLocalTransform={this.screenToLocalTransform} PanelWidth={this.return300} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 17f2e0d89..14da5049e 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -247,7 +247,6 @@ export class MainView extends React.Component { addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} rootSelected={returnTrue} - onClick={undefined} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} PanelWidth={this.getPWidth} @@ -310,7 +309,6 @@ export class MainView extends React.Component { pinToPres={emptyFunction} rootSelected={returnTrue} removeDocument={returnFalse} - onClick={undefined} ScreenToLocalTransform={this.mainContainerXf} PanelWidth={this.flyoutWidthFunc} PanelHeight={this.getContentsHeight} @@ -341,7 +339,6 @@ export class MainView extends React.Component { pinToPres={emptyFunction} rootSelected={returnTrue} removeDocument={returnFalse} - onClick={undefined} ScreenToLocalTransform={this.sidebarScreenToLocal} PanelWidth={this.menuPanelWidth} PanelHeight={this.getContentsHeight} @@ -460,7 +457,6 @@ export class MainView extends React.Component { addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} removeDocument={this.remButtonDoc} - onClick={undefined} ScreenToLocalTransform={this.buttonBarXf} PanelWidth={this.flyoutWidthFunc} PanelHeight={this.getContentsHeight} @@ -521,7 +517,6 @@ export class MainView extends React.Component { addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} rootSelected={returnTrue} - onClick={undefined} styleProvider={DefaultStyleProvider} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index 304687123..d181c7651 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -45,7 +45,6 @@ export default class Palette extends React.Component { rootSelected={returnTrue} pinToPres={emptyFunction} removeDocument={undefined} - onClick={undefined} ScreenToLocalTransform={Transform.Identity} PanelWidth={() => window.screen.width} PanelHeight={() => window.screen.height} diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 99a11de15..756346356 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -146,7 +146,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { pinToPres={emptyFunction} rootSelected={this.props.isSelected} removeDocument={this.props.removeDocument} - onClick={undefined} ScreenToLocalTransform={this.getTransform(dref)} PanelWidth={nested ? pair.layout[WidthSym] : this.dimension} PanelHeight={nested ? pair.layout[HeightSym] : this.dimension} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 9405b1ed5..c2c863284 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -74,7 +74,6 @@ export interface DocumentViewSharedProps { pinToPres: (document: Doc) => void; ScreenToLocalTransform: () => Transform; bringToFront: (doc: Doc, sendToBack?: boolean) => void; - onClick?: () => ScriptField; dropAction?: dropActionType; dontRegisterView?: boolean; ignoreAutoHeight?: boolean; @@ -95,6 +94,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { NativeHeight?: () => number; LayoutTemplate?: () => Opt; contextMenuItems?: () => { script: ScriptField, label: string }[]; + onClick?: () => ScriptField; onDoubleClick?: () => ScriptField; onPointerDown?: () => ScriptField; onPointerUp?: () => ScriptField; @@ -1190,7 +1190,7 @@ export class DocumentView extends React.Component { ScreenToLocalTransform: this.screenToLocalTransform, focus: this.props.focus || emptyFunction, bringToFront: emptyFunction, - } + }; return (
    {!this.props.Document || !this.props.PanelWidth() ? (null) : (
    { - this.doLinkOnDeselect(); FormattedTextBoxComment.textBox = this; - if (this.props.onClick && e.button === 0 && !this.props.isSelected(false)) { - e.preventDefault(); - } if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar e.stopPropagation(); // if the text box is selected, then it consumes all down events @@ -1715,7 +1708,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
    diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx index e73950f42..d32e19ee1 100644 --- a/src/mobile/AudioUpload.tsx +++ b/src/mobile/AudioUpload.tsx @@ -89,7 +89,6 @@ export class AudioUpload extends React.Component { docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} - onClick={undefined} ScreenToLocalTransform={Transform.Identity} PanelWidth={() => 600} PanelHeight={() => 400} diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index a901d317f..c4a6433c8 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -206,7 +206,6 @@ export class MobileInterface extends React.Component { pinToPres={emptyFunction} rootSelected={returnFalse} removeDocument={undefined} - onClick={undefined} ScreenToLocalTransform={Transform.Identity} PanelWidth={this.returnWidth} PanelHeight={this.returnHeight} -- cgit v1.2.3-70-g09d2 From 5fd6d3d0a04d30a630be0bef8fcb045cdf57fb86 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 14 Dec 2020 22:44:57 -0500 Subject: fixed linkButton boxShadow so it will show up --- src/client/views/StyleProvider.tsx | 22 +++++++++++++--------- src/client/views/nodes/DocumentView.tsx | 8 ++++---- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 9ed8a2924..74e4e9bee 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -70,6 +70,10 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { const docProps = testDocProps(props) ? props : undefined; const selected = property.includes(":selected"); + const isBackground = () => StrListCast(doc?.layers).includes(StyleLayers.Background); + const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); + const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); + switch (property.split(":")[0]) { case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return darkScheme() ? "lightgrey" : "dimgrey"; @@ -80,7 +84,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 600 || col.alpha() < 0.25) return "black"; @@ -111,7 +115,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 0 ? Doc.UserDoc().activeCollectionNestedBackground : @@ -124,16 +128,17 @@ export function DefaultStyleProvider(doc: Opt, props: Opt StrListCast(doc.layers).includes(StyleLayers.Background); + if (!doc || opacity() === 0) return undefined; // if it's not visible, then no shadow) const backgroundHalo = (doc: Doc) => props?.ContainingCollectionDoc?._useClusters || NumCast(doc.group, -1) !== -1; + if (doc?.isLinkButton && doc.type !== DocumentType.LINK) return StrCast(doc?._linkButtonShadow, "lightblue 0em 0em 1em"); + switch (doc?.type) { case DocumentType.COL: return isBackground() ? undefined : `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; default: return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow - backgroundHalo(doc) && doc.type !== DocumentType.INK ? (`${props?.styleProvider?.(doc, props, StyleProp.BackgroundColor)} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + backgroundHalo(doc) && doc.type !== DocumentType.INK ? (`${backgroundCol()} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent isBackground() ? undefined : // if it's a background & has a cluster color, make the shadow spread really big StrCast(doc.boxShadow, ""); } @@ -141,17 +146,16 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 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)) ?
    toggleBackground(doc)}> - +
    : (null); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index c2c863284..a005a5db4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -981,6 +981,9 @@ export class DocumentViewInternal extends DocComponent {PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc} -- cgit v1.2.3-70-g09d2 From 2c3b8155deea0bc7916e4bcded7c969d155cbd38 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 15 Dec 2020 00:28:55 -0500 Subject: fixed borderradius for videos & images to match highlight border radius --- src/client/views/.DS_Store | Bin 10244 -> 10244 bytes src/client/views/StyleProvider.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 8 ++------ src/client/views/nodes/ImageBox.tsx | 5 ++++- src/client/views/nodes/VideoBox.scss | 1 + src/client/views/nodes/VideoBox.tsx | 5 ++++- 6 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store index 14e9f6680..33e624ef4 100644 Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 74e4e9bee..f2569edbd 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -90,7 +90,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 600 || col.alpha() < 0.25) return "black"; return "white"; case StyleProp.Hidden: return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); - case StyleProp.BorderRounding: return !doc ? undefined : StrCast(doc._borderRounding, StrCast(doc.borderRounding)); + case StyleProp.BorderRounding: return StrCast(doc?._borderRounding, StrCast(doc?.borderRounding)); case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && doc?._showTitle && !doc?._showTitleHover ? 15 : 0; case StyleProp.BackgroundColor: { if (Doc.UserDoc().renderStyle === "comic") return "transparent"; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 305e01c93..a06dd530b 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -136,9 +136,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this; render() { TraceMobx(); - const backgroundColor = this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor); - const borderRadius = this.props.styleProvider?.(this.Document, this.props, StyleProp.BorderRounding); - const boxShadow = this.props.styleProvider?.(this.Document, this.props, StyleProp.BoxShadow); + const backgroundColor = () => this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor); const divProps: DocumentViewProps = { ...this.props, CollectionFreeFormDocumentView: this.returnThis, @@ -149,8 +147,6 @@ export class CollectionFreeFormDocumentView extends DocComponent + style={{ stroke: "black", fill: backgroundColor(), strokeWidth: 0.2 }} />
    } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 403b12f0d..393ba07e6 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -26,6 +26,7 @@ import { FaceRectangles } from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); +import { StyleProp } from '../StyleProvider'; const path = require('path'); const { Howl } = require('howler'); @@ -403,12 +404,14 @@ export class ImageBox extends ViewBoxAnnotatableComponent this.props.ScreenToLocalTransform(); contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content]; render() { + const borderRad = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BorderRounding); + const borderRadius = borderRad?.includes("px") ? `${Number(borderRad.split("px")[0]) / (this.props.scaling?.() || 1)}px` : borderRad; return (
    Date: Tue, 15 Dec 2020 13:01:18 -0500 Subject: simplifying dragging to make links by moving linkDocument to event, instead of dragData. moved link anchor and caption styling to default style provider. CURRENTLY, typing text, brushing doc highlights along with a bunch of other things ARE BROKEN .. --- src/client/documents/Documents.ts | 34 +- src/client/util/DragManager.ts | 7 +- src/client/views/StyleProvider.tsx | 9 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentLinksButton.tsx | 9 +- src/client/views/nodes/DocumentView.tsx | 386 ++++++++------------- src/client/views/nodes/WebBox.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 9 +- src/client/views/pdf/PDFViewer.tsx | 6 +- 9 files changed, 197 insertions(+), 269 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 95daecc64..8fd906dc7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1,4 +1,4 @@ -import { runInAction } from "mobx"; +import { runInAction, action } from "mobx"; import { basename, extname } from "path"; import { DateField } from "../../fields/DateField"; import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc"; @@ -53,6 +53,8 @@ import { PresElementBox } from "../views/presentationview/PresElementBox"; import { SearchBox } from "../views/search/SearchBox"; import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { DocumentType } from "./DocumentTypes"; +import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox"; +import { LinkDescriptionPopup } from "../views/nodes/LinkDescriptionPopup"; const path = require('path'); const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", "")); @@ -1011,11 +1013,37 @@ export namespace DocUtils { DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline")); } - export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, allowParCollectionLink?: boolean) { + export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, allowParCollectionLink?: boolean, showPopup?: number[]) { const sv = DocumentManager.Instance.getDocumentView(source.doc); if (!allowParCollectionLink && sv?.props.ContainingCollectionDoc === target.doc) return; if (target.doc === Doc.UserDoc()) return undefined; + + const makeLink = action((linkDoc: Doc, showPopup: number[]) => { + LinkManager.currentLink = linkDoc; + + TaskCompletionBox.textDisplayed = "Link Created"; + TaskCompletionBox.popupX = showPopup[0]; + TaskCompletionBox.popupY = showPopup[1] - 33; + TaskCompletionBox.taskCompleted = true; + + LinkDescriptionPopup.popupX = showPopup[0]; + LinkDescriptionPopup.popupY = showPopup[1]; + LinkDescriptionPopup.descriptionPopup = true; + + const rect = document.body.getBoundingClientRect(); + if (LinkDescriptionPopup.popupX + 200 > rect.width) { + LinkDescriptionPopup.popupX -= 190; + TaskCompletionBox.popupX -= 40; + } + if (LinkDescriptionPopup.popupY + 100 > rect.height) { + LinkDescriptionPopup.popupY -= 40; + TaskCompletionBox.popupY -= 40; + } + + setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2500); + }); + const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); Doc.GetProto(linkDoc)["anchor1-useLinkSmallAnchor"] = source.doc.useLinkSmallAnchor; Doc.GetProto(linkDoc)["anchor2-useLinkSmallAnchor"] = target.doc.useLinkSmallAnchor; @@ -1024,7 +1052,7 @@ export namespace DocUtils { Doc.GetProto(linkDoc)["acl-Public"] = linkDoc["acl-Public"] = SharingPermissions.Add; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); - + showPopup && makeLink(linkDoc, showPopup); return linkDoc; } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 4704d9e71..1a58b4bf1 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -109,6 +109,7 @@ export namespace DragManager { this.linkDragData = dragData instanceof LinkDragData ? dragData : undefined; this.columnDragData = dragData instanceof ColumnDragData ? dragData : undefined; } + linkDocument?: Doc; aborted: boolean; docDragData?: DocumentDragData; annoDragData?: PdfAnnoDragData; @@ -143,8 +144,7 @@ export namespace DragManager { droppedDocuments: Doc[] = []; linkSourceDocument: Doc; dontClearTextBox?: boolean; - linkDocument?: Doc; - linkDropCallback?: (data: { linkDocument?: Doc }) => void; + linkDropCallback?: (data: { linkDocument: Doc }) => void; } export class ColumnDragData { constructor(colKey: SchemaHeaderField) { @@ -161,7 +161,6 @@ export namespace DragManager { this.annotationDocument = annotationDoc; this.offset = [0, 0]; } - linkDocument?: Doc; targetContext: Doc | undefined; dragDocument: Doc; annotationDocument: Doc; @@ -169,7 +168,7 @@ export namespace DragManager { offset: number[]; dropAction: dropActionType; userDropAction: dropActionType; - linkDropCallback?: (data: { linkDocument?: Doc }) => void; + linkDropCallback?: (data: { linkDocument: Doc }) => void; } export function MakeDropTarget( diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index f2569edbd..912d718cf 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -70,20 +70,24 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { const docProps = testDocProps(props) ? props : undefined; const selected = property.includes(":selected"); + const isCaption = property.includes(":caption"); + const isAnchor = property.includes(":anchor"); const isBackground = () => StrListCast(doc?.layers).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); switch (property.split(":")[0]) { case StyleProp.DocContents: return undefined; + case StyleProp.LinkSource: return isAnchor && docProps?.Document; // pass the LinkSource to the LinkAnchorBox 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.HideLinkButton: return isAnchor || 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: + if (isCaption) return "white"; const backColor = backgroundCol() || "black"; const col = Color(backColor).rgb(); const colsum = (col.red() + col.green() + col.blue()); @@ -93,6 +97,8 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); if (!docProps) { @@ -144,6 +150,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { - const linkDoc = dropEv.linkDragData?.linkDocument as Doc; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop - if (this.props.View && linkDoc) { - !linkDoc.linkRelationship && (Doc.GetProto(linkDoc).linkRelationship = "hyperlink"); + if (this.props.View && dropEv.linkDocument) {// dropEv.linkDocument equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop + !dropEv.linkDocument.linkRelationship && (Doc.GetProto(dropEv.linkDocument).linkRelationship = "hyperlink"); // we want to allow specific views to handle the link creation in their own way (e.g., rich text makes text hyperlinks) // the dragged view can regiser a linkDropCallback to be notified that the link was made and to update their data structures // however, the dropped document isn't so accessible. What we do is set the newly created link document on the documentView // The documentView passes a function prop returning this link doc to its descendants who can react to changes to it. - dropEv.linkDragData?.linkDropCallback?.(dropEv.linkDragData); - runInAction(() => this.props.View.LinkBeingCreated = linkDoc); + dropEv.linkDragData?.linkDropCallback?.(dropEv as { linkDocument: Doc }); // bcz: typescript can't figure out that this is valid even though we tested dropEv.linkDocument above + runInAction(() => this.props.View.LinkBeingCreated = dropEv.linkDocument); setTimeout(action(() => this.props.View.LinkBeingCreated = undefined), 0); } linkDrag?.end(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a005a5db4..da10f2a69 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -153,6 +153,25 @@ export class DocumentViewInternal extends DocComponent): any => { this.removeMoveListeners(); this.removeEndListeners(); @@ -194,6 +213,113 @@ export class DocumentViewInternal extends DocComponent) => { + if (!e.nativeEvent.cancelBubble && !this.props.isSelected()) { + e.stopPropagation(); + e.preventDefault(); + + this.removeMoveListeners(); + this.addMoveListeners(); + this.removeEndListeners(); + this.addEndListeners(); + } + } + + handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent) => { + SelectionManager.DeselectAll(); + if (this.Document.onPointerDown) return; + const touch = me.touchEvent.changedTouches.item(0); + if (touch) { + this._downX = touch.clientX; + this._downY = touch.clientY; + if (!e.nativeEvent.cancelBubble) { + if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) e.stopPropagation(); + this.removeMoveListeners(); + this.addMoveListeners(); + this.removeEndListeners(); + this.addEndListeners(); + e.stopPropagation(); + } + } + } + + handle1PointerMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent) => { + if ((e as any).formattedHandled) { e.stopPropagation; return; } + if (e.cancelBubble && this.active) { + this.removeMoveListeners(); + } + else if (!e.cancelBubble && (this.props.isSelected(true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { + const touch = me.touchEvent.changedTouches.item(0); + if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { + if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler)) { + this.cleanUpInteractions(); + this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined); + } + } + e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers + e.preventDefault(); + } + } + + @action + handle2PointersMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent) => { + const myTouches = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true); + const pt1 = myTouches[0]; + const pt2 = myTouches[1]; + const oldPoint1 = this.prevPoints.get(pt1.identifier); + const oldPoint2 = this.prevPoints.get(pt2.identifier); + const pinching = InteractionUtils.Pinning(pt1, pt2, oldPoint1!, oldPoint2!); + if (pinching !== 0 && oldPoint1 && oldPoint2) { + const dW = (Math.abs(pt1.clientX - pt2.clientX) - Math.abs(oldPoint1.clientX - oldPoint2.clientX)); + const dH = (Math.abs(pt1.clientY - pt2.clientY) - Math.abs(oldPoint1.clientY - oldPoint2.clientY)); + const dX = -1 * Math.sign(dW); + const dY = -1 * Math.sign(dH); + + if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { + const doc = Document(this.props.Document); + const layoutDoc = Document(Doc.Layout(this.props.Document)); + let nwidth = Doc.NativeWidth(layoutDoc); + let nheight = Doc.NativeHeight(layoutDoc); + const width = (layoutDoc._width || 0); + const height = (layoutDoc._height || (nheight / nwidth * width)); + const scale = this.props.ScreenToLocalTransform().Scale * this.ContentScale; + const actualdW = Math.max(width + (dW * scale), 20); + const actualdH = Math.max(height + (dH * scale), 20); + doc.x = (doc.x || 0) + dX * (actualdW - width); + doc.y = (doc.y || 0) + dY * (actualdH - height); + const fixedAspect = e.ctrlKey || (nwidth && nheight); + if (fixedAspect && (!nwidth || !nheight)) { + Doc.SetNativeWidth(layoutDoc, nwidth = layoutDoc._width || 0); + Doc.SetNativeHeight(layoutDoc, nheight = layoutDoc._height || 0); + } + if (nwidth > 0 && nheight > 0) { + if (Math.abs(dW) > Math.abs(dH)) { + if (!fixedAspect) { + Doc.SetNativeWidth(layoutDoc, actualdW / (layoutDoc._width || 1) * Doc.NativeWidth(layoutDoc)); + } + layoutDoc._width = actualdW; + if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._height = nheight / nwidth * layoutDoc._width; + else layoutDoc._height = actualdH; + } + else { + if (!fixedAspect) { + Doc.SetNativeHeight(layoutDoc, actualdH / (layoutDoc._height || 1) * Doc.NativeHeight(doc)); + } + layoutDoc._height = actualdH; + if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._width = nwidth / nheight * layoutDoc._height; + else layoutDoc._width = actualdW; + } + } else { + dW && (layoutDoc._width = actualdW); + dH && (layoutDoc._height = actualdH); + dH && layoutDoc._autoHeight && (layoutDoc._autoHeight = false); + } + } + e.stopPropagation(); + e.preventDefault(); + } + } + @action onRadialMenu = (e: Event, me: InteractionUtils.MultiTouchEvent): void => { const pt = me.touchEvent.touches[me.touchEvent.touches.length - 1]; @@ -209,43 +335,15 @@ export class DocumentViewInternal extends DocComponent) => { - SelectionManager.DeselectAll(); - if (this.Document.onPointerDown) return; - const touch = me.touchEvent.changedTouches.item(0); - if (touch) { - this._downX = touch.clientX; - this._downY = touch.clientY; - if (!e.nativeEvent.cancelBubble) { - if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) e.stopPropagation(); - this.removeMoveListeners(); - this.addMoveListeners(); - this.removeEndListeners(); - this.addEndListeners(); - e.stopPropagation(); - } - } - } - - handle1PointerMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent) => { - if ((e as any).formattedHandled) { e.stopPropagation; return; } - if (e.cancelBubble && this.active) { - this.removeMoveListeners(); - } - else if (!e.cancelBubble && (this.props.isSelected(true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { - - const touch = me.touchEvent.changedTouches.item(0); - if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { - if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler)) { - this.cleanUpInteractions(); - this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined); - } - } - e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers - e.preventDefault(); - } - } - - handle2PointersDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent) => { - if (!e.nativeEvent.cancelBubble && !this.props.isSelected()) { - e.stopPropagation(); - e.preventDefault(); - - this.removeMoveListeners(); - this.addMoveListeners(); - this.removeEndListeners(); - this.addEndListeners(); - } - } - - - @action - handle2PointersMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent) => { - const myTouches = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true); - const pt1 = myTouches[0]; - const pt2 = myTouches[1]; - const oldPoint1 = this.prevPoints.get(pt1.identifier); - const oldPoint2 = this.prevPoints.get(pt2.identifier); - const pinching = InteractionUtils.Pinning(pt1, pt2, oldPoint1!, oldPoint2!); - if (pinching !== 0 && oldPoint1 && oldPoint2) { - const dW = (Math.abs(pt1.clientX - pt2.clientX) - Math.abs(oldPoint1.clientX - oldPoint2.clientX)); - const dH = (Math.abs(pt1.clientY - pt2.clientY) - Math.abs(oldPoint1.clientY - oldPoint2.clientY)); - const dX = -1 * Math.sign(dW); - const dY = -1 * Math.sign(dH); - - if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { - const doc = Document(this.props.Document); - const layoutDoc = Document(Doc.Layout(this.props.Document)); - let nwidth = Doc.NativeWidth(layoutDoc); - let nheight = Doc.NativeHeight(layoutDoc); - const width = (layoutDoc._width || 0); - const height = (layoutDoc._height || (nheight / nwidth * width)); - const scale = this.props.ScreenToLocalTransform().Scale * this.ContentScale; - const actualdW = Math.max(width + (dW * scale), 20); - const actualdH = Math.max(height + (dH * scale), 20); - doc.x = (doc.x || 0) + dX * (actualdW - width); - doc.y = (doc.y || 0) + dY * (actualdH - height); - const fixedAspect = e.ctrlKey || (nwidth && nheight); - if (fixedAspect && (!nwidth || !nheight)) { - Doc.SetNativeWidth(layoutDoc, nwidth = layoutDoc._width || 0); - Doc.SetNativeHeight(layoutDoc, nheight = layoutDoc._height || 0); - } - if (nwidth > 0 && nheight > 0) { - if (Math.abs(dW) > Math.abs(dH)) { - if (!fixedAspect) { - Doc.SetNativeWidth(layoutDoc, actualdW / (layoutDoc._width || 1) * Doc.NativeWidth(layoutDoc)); - } - layoutDoc._width = actualdW; - if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._height = nheight / nwidth * layoutDoc._width; - else layoutDoc._height = actualdH; - } - else { - if (!fixedAspect) { - Doc.SetNativeHeight(layoutDoc, actualdH / (layoutDoc._height || 1) * Doc.NativeHeight(doc)); - } - layoutDoc._height = actualdH; - if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._width = nwidth / nheight * layoutDoc._height; - else layoutDoc._width = actualdW; - } - } else { - dW && (layoutDoc._width = actualdW); - dH && (layoutDoc._height = actualdH); - dH && layoutDoc._autoHeight && (layoutDoc._autoHeight = false); - } - } - e.stopPropagation(); - e.preventDefault(); - } - } + }) onPointerDown = (e: React.PointerEvent): void => { // continue if the event hasn't been canceled AND we are using a moues or this is has an onClick or onDragStart function (meaning it is a button document) @@ -526,11 +515,6 @@ export class DocumentViewInternal extends DocComponent { - this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined; - } - @undoBatch @action toggleFollowLink = (location: Opt, zoom: boolean, setPushpin: boolean): void => { this.Document.ignoreClick = false; @@ -564,7 +548,6 @@ export class DocumentViewInternal extends DocComponent { this.Document.ignoreClick = false; @@ -585,45 +568,10 @@ export class DocumentViewInternal extends DocComponent { - LinkManager.currentLink = linkDoc; - - TaskCompletionBox.textDisplayed = "Link Created"; - TaskCompletionBox.popupX = de.x; - TaskCompletionBox.popupY = de.y - 33; - TaskCompletionBox.taskCompleted = true; - - LinkDescriptionPopup.popupX = de.x; - LinkDescriptionPopup.popupY = de.y; - LinkDescriptionPopup.descriptionPopup = true; - - const rect = document.body.getBoundingClientRect(); - if (LinkDescriptionPopup.popupX + 200 > rect.width) { - LinkDescriptionPopup.popupX -= 190; - TaskCompletionBox.popupX -= 40; - } - if (LinkDescriptionPopup.popupY + 100 > rect.height) { - LinkDescriptionPopup.popupY -= 40; - TaskCompletionBox.popupY -= 40; - } - - setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2500); - }); - if (de.complete.annoDragData) { - /// this whole section for handling PDF annotations looks weird. Need to rethink this to make it cleaner - e.stopPropagation(); - de.complete.annoDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link"); - de.complete.annoDragData.linkDocument && makeLink(de.complete.annoDragData.linkDocument); - } - if (de.complete.linkDragData) { + const linkSource = de.complete.annoDragData ? de.complete.annoDragData.annotationDocument : de.complete.linkDragData ? de.complete.linkDragData.linkSourceDocument : undefined; + if (linkSource && linkSource !== this.props.Document) { e.stopPropagation(); - const linkSource = de.complete.linkDragData.linkSourceDocument; - if (linkSource !== this.props.Document) { - const linkDoc = DocUtils.MakeLink({ doc: linkSource }, { doc: this.props.Document }, `link`); - linkSource !== this.props.Document && (de.complete.linkDragData.linkDocument = linkDoc); // TODODO this is where in text links get passed - linkDoc && makeLink(linkDoc); - } - + de.complete.linkDocument = DocUtils.MakeLink({ doc: linkSource }, { doc: this.props.Document }, "link", undefined, undefined, undefined, [de.x, de.y]); } } @@ -707,7 +655,7 @@ export class DocumentViewInternal extends DocComponent SelectionManager.SelectedDocuments().forEach(dv => dv.props.bringToFront(dv.rootDoc, false)), icon: "expand-arrows-alt" }); zorderItems.push({ description: "Send to Back", event: () => SelectionManager.SelectedDocuments().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" }); - zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: this.toggleRaiseWhenDragged, icon: "expand-arrows-alt" }); + zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: undoBatch(action(() => this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined)), icon: "expand-arrows-alt" }); !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" }); onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); @@ -784,17 +732,13 @@ export class DocumentViewInternal extends DocComponent { - return this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; - } - + rootSelected = (outsideReaction?: boolean) => { return this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; } panelHeight = () => this.props.PanelHeight() - this.headerMargin; parentActive = (outsideReaction: boolean) => this.props.layerProvider?.(this.layoutDoc) === false ? this.props.parentActive(outsideReaction) : false; screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin); contentScaling = () => this.ContentScale; onClickFunc = () => this.onClickHandler; - onDoubleClickFunc = () => this.onDoubleClickHandler; - + makeLink = () => this.props.DocumentView._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. @observable contentsActive: () => boolean = returnFalse; @action setContentsActive = (setActive: () => boolean) => this.contentsActive = setActive; @@ -805,41 +749,14 @@ export class DocumentViewInternal extends DocComponent - {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} @@ -859,26 +776,11 @@ export class DocumentViewInternal extends DocComponent this.props.DocumentView._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, doc) => flg && (doc.hidden = true), true) anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; - anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { - if (testDocProps(props)) { - switch (property.split(":")[0]) { - case StyleProp.BackgroundColor: return "transparent"; // background of linkanchor documentView is transparent since it covers the whole document - case StyleProp.HideLinkButton: return true; // don't want linkAnchor documentview to show its own link button - case StyleProp.PointerEvents: return "none"; // don't want linkAnchor documentView to handle events (since it covers the whole document). However, the linkAnchorBox itself is set to pointerEvent all - } - } else { - switch (property.split(":")[0]) { - case StyleProp.LinkSource: return this.props.Document; // pass the LinkSource to the LinkAnchorBox - } - } - return this.props.styleProvider?.(doc, props, property); - } + anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => this.props.styleProvider?.(doc, props, property + ":anchor"); @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } @@ -904,11 +806,7 @@ export class DocumentViewInternal extends DocComponent
    ); } - captionStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { - if (property === StyleProp.Color) return "white"; - if (property === StyleProp.BackgroundColor) return "rgba(0,0,0 ,0.4)"; - return this.props?.styleProvider?.(doc, props, property); - } + captionStyleProvider = (doc: Opt, props: Opt, property: string) => this.props?.styleProvider?.(doc, props, property + ":caption"); @computed get innards() { TraceMobx(); const showTitle = this.ShowTitle; @@ -938,9 +836,7 @@ export class DocumentViewInternal extends DocComponent Field.toString((this.dataDoc || this.props.Document)[showTitle.split(";")[0]] as any as Field)} - SetValue={undoBatch((value: string) => { - showTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[showTitle] = value) ? true : true; - })} + SetValue={undoBatch((value) => showTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[showTitle] = value) ? true : true)} />
    ); return this.props.hideTitle || (!showTitle && !showCaption) ? @@ -988,7 +884,7 @@ export class DocumentViewInternal extends DocComponent !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))} onPointerLeave={action(e => { let entered = false; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 125bf62f0..8e824a447 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -546,8 +546,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { - if (!e.aborted && e.annoDragData && !e.annoDragData.linkDocument) { - e.annoDragData.linkDocument = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation"); + if (!e.aborted && e.annoDragData && !e.linkDocument) { + e.linkDocument = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation"); annotationDoc.isLinkButton = true; annotationDoc.isPushpin = e.annoDragData?.dropDocument.annotationOn === this.props.Document; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f82e533ad..0bb483b41 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -478,11 +478,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp de.complete.annoDragData.linkDropCallback = this.linkDrop; } } - linkDrop = (data: { linkDocument?: Doc }) => { - const linkDoc = data.linkDocument!; - const anchor1Title = linkDoc.anchor1 instanceof Doc ? StrCast(linkDoc.anchor1.title) : "-untitled-"; - const anchor1Id = linkDoc.anchor1 instanceof Doc ? linkDoc.anchor1[Id] : ""; - this.makeLinkToSelection(linkDoc[Id], anchor1Title, "add:right", anchor1Id); + linkDrop = (data: { linkDocument: Doc }) => { + const anchor1Title = data.linkDocument.anchor1 instanceof Doc ? StrCast(data.linkDocument.anchor1.title) : "-untitled-"; + const anchor1Id = data.linkDocument.anchor1 instanceof Doc ? data.linkDocument.anchor1[Id] : ""; + this.makeLinkToSelection(data.linkDocument[Id], anchor1Title, "add:right", anchor1Id); } getNodeEndpoints(context: Node, node: Node): { from: number, to: number } | null { diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index be64754af..d6d500702 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -633,12 +633,12 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - if (!e.aborted && e.annoDragData && !e.annoDragData.linkDocument) { - e.annoDragData.linkDocument = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation"); + if (!e.aborted && e.annoDragData && !e.linkDocument) { + e.linkDocument = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation"); } annotationDoc.isLinkButton = true; // prevents link button fro showing up --- maybe not a good thing? annotationDoc.isPushpin = e.annoDragData?.dropDocument.annotationOn === this.props.Document; - e.annoDragData && e.annoDragData.linkDocument && e.annoDragData?.linkDropCallback?.({ linkDocument: e.annoDragData.linkDocument }); + e.linkDocument && e.annoDragData?.linkDropCallback?.(e as { linkDocument: Doc });// bcz: typescript can't figure out that this is valid even though we tested e.linkDocument above } }); } -- cgit v1.2.3-70-g09d2 From 64b71d1f652bb3a7523ed3914d93f4603ae9fe98 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 15 Dec 2020 13:29:15 -0500 Subject: fixed previous problems -- weird that you can't call componentWillUnmount. also fixed dragging to show original unless hideSource is set --- src/client/util/DragManager.ts | 3 +-- src/client/views/nodes/DocumentView.tsx | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 1a58b4bf1..bebdc8bb2 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -412,13 +412,12 @@ export namespace DragManager { return dragElement; }); - const hideSource = options?.hideSource ? true : false; const hideDragShowOriginalElements = (hide: boolean) => { dragLabel.style.display = hide ? "" : "none"; !hide && dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); eles.forEach(ele => ele.hidden = hide); }; - hideDragShowOriginalElements(hideSource); + options?.hideSource && hideDragShowOriginalElements(true); SnappingManager.SetIsDragging(true); let lastX = downX; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index da10f2a69..eb1807a71 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -153,9 +153,10 @@ export class DocumentViewInternal extends DocComponent { // continue if the event hasn't been canceled AND we are using a moues or this is has an onClick or onDragStart function (meaning it is a button document) @@ -732,7 +733,7 @@ export class DocumentViewInternal extends DocComponent { return this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; } + rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; panelHeight = () => this.props.PanelHeight() - this.headerMargin; parentActive = (outsideReaction: boolean) => this.props.layerProvider?.(this.layoutDoc) === false ? this.props.parentActive(outsideReaction) : false; screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin); -- cgit v1.2.3-70-g09d2 From a6de26815ba43ae8cbc93cce91f34aecf6542b61 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 15 Dec 2020 19:41:24 -0500 Subject: added real grouping --- src/client/util/DragManager.ts | 8 +++- src/client/views/StyleProvider.tsx | 29 ++++++------- src/client/views/collections/CollectionView.tsx | 6 +-- .../collectionFreeForm/CollectionFreeFormView.tsx | 48 +++++++++++++++++++--- .../collections/collectionFreeForm/MarqueeView.tsx | 25 +++++++---- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 + src/client/views/nodes/DocumentView.tsx | 5 ++- 7 files changed, 90 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index bebdc8bb2..d24348746 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -213,7 +213,7 @@ export namespace DragManager { }; const finishDrag = (e: DragCompleteEvent) => { const docDragData = e.docDragData; - if (dropEvent) dropEvent(); // glr: optional additional function to be called - in this case with presentation trails + dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails if (docDragData && !docDragData.droppedDocuments.length) { docDragData.dropAction = dragData.userDropAction || dragData.dropAction; docDragData.droppedDocuments = @@ -344,6 +344,9 @@ export namespace DragManager { dragDiv.appendChild(dragLabel); DragManager.Root().appendChild(dragDiv); } + dragDiv.style.width = ""; + dragDiv.style.height = ""; + dragDiv.style.overflow = ""; dragDiv.hidden = false; const scaleXs: number[] = []; const scaleYs: number[] = []; @@ -544,6 +547,9 @@ export namespace DragManager { return ret; }); dragDiv.hidden = true; + dragDiv.style.width = "0"; + dragDiv.style.height = "0"; + dragDiv.style.overflow = "hidden"; const target = document.elementFromPoint(e.x, e.y); removed.map(r => { r.ele.style.width = r.w; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 912d718cf..3389095b8 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -91,7 +91,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 600 || col.alpha() < 0.25) return "black"; + if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black"; return "white"; case StyleProp.Hidden: return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); case StyleProp.BorderRounding: return StrCast(doc?._borderRounding, StrCast(doc?.borderRounding)); @@ -119,13 +119,14 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 0 ? - Doc.UserDoc().activeCollectionNestedBackground : - Doc.UserDoc().activeCollectionBackground)); + docColor = docColor ? docColor : + doc?._isGroup ? "#00000004" : + (Doc.IsSystem(doc) ? (darkScheme() ? "rgb(62,62,62)" : "lightgrey") : + isBackground() ? "cyan" : + doc.annotationOn ? "#00000015" : + StrCast((props?.renderDepth || 0) > 0 ? + Doc.UserDoc().activeCollectionNestedBackground : + Doc.UserDoc().activeCollectionBackground)); break; //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)"; default: docColor = darkScheme() ? "black" : "white"; break; @@ -135,18 +136,18 @@ export function DefaultStyleProvider(doc: Opt, props: Opt props?.ContainingCollectionDoc?._useClusters || NumCast(doc.group, -1) !== -1; if (doc?.isLinkButton && doc.type !== DocumentType.LINK) return StrCast(doc?._linkButtonShadow, "lightblue 0em 0em 1em"); switch (doc?.type) { - case DocumentType.COL: return isBackground() ? undefined : - `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; + case DocumentType.COL: return StrCast(doc?.boxShadow, isBackground() || (doc?._isGroup && !SnappingManager.GetIsDragging()) ? undefined : + `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`); default: return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow - backgroundHalo(doc) && doc.type !== DocumentType.INK ? (`${backgroundCol()} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent - isBackground() ? undefined : // if it's a background & has a cluster color, make the shadow spread really big - StrCast(doc.boxShadow, ""); + props?.ContainingCollectionDoc?._useClusters && doc.type !== DocumentType.INK ? (`${backgroundCol()} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + NumCast(doc.group, -1) !== -1 && doc.type !== DocumentType.INK ? (`gray ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + isBackground() ? undefined : // if it's a background & has a cluster color, make the shadow spread really big + StrCast(doc.boxShadow, ""); } } case StyleProp.PointerEvents: diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 04edc3d09..8c0cdba07 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -40,6 +40,7 @@ import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; import { ScriptField } from '../../../fields/ScriptField'; import { StyleProp } from '../StyleProvider'; +import { SnappingManager } from '../../util/SnappingManager'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); @@ -108,6 +109,7 @@ export class CollectionView extends Touchable { active = (outsideReaction?: boolean) => (this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || this.props.Document.forceActive || + this.props.Document._isGroup || this._isChildActive || this.props.renderDepth === 0) ? true : @@ -385,10 +387,8 @@ export class CollectionView extends Touchable { ScreenToLocalTransform: this.screenToLocalTransform, CollectionView: this, }; - const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.treeViewOutlineMode || this.collectionViewType === CollectionViewType.Linear ? undefined : - this.props.styleProvider?.(this.props.Document, this.props, StyleProp.BoxShadow); return (
    + style={{ pointerEvents: (this.props.Document._isGroup && !SnappingManager.GetIsDragging()) ? "all" : this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined }}> {this.showIsTagged()} {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)} {this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => Cast(d.data, ImageField, null)).map(d => diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d17e87db4..9cc459495 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,4 +1,4 @@ -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; import { Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from "../../../../fields/Doc"; @@ -31,9 +31,9 @@ import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss" import { Timeline } from "../../animationtimeline/Timeline"; import { ContextMenu } from "../../ContextMenu"; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkingStroke"; -import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; +import { CollectionFreeFormDocumentView, CollectionFreeFormDocumentViewProps } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentLinksButton } from "../../nodes/DocumentLinksButton"; -import { DocumentViewProps, DocAfterFocusFunc } from "../../nodes/DocumentView"; +import { DocumentViewProps, DocAfterFocusFunc, DocumentView } from "../../nodes/DocumentView"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { pageSchema } from "../../nodes/ImageBox"; import { PresBox } from "../../nodes/PresBox"; @@ -220,8 +220,28 @@ export class CollectionFreeFormView extends CollectionSubView super.onExternalDrop(e, { x: pt[0], y: pt[1] }))(this.getTransform().transformPoint(e.pageX, e.pageY)); } + updateGroupBounds = () => { + if (!this.props.Document._isGroup) return; + const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() })); + const cbounds = aggregateBounds(clist, 0, 0); + const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[HeightSym]() / 2]; + const p = [NumCast(this.layoutDoc._panX), NumCast(this.layoutDoc._panY)]; + const pbounds = { + x: (cbounds.x - p[0]) * this.zoomScaling() + c[0], y: (cbounds.y - p[1]) * this.zoomScaling() + c[1], + r: (cbounds.r - p[0]) * this.zoomScaling() + c[0], b: (cbounds.b - p[1]) * this.zoomScaling() + c[1] + }; + + this.layoutDoc._width = (pbounds.r - pbounds.x); + this.layoutDoc._height = (pbounds.b - pbounds.y); + this.layoutDoc._panX = (cbounds.r + cbounds.x) / 2; + this.layoutDoc._panY = (cbounds.b + cbounds.y) / 2; + this.layoutDoc.x = pbounds.x; + this.layoutDoc.y = pbounds.y; + } + @action internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData, xp: number, yp: number) { + if (!this.ChildDrag && this.props.Document._isGroup) return false; if (!super.onInternalDrop(e, de)) return false; const refDoc = docDragData.droppedDocuments[0]; const [xpo, ypo] = this.getTransformOverlay().transformPoint(de.x, de.y); @@ -252,6 +272,8 @@ export class CollectionFreeFormView extends CollectionSubView !StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); set && set.filter(s => StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); } - } else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; + } //else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; return styleProp; } @@ -654,6 +676,7 @@ export class CollectionFreeFormView extends CollectionSubView this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false; @@ -1165,6 +1189,7 @@ export class CollectionFreeFormView extends CollectionSubView this._showAnimTimeline = !this._showAnimTimeline), icon: "eye" }); this.props.ContainingCollectionView && - optionItems.push({ description: "Move Items Out of Collection", event: this.promoteCollection, icon: "table" }); + optionItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" }); optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" }); this.props.renderDepth && optionItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" }); if (!Doc.UserDoc().noviceMode) { @@ -1468,6 +1494,7 @@ export class CollectionFreeFormView extends CollectionSubView 0 ? undefined : this.nudge} addDocTab={this.addDocTab} trySelectCluster={this.trySelectCluster} @@ -1547,6 +1574,17 @@ export class CollectionFreeFormView extends CollectionSubView )}
    } + + {this.ChildDrag && this.props.Document._isGroup ? +
    : (null)}
    ; } } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index f1f190bff..0ab20fea2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -38,6 +38,7 @@ interface MarqueeViewProps { isSelected: () => boolean; trySelectCluster: (addToSel: boolean) => boolean; nudge?: (x: number, y: number) => boolean; + ungroup?: () => void; setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; } @observer @@ -93,7 +94,11 @@ export class MarqueeView extends React.Component, options: DocumentOptions, id?: string) => Doc>, layers: string[]) => { - const newCollection = creator ? creator(selected, { title: "nested stack", }) : ((doc: Doc) => { + getCollection = action((selected: Doc[], creator: Opt<(documents: Array, options: DocumentOptions, id?: string) => Doc>, layers: string[], makeGroup: Opt) => { + const newCollection = creator ? creator(selected, { title: makeGroup ? "grouping" : "nested stack", }) : ((doc: Doc) => { Doc.GetProto(doc).data = new List(selected); Doc.GetProto(doc).title = "nested freeform"; doc._panX = doc._panY = 0; @@ -352,6 +357,7 @@ export class MarqueeView extends React.Component(layers); newCollection._width = this.Bounds.width; newCollection._height = this.Bounds.height; + newCollection._isGroup = makeGroup; newCollection.x = this.Bounds.left; newCollection.y = this.Bounds.top; selected.forEach(d => d.context = newCollection); @@ -410,9 +416,9 @@ export class MarqueeView extends React.Component { + collection = (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => { const selected = this.marqueeSelect(false); - if (e instanceof KeyboardEvent ? e.key === "c" : true) { + if (e instanceof KeyboardEvent ? "cg".includes(e.key) : true) { selected.map(action(d => { const dx = NumCast(d.x); const dy = NumCast(d.y); @@ -426,7 +432,7 @@ export class MarqueeView extends React.Component { - const newCollection = this.getCollection([], undefined, [StyleLayers.Background]); + const newCollection = this.getCollection([], undefined, [StyleLayers.Background], undefined); this.props.addDocument?.(newCollection); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); @@ -542,11 +548,12 @@ export class MarqueeView extends React.Component e.preventDefault()} onScroll={(e) => e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0} onClick={this.onClick} onPointerDown={this.onPointerDown}> {this._visible ? this.marqueeDiv : null} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a06dd530b..a9bcf17e2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -16,6 +16,7 @@ import "./CollectionFreeFormDocumentView.scss"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import { FieldViewProps } from "./FieldView"; import React = require("react"); +import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; @@ -26,6 +27,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { jitterRotation: number; dataTransition?: string; replica: string; + CollectionFreeFormView: CollectionFreeFormView; } @observer diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index eb1807a71..5909fceb5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -338,6 +338,8 @@ export class DocumentViewInternal extends DocComponent (ffview().props.CollectionFreeFormView.ChildDrag = this.props.DocumentView)); const dragData = new DragManager.DocumentDragData([this.props.Document]); const [left, top] = this.props.ScreenToLocalTransform().scale(this.ContentScale).inverse().transformPoint(0, 0); dragData.offset = this.props.ScreenToLocalTransform().scale(this.ContentScale).transformDirection(x - left, y - top); @@ -345,7 +347,8 @@ export class DocumentViewInternal extends DocComponent setTimeout(action(() => ffview && (ffview().props.CollectionFreeFormView.ChildDrag = undefined)))); // this needs to happen after the drop event is processed. } } onKeyDown = (e: React.KeyboardEvent) => { -- cgit v1.2.3-70-g09d2 From d222ccf613fa7dc1edabc325d226fed4f88d2db0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 15 Dec 2020 21:22:39 -0500 Subject: fixed some events with groups - they remain active when in "background" --- src/client/views/StyleProvider.tsx | 19 ++++++++++--------- src/client/views/collections/CollectionView.tsx | 5 ++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 16 ++++++++-------- .../collections/collectionFreeForm/MarqueeView.tsx | 6 +++--- src/client/views/nodes/DocumentView.tsx | 5 +++-- 5 files changed, 26 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 3389095b8..134f4cf0b 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -43,13 +43,12 @@ function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkSc function toggleBackground(doc: Doc) { UndoManager.RunInBatch(() => runInAction(() => { - const layers = StrListCast(doc.layers); + let layers = StrListCast(doc.layers); if (!layers.includes(StyleLayers.Background)) { - if (!layers.length) doc.layers = new List([StyleLayers.Background]); + if (!layers.length) doc.layers = layers = new List([StyleLayers.Background]); else layers.push(StyleLayers.Background); } else layers.splice(layers.indexOf(StyleLayers.Background), 1); - doc._overflow = !layers.includes(StyleLayers.Background) ? "visible" : undefined; if (!layers.includes(StyleLayers.Background)) { //this.props.bringToFront(doc, true); // const wid = this.Document[WidthSym](); // change the nativewidth and height if the background is to be a collection that aggregates stuff that is added to it. @@ -120,10 +119,10 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground)); @@ -140,8 +139,10 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { active = (outsideReaction?: boolean) => (this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || - this.props.Document.forceActive || - this.props.Document._isGroup || + (this.props.layerProvider?.(this.props.Document) !== false && (this.props.Document.forceActive || this.props.Document._isGroup)) || this._isChildActive || this.props.renderDepth === 0) ? true : @@ -388,7 +387,7 @@ export class CollectionView extends Touchable { CollectionView: this, }; return (
    + style={{ pointerEvents: this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined }}> {this.showIsTagged()} {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)} {this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => Cast(d.data, ImageField, null)).map(d => diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9cc459495..58e2863e5 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -241,7 +241,7 @@ export class CollectionFreeFormView extends CollectionSubView { - (DocumentDecorations.Instance.Interacting || SnappingManager.GetIsDragging()) && this.setupDragLines(e.ctrlKey || e.shiftKey); + (DocumentDecorations.Instance.Interacting || (this.props.layerProvider?.(this.props.Document) === false && SnappingManager.GetIsDragging())) && this.setupDragLines(e.ctrlKey || e.shiftKey); e.stopPropagation(); } @@ -1575,12 +1575,12 @@ export class CollectionFreeFormView extends CollectionSubView
    } - {this.ChildDrag && this.props.Document._isGroup ? + {(this.ChildDrag || this.props.layerProvider?.(this.props.Document) === false) && SnappingManager.GetIsDragging() && this.props.Document._isGroup ?
    , options: DocumentOptions, id?: string) => Doc>, layers: string[], makeGroup: Opt) => { - const newCollection = creator ? creator(selected, { title: makeGroup ? "grouping" : "nested stack", }) : ((doc: Doc) => { + const newCollection = creator ? creator(selected, { title: "nested stack", }) : ((doc: Doc) => { Doc.GetProto(doc).data = new List(selected); - Doc.GetProto(doc).title = "nested freeform"; + Doc.GetProto(doc).title = makeGroup ? "grouping" : "nested freeform"; doc._panX = doc._panY = 0; return doc; })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); @@ -641,7 +641,7 @@ export class MarqueeView extends React.Component e.preventDefault()} onScroll={(e) => e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0} onClick={this.onClick} onPointerDown={this.onPointerDown}> {this._visible ? this.marqueeDiv : null} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5909fceb5..3c140a22a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -154,8 +154,9 @@ export class DocumentViewInternal extends DocComponent Date: Tue, 15 Dec 2020 21:48:43 -0500 Subject: from last --- src/client/views/StyleProvider.tsx | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 134f4cf0b..d6571276a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -4,19 +4,20 @@ import 'golden-layout/src/css/goldenlayout-dark-theme.css'; import { runInAction } from 'mobx'; import { Doc, Opt, StrListCast } from "../../fields/Doc"; import { List } from '../../fields/List'; -import { BoolCast, Cast, StrCast, NumCast } from "../../fields/Types"; +import { listSpec } from '../../fields/Schema'; +import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; +import { returnFalse } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { SnappingManager } from '../util/SnappingManager'; import { UndoManager } from '../util/UndoManager'; import { CollectionViewType } from './collections/CollectionView'; +import { MainView } from './MainView'; import { DocumentViewProps } from "./nodes/DocumentView"; +import { FieldViewProps } from './nodes/FieldView'; import "./StyleProvider.scss"; import React = require("react"); import Color = require('color'); -import { listSpec } from '../../fields/Schema'; -import { MainView } from './MainView'; -import { FieldViewProps } from './nodes/FieldView'; export enum StyleLayers { Background = "background" @@ -43,19 +44,12 @@ function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkSc function toggleBackground(doc: Doc) { UndoManager.RunInBatch(() => runInAction(() => { - let layers = StrListCast(doc.layers); + const layers = StrListCast(doc.layers); if (!layers.includes(StyleLayers.Background)) { - if (!layers.length) doc.layers = layers = new List([StyleLayers.Background]); + if (!layers.length) doc.layers = new List([StyleLayers.Background]); else layers.push(StyleLayers.Background); } else layers.splice(layers.indexOf(StyleLayers.Background), 1); - if (!layers.includes(StyleLayers.Background)) { - //this.props.bringToFront(doc, true); - // const wid = this.Document[WidthSym](); // change the nativewidth and height if the background is to be a collection that aggregates stuff that is added to it. - // const hgt = this.Document[HeightSym](); - // Doc.SetNativeWidth(this.props.Document[DataSym], wid); - // Doc.SetNativeHeight(this.props.Document[DataSym], hgt); - } }), "toggleBackground"); } @@ -190,7 +184,7 @@ export function DefaultLayerProvider(thisDoc: Doc) { return true; } else { if (Doc.AreProtosEqual(doc, thisDoc)) return true; - const layers = Cast(doc.layers, listSpec("string"), []); + const layers = StrListCast(doc.layers); if (!layers.length && !thisDoc?.activeLayer) return true; if (layers.includes(StrCast(thisDoc?.activeLayer))) return true; return false; -- cgit v1.2.3-70-g09d2 From ada340bb7b6e86814db431e70f1e892162302814 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 15 Dec 2020 22:18:08 -0500 Subject: from last --- src/client/views/collections/CollectionView.tsx | 4 ++-- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 90806857f..bea5ac2ed 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -147,7 +147,7 @@ export class CollectionView extends Touchable { if (effectiveAcl === AclAddonly) { added.map(doc => { - this.props.layerProvider?.(doc, true); + this.props.layerProvider?.(doc, true);// assigns layer values to the newly added document... testing the utility of this Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc); doc.context = this.props.Document; }); @@ -172,7 +172,7 @@ export class CollectionView extends Touchable { doc._stayInCollection = undefined; doc.context = this.props.Document; }); - added.map(doc => this.props.layerProvider?.(doc, true)); + added.map(doc => this.props.layerProvider?.(doc, true));// assigns layer values to the newly added document... testing the utility of this (targetDataDoc[this.props.fieldKey] as List).push(...added); targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 58e2863e5..4ac4f4079 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1575,7 +1575,7 @@ export class CollectionFreeFormView extends CollectionSubView
    } - {(this.ChildDrag || this.props.layerProvider?.(this.props.Document) === false) && SnappingManager.GetIsDragging() && this.props.Document._isGroup ? + {this.props.Document._isGroup && SnappingManager.GetIsDragging() && (this.ChildDrag || this.props.layerProvider?.(this.props.Document) === false) ?
    Date: Wed, 16 Dec 2020 00:28:16 -0500 Subject: fixed exxception on deactivating background lock. --- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a9bcf17e2..727b25d1b 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -51,7 +51,6 @@ export class CollectionFreeFormDocumentView extends DocComponent, property: string) => { if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children @@ -155,7 +154,7 @@ export class CollectionFreeFormDocumentView extends DocComponent {Doc.UserDoc().renderStyle !== "comic" ? (null) : -- cgit v1.2.3-70-g09d2 From 3fd3a5d8a130b32cd60c30904c3ce1d5d86de825 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 00:34:39 -0500 Subject: from last --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4ac4f4079..1add65c10 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1318,6 +1318,8 @@ export class CollectionFreeFormView extends CollectionSubView { 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" }); + this.props.ContainingCollectionView && + appearanceItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" }); !Doc.UserDoc().noviceMode ? appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }) : null; !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); @@ -1332,8 +1334,6 @@ export class CollectionFreeFormView extends CollectionSubView this._showAnimTimeline = !this._showAnimTimeline), icon: "eye" }); - this.props.ContainingCollectionView && - optionItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" }); optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" }); this.props.renderDepth && optionItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" }); if (!Doc.UserDoc().noviceMode) { -- cgit v1.2.3-70-g09d2 From f54dd2851a1dd99157a4047d7d17d0c40178d30e Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 10:13:57 -0500 Subject: partial tree view fix. --- src/client/views/collections/TreeView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index e289f24a9..31a1a2b99 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -503,7 +503,7 @@ export class TreeView extends React.Component { switch (property.split(":")[0]) { case StyleProp.Opacity: return this.outlineMode ? undefined : 1; case StyleProp.BackgroundColor: return StrCast(doc._backgroundColor, StrCast(doc.backgroundColor)); - case StyleProp.DocContents: return testDocProps(props) && props?.treeViewDoc ? (null) : + case StyleProp.DocContents: return testDocProps(props) && !props?.treeViewDoc ? (null) :
    Date: Wed, 16 Dec 2020 12:02:52 -0500 Subject: fixed treeView layouts to pass good values for panelWidth/height to DocumentView. renamed Selectionmanager methods to be views not documents. --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/DictationManager.ts | 2 +- src/client/util/DocumentManager.ts | 4 +- src/client/util/HypothesisUtils.ts | 2 +- src/client/util/SelectionManager.ts | 52 ++++++++--------- src/client/util/SharingManager.tsx | 12 ++-- src/client/views/DocumentButtonBar.tsx | 4 +- src/client/views/DocumentDecorations.tsx | 68 +++++++++++----------- src/client/views/GlobalKeyHandler.ts | 42 ++++++------- src/client/views/InkStrokeProperties.ts | 6 +- src/client/views/PropertiesButtons.tsx | 22 +++---- src/client/views/PropertiesView.tsx | 24 ++++---- src/client/views/StyleProvider.tsx | 2 +- src/client/views/collections/CollectionMenu.tsx | 8 +-- .../views/collections/CollectionSchemaView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 6 +- .../views/collections/CollectionTreeView.scss | 2 +- .../views/collections/CollectionTreeView.tsx | 3 +- src/client/views/collections/TabDocView.tsx | 6 +- src/client/views/collections/TreeView.scss | 2 +- src/client/views/collections/TreeView.tsx | 22 ++++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/globalCssVariables.scss | 2 + src/client/views/globalCssVariables.scss.d.ts | 1 + src/client/views/nodes/AudioBox.tsx | 2 +- src/client/views/nodes/ColorBox.tsx | 6 +- src/client/views/nodes/DocumentView.tsx | 14 ++--- src/client/views/nodes/PresBox.tsx | 8 +-- .../views/nodes/formattedText/RichTextMenu.tsx | 8 +-- src/client/views/pdf/PDFViewer.tsx | 2 +- src/fields/Doc.ts | 2 +- 32 files changed, 176 insertions(+), 166 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 82750bd53..00ee0f4b9 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1203,7 +1203,7 @@ Scripting.addGlobal(function openDragFactory(dragFactory: Doc) { if (copy) { CollectionDockingView.AddSplit(copy, "right"); const view = DocumentManager.Instance.getFirstDocumentView(copy); - view && SelectionManager.SelectDoc(view, false); + view && SelectionManager.SelectView(view, false); } }); Scripting.addGlobal(function snapshotDashboard() { CurrentUserUtils.snapshotDashboard(Doc.UserDoc()); }, diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 34e274699..c6b654dda 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -235,7 +235,7 @@ export namespace DictationManager { export const execute = async (phrase: string) => { return UndoManager.RunInBatch(async () => { - const targets = SelectionManager.SelectedDocuments(); + const targets = SelectionManager.Views(); if (!targets || !targets.length) { return; } diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 6258cc0ab..1c81cf26c 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -46,12 +46,12 @@ export class DocumentManager { }); this.DocumentViews.push(view); } - public RemoveView = (view: DocumentView) => { + public RemoveView = action((view: DocumentView) => { const index = this.DocumentViews.indexOf(view); index !== -1 && this.DocumentViews.splice(index, 1); this.LinkedDocumentViews.slice().forEach(action((pair, i) => pair.a === view || pair.b === view ? this.LinkedDocumentViews.splice(i, 1) : null)); - } + }) //gets all views public getDocumentViewsById(id: string) { diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts index f4cf336e2..7a449b882 100644 --- a/src/client/util/HypothesisUtils.ts +++ b/src/client/util/HypothesisUtils.ts @@ -29,7 +29,7 @@ export namespace Hypothesis { * Search for a WebDocument whose url field matches the given uri, return undefined if not found */ export const findWebDoc = async (uri: string) => { - const currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document; + const currentDoc = SelectionManager.Views().length && SelectionManager.Views()[0].props.Document; if (currentDoc && Cast(currentDoc.data, WebField)?.url.href === uri) return currentDoc; // always check first whether the currently selected doc is the annotation's source, only use Search otherwise const results: Doc[] = []; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 728a4bce1..f657e5b40 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -10,38 +10,38 @@ export namespace SelectionManager { class Manager { @observable IsDragging: boolean = false; - SelectedDocuments: ObservableMap = new ObservableMap(); + SelectedViews: ObservableMap = new ObservableMap(); @observable SelectedSchemaDocument: Doc | undefined; @observable SelectedSchemaCollection: CollectionSchemaView | undefined; @action - SelectSchemaDoc(collectionView: Opt, doc: Opt) { + SelectSchemaView(collectionView: Opt, doc: Opt) { manager.SelectedSchemaDocument = doc; manager.SelectedSchemaCollection = collectionView; } @action - SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { + SelectView(docView: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it - if (!manager.SelectedDocuments.get(docView)) { + if (!manager.SelectedViews.get(docView)) { if (!ctrlPressed) { this.DeselectAll(); } - manager.SelectedDocuments.set(docView, true); + manager.SelectedViews.set(docView, true); docView.props.whenActiveChanged(true); - } else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) { - Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false)); + } else if (!ctrlPressed && Array.from(manager.SelectedViews.entries()).length > 1) { + Array.from(manager.SelectedViews.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false)); manager.SelectedSchemaDocument = undefined; manager.SelectedSchemaCollection = undefined; - manager.SelectedDocuments.clear(); - manager.SelectedDocuments.set(docView, true); + manager.SelectedViews.clear(); + manager.SelectedViews.set(docView, true); } } @action - DeselectDoc(docView: DocumentView): void { + DeselectView(docView: DocumentView): void { - if (manager.SelectedDocuments.get(docView)) { - manager.SelectedDocuments.delete(docView); + if (manager.SelectedViews.get(docView)) { + manager.SelectedViews.delete(docView); docView.props.whenActiveChanged(false); } } @@ -49,49 +49,49 @@ export namespace SelectionManager { DeselectAll(): void { manager.SelectedSchemaCollection = undefined; manager.SelectedSchemaDocument = undefined; - Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false)); - manager.SelectedDocuments.clear(); + Array.from(manager.SelectedViews.keys()).map(dv => dv.props.whenActiveChanged(false)); + manager.SelectedViews.clear(); } } const manager = new Manager(); - export function DeselectDoc(docView: DocumentView): void { - manager.DeselectDoc(docView); + export function DeselectView(docView: DocumentView): void { + manager.DeselectView(docView); } - export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { - manager.SelectDoc(docView, ctrlPressed); + export function SelectView(docView: DocumentView, ctrlPressed: boolean): void { + manager.SelectView(docView, ctrlPressed); } - export function SelectSchemaDoc(colSchema: Opt, document: Opt): void { - manager.SelectSchemaDoc(colSchema, document); + export function SelectSchemaView(colSchema: Opt, document: Opt): void { + manager.SelectSchemaView(colSchema, document); } const IsSelectedCache = computedFn(function isSelected(doc: DocumentView) { // wraapping get() in a computedFn only generates mobx() invalidations when the return value of the function for the specific get parameters has changed - return manager.SelectedDocuments.get(doc) ? true : false; + return manager.SelectedViews.get(doc) ? true : false; }); // computed functions, such as used in IsSelected generate errors if they're called outside of a // reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature // to avoid unnecessary mobx invalidations when running inside a reaction. export function IsSelected(doc: DocumentView | undefined, outsideReaction?: boolean): boolean { return !doc ? false : outsideReaction ? - manager.SelectedDocuments.get(doc) ? true : false : // get() accesses a hashtable -- setting anything in the hashtable generates a mobx invalidation for every get() + manager.SelectedViews.get(doc) ? true : false : // get() accesses a hashtable -- setting anything in the hashtable generates a mobx invalidation for every get() IsSelectedCache(doc); } export function DeselectAll(except?: Doc): void { let found: DocumentView | undefined = undefined; if (except) { - for (const view of Array.from(manager.SelectedDocuments.keys())) { + for (const view of Array.from(manager.SelectedViews.keys())) { if (view.props.Document === except) found = view; } } manager.DeselectAll(); - if (found) manager.SelectDoc(found, false); + if (found) manager.SelectView(found, false); } - export function SelectedDocuments(): Array { - return Array.from(manager.SelectedDocuments.keys()).filter(dv => dv.props.Document._viewType !== CollectionViewType.Docking); + export function Views(): Array { + return Array.from(manager.SelectedViews.keys()).filter(dv => dv.props.Document._viewType !== CollectionViewType.Docking); } export function SelectedSchemaDoc(): Doc | undefined { return manager.SelectedSchemaDocument; diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 646926bb7..2aea73528 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -166,7 +166,7 @@ export class SharingManager extends React.Component<{}> { const key = normalizeEmail(StrCast(group.title)); const acl = `acl-${key}`; - const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); + const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); docs.forEach(doc => { doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc); @@ -271,7 +271,7 @@ export class SharingManager extends React.Component<{}> { const acl = `acl-${normalizeEmail(user.email)}`; const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; - const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); + const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); docs.forEach(doc => { doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); distributeAcls(acl, permission as SharingPermissions, doc); @@ -323,7 +323,7 @@ export class SharingManager extends React.Component<{}> { private focusOn = (contents: string) => { const title = this.targetDoc ? StrCast(this.targetDoc.title) : ""; - const docs = SelectionManager.SelectedDocuments().length > 1 ? SelectionManager.SelectedDocuments().map(docView => docView.props.Document) : [this.targetDoc]; + const docs = SelectionManager.Views().length > 1 ? SelectionManager.Views().map(docView => docView.props.Document) : [this.targetDoc]; return ( { const target = targetDoc || this.targetDoc!; - const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); + const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); docs.forEach(doc => { for (const [key, value] of Object.entries(doc[AclSym])) { distributeAcls(key, AclMap.get(value)! as SharingPermissions, target); @@ -458,9 +458,9 @@ export class SharingManager extends React.Component<{}> { const groups = this.groupSort === "ascending" ? groupList.slice().sort(this.sortGroups) : this.groupSort === "descending" ? groupList.slice().sort(this.sortGroups).reverse() : groupList; // handles the case where multiple documents are selected - let docs = SelectionManager.SelectedDocuments().length < 2 ? + let docs = SelectionManager.Views().length < 2 ? [this.layoutDocAcls ? this.targetDoc : this.targetDoc?.[DataSym]] - : SelectionManager.SelectedDocuments().map(docView => this.layoutDocAcls ? docView.props.Document : docView.props.Document?.[DataSym]); + : SelectionManager.Views().map(docView => this.layoutDocAcls ? docView.props.Document : docView.props.Document?.[DataSym]); if (this.myDocAcls) { const newDocs: Doc[] = []; diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index dc6311696..96f5d78fd 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -187,7 +187,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV get pinButton() { const targetDoc = this.view0?.props.Document; const isPinned = targetDoc && Doc.isDocPinned(targetDoc); - return !targetDoc ? (null) :
    {SelectionManager.SelectedDocuments().length > 1 ? "Pin multiple documents to presentation" : "Pin to presentation"}
    }> + return !targetDoc ? (null) :
    {SelectionManager.Views().length > 1 ? "Pin multiple documents to presentation" : "Pin to presentation"}
    }>
    this.props.views().map(view => view && TabDocView.PinDoc(view.props.Document, false)))}> @@ -336,7 +336,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV } openContextMenu = (e: React.MouseEvent) => { - let child = SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0]; + let child = SelectionManager.Views()[0].ContentDiv!.children[0]; while (child.children.length) { const next = Array.from(child.children).find(c => typeof (c.className) === "string"); if (next?.className.includes(DocumentView.ROOT_DIV)) break; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 1d0c5dac0..eed77b398 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -57,12 +57,12 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b constructor(props: any) { super(props); DocumentDecorations.Instance = this; - reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this.titleBlur(false)); + reaction(() => SelectionManager.Views().slice(), docs => this.titleBlur(false)); } @computed get Bounds(): { x: number, y: number, b: number, r: number } { - return SelectionManager.SelectedDocuments().map(dv => dv.getBounds()).reduce((bounds, rect) => + return SelectionManager.Views().map(dv => dv.getBounds()).reduce((bounds, rect) => !rect ? bounds : { x: Math.min(rect.left, bounds.x), @@ -80,8 +80,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b this._titleControlString = this._accumulatedTitle; } else if (this._titleControlString.startsWith("#")) { const selectionTitleFieldKey = this._titleControlString.substring(1); - selectionTitleFieldKey === "title" && (SelectionManager.SelectedDocuments()[0].dataDoc["title-custom"] = !this._accumulatedTitle.startsWith("-")); - UndoManager.RunInBatch(() => selectionTitleFieldKey && SelectionManager.SelectedDocuments().forEach(d => { + selectionTitleFieldKey === "title" && (SelectionManager.Views()[0].dataDoc["title-custom"] = !this._accumulatedTitle.startsWith("-")); + UndoManager.RunInBatch(() => selectionTitleFieldKey && SelectionManager.Views().forEach(d => { const value = typeof d.props.Document[selectionTitleFieldKey] === "number" ? +this._accumulatedTitle : this._accumulatedTitle; Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, value, true); }), "title blur"); @@ -96,7 +96,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b const text = e.target.value; if (text.startsWith("::")) { this._accumulatedTitle = text.slice(2, text.length); - const promoteDoc = SelectionManager.SelectedDocuments()[0]; + const promoteDoc = SelectionManager.Views()[0]; Doc.SetInPlace(promoteDoc.props.Document, "title", this._accumulatedTitle, true); DocUtils.Publish(promoteDoc.props.Document, this._accumulatedTitle, promoteDoc.props.addDocument, promoteDoc.props.removeDocument); } @@ -118,8 +118,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onBackgroundMove = (dragTitle: boolean, e: PointerEvent): boolean => { - const dragDocView = SelectionManager.SelectedDocuments()[0]; - const dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); + const dragDocView = SelectionManager.Views()[0]; + const dragData = new DragManager.DocumentDragData(SelectionManager.Views().map(dv => dv.props.Document)); const { left, top } = dragDocView.getBounds() || { left: 0, top: 0 }; dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.ContentScale()).transformDirection(e.x - left, e.y - top); dragData.moveDocument = dragDocView.props.moveDocument; @@ -128,7 +128,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b dragData.dropAction = dragDocView.props.dropAction; this.Interacting = true; this._hidden = true; - DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(dv => dv.ContentDiv!), dragData, e.x, e.y, { + DragManager.StartDocumentDrag(SelectionManager.Views().map(dv => dv.ContentDiv!), dragData, e.x, e.y, { dragComplete: action(e => { dragData.canEmbed && SelectionManager.DeselectAll(); this._hidden = this.Interacting = false; @@ -145,7 +145,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onCloseClick = async (e: React.MouseEvent | undefined) => { if (!e?.button) { - const selected = SelectionManager.SelectedDocuments().slice(); + const selected = SelectionManager.Views().slice(); SelectionManager.DeselectAll(); selected.map(dv => dv.props.removeDocument?.(dv.props.Document)); } @@ -158,7 +158,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onMaximizeClick = (e: PointerEvent): void => { if (e.button === 0) { - const selectedDocs = SelectionManager.SelectedDocuments(); + const selectedDocs = SelectionManager.Views(); if (selectedDocs.length) { if (e.ctrlKey) { // open an alias in a new tab with Ctrl Key selectedDocs[0].props.Document._fullScreenView = Doc.MakeAlias(selectedDocs[0].props.Document); @@ -181,7 +181,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onIconifyClick = (e: PointerEvent): void => { if (e.button === 0) { - SelectionManager.SelectedDocuments().forEach(dv => dv?.iconify()); + SelectionManager.Views().forEach(dv => dv?.iconify()); } SelectionManager.DeselectAll(); } @@ -189,7 +189,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onSelectorUp = (e: React.PointerEvent): void => { setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e) => { - const selDoc = SelectionManager.SelectedDocuments()?.[0]; + const selDoc = SelectionManager.Views()?.[0]; if (selDoc) { selDoc.props.ContainingCollectionView?.props.select(false); } @@ -207,7 +207,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b onRadiusMove = (e: PointerEvent, down: number[]): boolean => { let dist = Math.sqrt((e.clientX - down[0]) * (e.clientX - down[0]) + (e.clientY - down[1]) * (e.clientY - down[1])); dist = dist < 3 ? 0 : dist; - SelectionManager.SelectedDocuments().map(dv => dv.props.Document).map(doc => doc.layout instanceof Doc ? doc.layout : doc.isTemplateForField ? doc : Doc.GetProto(doc)). + SelectionManager.Views().map(dv => dv.props.Document).map(doc => doc.layout instanceof Doc ? doc.layout : doc.isTemplateForField ? doc : Doc.GetProto(doc)). map(d => d.borderRounding = `${Math.max(0, dist)}px`); return false; } @@ -220,7 +220,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b setupMoveUpEvents(this, e, this.onRotateMove, this.onRotateUp, (e) => { }); this._prevX = e.clientX; this._prevY = e.clientY; - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + SelectionManager.Views().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { const ink = Cast(doc.data, InkField)?.inkData; @@ -257,7 +257,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b this._prevX = e.clientX; this._prevY = e.clientY; var index = 0; - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + SelectionManager.Views().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { doc.rotation = Number(doc.rotation) + Number(angle); @@ -304,7 +304,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b onPointerDown = (e: React.PointerEvent): void => { this._inkDocs = []; - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + SelectionManager.Views().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height) { this._inkDocs.push({ x: doc.x, y: doc.y, width: doc._width, height: doc._height }); @@ -327,18 +327,18 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b this._snapX = e.pageX; this._snapY = e.pageY; this._initialAutoHeight = true; - DragManager.docsBeingDragged = SelectionManager.SelectedDocuments().map(dv => dv.rootDoc); - SelectionManager.SelectedDocuments().map(dv => { + DragManager.docsBeingDragged = SelectionManager.Views().map(dv => dv.rootDoc); + SelectionManager.Views().map(dv => { this._dragHeights.set(dv.layoutDoc, NumCast(dv.layoutDoc._height)); dv.layoutDoc._delayAutoHeight = dv.layoutDoc._height; }); } onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => { - const first = SelectionManager.SelectedDocuments()[0]; + const first = SelectionManager.Views()[0]; let thisPt = { thisX: e.clientX - this._offX, thisY: e.clientY - this._offY }; var fixedAspect = Doc.NativeAspect(first.layoutDoc); - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + SelectionManager.Views().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc._width && doc._height && InkStrokeProperties.Instance?._lock) { fixedAspect = Doc.NativeHeight(doc); @@ -371,7 +371,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b let dragRight = false; let dX = 0, dY = 0, dW = 0, dH = 0; const unfreeze = () => - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => + SelectionManager.Views().forEach(action((element: DocumentView) => ((element.rootDoc.type === DocumentType.RTF || element.rootDoc.type === DocumentType.COMPARISON || (element.rootDoc.type === DocumentType.WEB && Doc.LayoutField(element.rootDoc) instanceof HtmlField)) @@ -420,7 +420,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b break; } - SelectionManager.SelectedDocuments().forEach(action((docView: DocumentView) => { + SelectionManager.Views().forEach(action((docView: DocumentView) => { if (e.ctrlKey && !Doc.NativeHeight(docView.props.Document)) docView.toggleNativeDimensions(); if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { const doc = Document(docView.rootDoc); @@ -486,7 +486,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @action onPointerUp = (e: PointerEvent): void => { - SelectionManager.SelectedDocuments().map(dv => { + SelectionManager.Views().map(dv => { if (NumCast(dv.layoutDoc._delayAutoHeight) < this._dragHeights.get(dv.layoutDoc)!) { dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.ContentScale(), dv.props.PanelWidth(), dv.props.PanelHeight()); dv.layoutDoc._autoHeight = true; @@ -501,7 +501,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b //need to change points for resize, or else rotation/control points will fail. - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView, index) => { + SelectionManager.Views().forEach(action((element: DocumentView, index) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) { const ink = Cast(doc.data, InkField)?.inkData; @@ -524,8 +524,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @computed get selectionTitle(): string { - if (SelectionManager.SelectedDocuments().length === 1) { - const selected = SelectionManager.SelectedDocuments()[0]; + if (SelectionManager.Views().length === 1) { + const selected = SelectionManager.Views()[0]; if (this._titleControlString.startsWith("=")) { return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })!.script.run({ self: selected.rootDoc, this: selected.layoutDoc }, console.log).result?.toString() || ""; } @@ -533,7 +533,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b return Field.toString(selected.props.Document[this._titleControlString.substring(1)] as Field) || "-unset-"; } return this._accumulatedTitle; - } else if (SelectionManager.SelectedDocuments().length > 1) { + } else if (SelectionManager.Views().length > 1) { return "-multiple-"; } return "-unset-"; @@ -558,16 +558,16 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b render() { const darkScheme = CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimgray" : undefined; const bounds = this.Bounds; - const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; + const seldoc = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { return (null); } - const canDelete = SelectionManager.SelectedDocuments().some(docView => { + const canDelete = SelectionManager.Views().some(docView => { const collectionAcl = docView.props.ContainingCollectionView ? GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]) : AclEdit; const docAcl = GetEffectiveAcl(docView.props.Document); return !docView.props.Document._stayInCollection && (collectionAcl === AclAdmin || collectionAcl === AclEdit || docAcl === AclAdmin); }); - const canOpen = SelectionManager.SelectedDocuments().some(docView => !docView.props.Document._stayInCollection); + const canOpen = SelectionManager.Views().some(docView => !docView.props.Document._stayInCollection); const closeIcon = !canDelete ? (null) : ( Close
    } placement="top">
    @@ -575,7 +575,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
    ); const openIcon = !canOpen ? (null) : Open in Tab (ctrl: as alias, shift: in new collection)
    } placement="top">
    { e.preventDefault(); e.stopPropagation(); }} onPointerDown={this.onMaximizeDown}> - {SelectionManager.SelectedDocuments().length === 1 ? : "..."} + {SelectionManager.Views().length === 1 ? : "..."}
    ; @@ -606,7 +606,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b left: bounds.x - this._resizeBorderWidth / 2, top: bounds.y - this._resizeBorderWidth / 2, pointerEvents: KeyManager.Instance.ShiftPressed || this.Interacting ? "none" : "all", - zIndex: SelectionManager.SelectedDocuments().length > 1 ? 900 : 0, + zIndex: SelectionManager.Views().length > 1 ? 900 : 0, }} onPointerDown={this.onBackgroundDown} onContextMenu={e => { e.preventDefault(); e.stopPropagation(); }} >
    {bounds.r - bounds.x < 15 && bounds.b - bounds.y < 15 ? (null) : <> @@ -618,7 +618,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b }}> {closeIcon} {bounds.r - bounds.x < 100 ? null : titleArea} - {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : + {SelectionManager.Views().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : {`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
    } placement="top">
    @@ -645,7 +645,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
    {seldoc?.Document.type === DocumentType.FONTICON ? (null) :
    - +
    } }
    diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index a391bb550..3311a4dcc 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -93,7 +93,7 @@ export class KeyManager { return { stopPropagation: false, preventDefault: false }; } - const ungroupings = SelectionManager.SelectedDocuments().slice(); + const ungroupings = SelectionManager.Views().slice(); UndoManager.RunInBatch(() => ungroupings.map(dv => dv.layoutDoc.group = undefined), "ungroup"); SelectionManager.DeselectAll(); break; @@ -102,7 +102,7 @@ export class KeyManager { return { stopPropagation: false, preventDefault: false }; } - const groupings = SelectionManager.SelectedDocuments().slice(); + const groupings = SelectionManager.Views().slice(); const randomGroup = random(0, 1000); UndoManager.RunInBatch(() => groupings.map(dv => dv.layoutDoc.group = randomGroup), "group"); SelectionManager.DeselectAll(); @@ -139,14 +139,14 @@ export class KeyManager { return { stopPropagation: false, preventDefault: false }; } - const selected = SelectionManager.SelectedDocuments().slice(); + const selected = SelectionManager.Views().slice(); UndoManager.RunInBatch(() => selected.map(dv => !dv.props.Document._stayInCollection && dv.props.removeDocument?.(dv.props.Document)), "delete"); SelectionManager.DeselectAll(); break; - case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge(-1, 0)), "nudge left"); break; - case "arrowright": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(1, 0)), "nudge right"); break; - case "arrowup": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, -1)), "nudge up"); break; - case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, 1)), "nudge down"); break; + case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge(-1, 0)), "nudge left"); break; + case "arrowright": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(1, 0)), "nudge right"); break; + case "arrowup": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, -1)), "nudge up"); break; + case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, 1)), "nudge down"); break; } return { @@ -160,10 +160,10 @@ export class KeyManager { const preventDefault = false; switch (keyname) { - case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(-10, 0)), "nudge left"); break; - case "arrowright": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(10, 0)), "nudge right"); break; - case "arrowup": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, -10)), "nudge up"); break; - case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.SelectedDocuments().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, 10)), "nudge down"); break; + case "arrowleft": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(-10, 0)), "nudge left"); break; + case "arrowright": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(10, 0)), "nudge right"); break; + case "arrowup": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, -10)), "nudge up"); break; + case "arrowdown": UndoManager.RunInBatch(() => SelectionManager.Views().map(dv => dv.props.CollectionFreeFormDocumentView?.().nudge?.(0, 10)), "nudge down"); break; } return { @@ -179,7 +179,7 @@ export class KeyManager { switch (keyname) { case "Æ’": case "f": - const dv = SelectionManager.SelectedDocuments()?.[0]; + const dv = SelectionManager.Views()?.[0]; UndoManager.RunInBatch(() => dv?.float(), "float"); } @@ -219,7 +219,7 @@ export class KeyManager { SearchBox.Instance.enter(undefined); break; case "o": - const target = SelectionManager.SelectedDocuments()[0]; + const target = SelectionManager.Views()[0]; target && CollectionDockingView.OpenFullScreen(target.props.Document); break; case "r": @@ -246,11 +246,11 @@ export class KeyManager { preventDefault = false; break; case "x": - if (SelectionManager.SelectedDocuments().length) { + if (SelectionManager.Views().length) { const bds = DocumentDecorations.Instance.Bounds; - const pt = SelectionManager.SelectedDocuments()[0].props.ScreenToLocalTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); - const text = `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.SelectedDocuments().map(dv => dv.Document[Id]).join(":"); - SelectionManager.SelectedDocuments().length && navigator.clipboard.writeText(text); + const pt = SelectionManager.Views()[0].props.ScreenToLocalTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); + const text = `__DashDocId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views().map(dv => dv.Document[Id]).join(":"); + SelectionManager.Views().length && navigator.clipboard.writeText(text); DocumentDecorations.Instance.onCloseClick(undefined); stopPropagation = false; preventDefault = false; @@ -259,9 +259,9 @@ export class KeyManager { case "c": if (!PDFMenu.Instance.Active && DocumentDecorations.Instance.Bounds.r - DocumentDecorations.Instance.Bounds.x > 2) { const bds = DocumentDecorations.Instance.Bounds; - const pt = SelectionManager.SelectedDocuments()[0].props.ScreenToLocalTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); - const text = `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.SelectedDocuments().map(dv => dv.Document[Id]).join(":"); - SelectionManager.SelectedDocuments().length && navigator.clipboard.writeText(text); + const pt = SelectionManager.Views()[0].props.ScreenToLocalTransform().transformPoint(bds.x + (bds.r - bds.x) / 2, bds.y + (bds.b - bds.y) / 2); + const text = `__DashCloneId(${pt?.[0] || 0},${pt?.[1] || 0}):` + SelectionManager.Views().map(dv => dv.Document[Id]).join(":"); + SelectionManager.Views().length && navigator.clipboard.writeText(text); stopPropagation = false; } preventDefault = false; @@ -278,7 +278,7 @@ export class KeyManager { const plain = e.clipboardData?.getData("text/plain"); const clone = plain?.startsWith("__DashCloneId("); if (plain && (plain.startsWith("__DashDocId(") || clone)) { - const first = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; + const first = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (first?.props.Document.type === DocumentType.COL) { const docids = plain.split(":"); let count = 1; diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index ad5c70fb1..2dac44bf8 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -25,7 +25,7 @@ export class InkStrokeProperties { } @computed get selectedInk() { - const inks = SelectionManager.SelectedDocuments().filter(i => Document(i.rootDoc).type === DocumentType.INK); + const inks = SelectionManager.Views().filter(i => Document(i.rootDoc).type === DocumentType.INK); return inks.length ? inks : undefined; } @computed get unFilled() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; } @@ -150,7 +150,7 @@ export class InkStrokeProperties { @action rotate = (angle: number) => { const _centerPoints: { X: number, Y: number }[] = []; - SelectionManager.SelectedDocuments().forEach(action(inkView => { + SelectionManager.Views().forEach(action(inkView => { const doc = Document(inkView.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { const ink = Cast(doc.data, InkField)?.inkData; @@ -167,7 +167,7 @@ export class InkStrokeProperties { })); var index = 0; - SelectionManager.SelectedDocuments().forEach(action(inkView => { + SelectionManager.Views().forEach(action(inkView => { const doc = Document(inkView.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { doc.rotation = Number(doc.rotation) + Number(angle); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 1731d715a..bc3be4076 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -55,8 +55,8 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get selectedDocumentView() { - if (SelectionManager.SelectedDocuments().length) { - return SelectionManager.SelectedDocuments()[0]; + if (SelectionManager.Views().length) { + return SelectionManager.Views()[0]; } else return undefined; } @@ -187,7 +187,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @action @undoBatch onLock = () => { - SelectionManager.SelectedDocuments().forEach(dv => dv.docView?.toggleLockPosition()); + SelectionManager.Views().forEach(dv => dv.docView?.toggleLockPosition()); } @computed @@ -224,7 +224,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action setDictation = () => { - SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._showAudio = dv.rootDoc._showAudio === !dv.rootDoc._showAudio); + SelectionManager.Views().forEach(dv => dv.rootDoc._showAudio = dv.rootDoc._showAudio === !dv.rootDoc._showAudio); } @computed @@ -244,7 +244,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action setTitle = () => { - SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._showTitle = dv.rootDoc._showTitle === undefined ? "title" : undefined); + SelectionManager.Views().forEach(dv => dv.rootDoc._showTitle = dv.rootDoc._showTitle === undefined ? "title" : undefined); } @computed @@ -263,7 +263,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action setCaption = () => { - SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._showCaption = dv.rootDoc._showCaption === undefined ? "caption" : undefined); + SelectionManager.Views().forEach(dv => dv.rootDoc._showCaption = dv.rootDoc._showCaption === undefined ? "caption" : undefined); } @computed @@ -282,7 +282,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action setChrome = () => { - SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._chromeStatus = dv.rootDoc._chromeStatus === "disabled" ? "enabled" : "disabled"); + SelectionManager.Views().forEach(dv => dv.rootDoc._chromeStatus = dv.rootDoc._chromeStatus === "disabled" ? "enabled" : "disabled"); } @computed @@ -325,7 +325,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const value = e.target.value; this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value); - SelectionManager.SelectedDocuments().forEach(dv => { + SelectionManager.Views().forEach(dv => { if (value === "nothing") { dv.docView?.noOnClick(); } else if (value === "enterPortal") { @@ -347,7 +347,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action editOnClickScript = () => { if (this.selectedDoc) { - if (SelectionManager.SelectedDocuments().length) SelectionManager.SelectedDocuments().forEach(dv => DocUtils.makeCustomViewClicked(dv.rootDoc, undefined, "onClick")); + if (SelectionManager.Views().length) SelectionManager.Views().forEach(dv => DocUtils.makeCustomViewClicked(dv.rootDoc, undefined, "onClick")); else DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, "onClick"); } } @@ -432,7 +432,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @action @undoBatch changeFitToBox = () => { if (this.selectedDoc) { - if (SelectionManager.SelectedDocuments().length) SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._fitToBox = !dv.rootDoc._fitToBox); + if (SelectionManager.Views().length) SelectionManager.Views().forEach(dv => dv.rootDoc._fitToBox = !dv.rootDoc._fitToBox); else this.selectedDoc._fitToBox = !this.selectedDoc._fitToBox; } } @@ -440,7 +440,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @action @undoBatch changeClusters = () => { if (this.selectedDoc) { - if (SelectionManager.SelectedDocuments().length) SelectionManager.SelectedDocuments().forEach(dv => dv.rootDoc._useClusters = !dv.rootDoc._useClusters); + if (SelectionManager.Views().length) SelectionManager.Views().forEach(dv => dv.rootDoc._useClusters = !dv.rootDoc._useClusters); else this.selectedDoc._useClusters = !this.selectedDoc._useClusters; } } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 1c14bc721..32342075c 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -48,7 +48,7 @@ export class PropertiesView extends React.Component { @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get selectedDocumentView() { - if (SelectionManager.SelectedDocuments().length) return SelectionManager.SelectedDocuments()[0]; + if (SelectionManager.Views().length) return SelectionManager.Views()[0]; if (PresBox.Instance?._selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); return undefined; } @@ -118,8 +118,8 @@ export class PropertiesView extends React.Component { @computed get expandedField() { if (this.dataDoc && this.selectedDoc) { const ids: { [key: string]: string } = {}; - const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : - SelectionManager.SelectedDocuments().map(dv => this.layoutFields ? Doc.Layout(dv.layoutDoc) : dv.dataDoc); + const docs = SelectionManager.Views().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : + SelectionManager.Views().map(dv => this.layoutFields ? Doc.Layout(dv.layoutDoc) : dv.dataDoc); docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key))); const rows: JSX.Element[] = []; for (const key of Object.keys(ids).slice().sort()) { @@ -162,7 +162,7 @@ export class PropertiesView extends React.Component { @computed get noviceFields() { if (this.dataDoc) { const ids: { [key: string]: string } = {}; - const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => dv.dataDoc); + const docs = SelectionManager.Views().length < 2 ? [this.dataDoc] : SelectionManager.Views().map(dv => dv.dataDoc); docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key))); const rows: JSX.Element[] = []; const noviceReqFields = ["author", "creationDate", "tags"]; @@ -217,7 +217,7 @@ export class PropertiesView extends React.Component { @undoBatch setKeyValue = (value: string) => { - const docs = SelectionManager.SelectedDocuments().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => this.layoutFields ? dv.layoutDoc : dv.dataDoc); + const docs = SelectionManager.Views().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.Views().map(dv => this.layoutFields ? dv.layoutDoc : dv.dataDoc); docs.forEach(doc => { if (value.indexOf(":") !== -1) { const newVal = value[0].toUpperCase() + value.substring(1, value.length); @@ -256,7 +256,7 @@ export class PropertiesView extends React.Component { } @computed get layoutPreview() { - if (SelectionManager.SelectedDocuments().length > 1) { + if (SelectionManager.Views().length > 1) { return "-- multiple selected --"; } if (this.selectedDoc) { @@ -305,7 +305,7 @@ export class PropertiesView extends React.Component { */ @undoBatch changePermissions = (e: any, user: string) => { - const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.selectedDoc!] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); + const docs = SelectionManager.Views().length < 2 ? [this.selectedDoc!] : SelectionManager.Views().map(docView => docView.props.Document); SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs); } @@ -385,9 +385,9 @@ export class PropertiesView extends React.Component { ]); // all selected docs - const docs = SelectionManager.SelectedDocuments().length < 2 ? + const docs = SelectionManager.Views().length < 2 ? [this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym]] - : SelectionManager.SelectedDocuments().map(docView => this.layoutDocAcls ? docView.props.Document : docView.props.Document[DataSym]); + : SelectionManager.Views().map(docView => this.layoutDocAcls ? docView.props.Document : docView.props.Document[DataSym]); const target = docs[0]; @@ -438,7 +438,7 @@ export class PropertiesView extends React.Component { @computed get editableTitle() { const titles = new Set(); - SelectionManager.SelectedDocuments().forEach(dv => titles.add(StrCast(dv.rootDoc.title))); + SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title))); const title = Array.from(titles.keys()).length > 1 ? "--multiple selected--" : StrCast(this.selectedDoc?.title); return
    { @undoBatch @action setTitle = (value: string) => { - if (SelectionManager.SelectedDocuments().length > 1) { - SelectionManager.SelectedDocuments().map(dv => Doc.SetInPlace(dv.rootDoc, "title", value, true)); + if (SelectionManager.Views().length > 1) { + SelectionManager.Views().map(dv => Doc.SetInPlace(dv.rootDoc, "title", value, true)); return true; } else if (this.dataDoc) { if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, "title", value, true); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index d6571276a..83192164f 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -135,7 +135,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { } componentDidMount() { - reaction(() => SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0], + reaction(() => SelectionManager.Views().length && SelectionManager.Views()[0], (doc) => doc && this.SetSelection(doc)); } @@ -372,7 +372,7 @@ export class CollectionViewBaseChrome extends React.Component { - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + SelectionManager.Views().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK) { switch (field) { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index f153f1cca..c39f8b255 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -352,7 +352,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action setFocused = (doc: Doc) => this._focusedTable = doc; @action setPreviewDoc = (doc: Opt) => { - SelectionManager.SelectSchemaDoc(this, doc); + SelectionManager.SelectSchemaView(this, doc); this._previewDoc = doc; } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 38e461e46..d7b9d9745 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -305,8 +305,8 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: } else { let srcUrl: string | undefined; let srcWeb: Doc | undefined; - if (SelectionManager.SelectedDocuments().length) { - srcWeb = SelectionManager.SelectedDocuments()[0].props.Document; + if (SelectionManager.Views().length) { + srcWeb = SelectionManager.Views()[0].props.Document; srcUrl = (srcWeb.data as WebField).url?.href?.match(/http[s]?:\/\/[^/]*/)?.[0]; } const reg = new RegExp(Utils.prepend(""), "g"); @@ -315,7 +315,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc).text = text; this.addDocument(htmlDoc); if (srcWeb) { - const iframe = SelectionManager.SelectedDocuments()[0].ContentDiv?.getElementsByTagName("iframe")?.[0]; + const iframe = SelectionManager.Views()[0].ContentDiv?.getElementsByTagName("iframe")?.[0]; const focusNode = (iframe?.contentDocument?.getSelection()?.focusNode as any); if (focusNode) { const rects = iframe?.contentWindow?.getSelection()?.getRangeAt(0).getClientRects(); diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index f774af74f..72ab51784 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -21,7 +21,7 @@ ul { list-style: none; - padding-left: 20px; + padding-left: $TREE_BULLET_WIDTH; margin-bottom: 1px; // otherwise vertical scrollbars may pop up for no apparent reason.... > .contentFittingDocumentView { width: unset; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index a90edc2c9..344a6c103 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -189,6 +189,7 @@ export class CollectionTreeView extends CollectionSubView this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); whenActiveChanged = (isActive: boolean) => { this.props.whenActiveChanged(this._isChildActive = isActive); }; active = (outsideReaction: boolean | undefined) => this.props.active(outsideReaction) || this._isChildActive; + panelWidth = () => this.props.PanelWidth() - 20; // bcz: 20 is the 10 + 10 for the left and right padding. @computed get treeChildren() { TraceMobx(); return this.props.childDocuments || this.childDocs; @@ -200,7 +201,7 @@ export class CollectionTreeView extends CollectionSubView boolean) => this.props.moveDocument?.(d, target, addDoc) || false; return TreeView.GetChildElements(this.treeChildren, this, this.doc, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove, moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.styleProvider, this.props.ScreenToLocalTransform, - this.outerXf, this.active, this.props.PanelWidth, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), + this.outerXf, this.active, this.panelWidth, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick, this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.dontRegisterChildViews, "boolean", null)); } diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index a4ab201bc..0d03936dc 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -117,14 +117,14 @@ export class TabDocView extends React.Component { // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected titleEle.onpointerdown = action((e: any) => { if (e.target.className !== "lm_close_tab") { - if (this.view) SelectionManager.SelectDoc(this.view, false); + if (this.view) SelectionManager.SelectView(this.view, false); else this._activated = true; if (Date.now() - titleEle.lastClick < 1000) titleEle.select(); titleEle.lastClick = Date.now(); (document.activeElement !== titleEle) && titleEle.focus(); } }); - tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.topMost && v.props.Document === doc), + tab._disposers.selectionDisposer = reaction(() => SelectionManager.Views().some(v => v.topMost && v.props.Document === doc), action((selected) => { if (selected) this._activated = true; const toggle = tab.element[0].children[1].children[0] as HTMLInputElement; @@ -222,7 +222,7 @@ export class TabDocView extends React.Component { } componentDidMount() { - const selected = () => SelectionManager.SelectedDocuments().some(v => v.props.Document === this._document); + const selected = () => SelectionManager.Views().some(v => v.props.Document === this._document); new _global.ResizeObserver(action((entries: any) => { for (const entry of entries) { this._panelWidth = entry.contentRect.width; diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 8468e27df..7a654c7cf 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -37,7 +37,7 @@ } .bullet { position: relative; - width: 20px; + width: $TREE_BULLET_WIDTH; color: $intermediate-color; margin-top: 3px; transform: scale(1.3, 1.3); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 31a1a2b99..f51c745bb 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -1,6 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; +import { TREE_BULLET_WIDTH } from '../globalCssVariables.scss'; import { DataSym, Doc, DocListCast, DocListCastOrNull, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; @@ -64,6 +65,8 @@ export interface TreeViewProps { whenActiveChanged: (isActive: boolean) => void; } +let treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("px", "")); } + @observer /** * Renders a treeView of a collection of documents @@ -83,6 +86,7 @@ export class TreeView extends React.Component { private _uniqueId = Utils.GenerateGuid(); private _editMaxWidth: number | string = 0; + @observable _dref: DocumentView | undefined | null; @computed get doc() { TraceMobx(); return this.props.document; } get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); } @@ -284,9 +288,9 @@ export class TreeView extends React.Component { docWidth = () => { const layoutDoc = this.layoutDoc; const aspect = Doc.NativeAspect(layoutDoc); - if (layoutDoc._fitWidth) return Math.min(this.props.panelWidth() - 20, layoutDoc[WidthSym]()); - if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.panelWidth() - 20)); - return Doc.NativeWidth(layoutDoc) ? Math.min(layoutDoc[WidthSym](), this.props.panelWidth() - 20) : Math.min(this.layoutDoc[WidthSym](), this.props.panelWidth() - 20); + if (layoutDoc._fitWidth) return Math.min(this.props.panelWidth() - treeBulletWidth(), layoutDoc[WidthSym]()); + if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.panelWidth() - treeBulletWidth())); + return Math.min(this.props.panelWidth() - treeBulletWidth(), Doc.NativeWidth(layoutDoc) ? layoutDoc[WidthSym]() : this.layoutDoc[WidthSym]()); } docHeight = () => { const layoutDoc = this.layoutDoc; @@ -354,9 +358,9 @@ export class TreeView extends React.Component { return rows; } - rtfWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.props.panelWidth() - 20); + rtfWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.props.panelWidth() - treeBulletWidth()); rtfHeight = () => this.rtfWidth() <= this.layoutDoc?.[WidthSym]() ? Math.min(this.layoutDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT; - rtfOutlineHeight = () => Math.max(this.layoutDoc?.[HeightSym](), 20); + rtfOutlineHeight = () => Math.max(this.layoutDoc?.[HeightSym](), treeBulletWidth()); expandPanelHeight = () => { if (this.layoutDoc._fitWidth) return this.docHeight(); const aspect = this.layoutDoc[WidthSym]() / this.layoutDoc[HeightSym](); @@ -486,7 +490,7 @@ export class TreeView extends React.Component { showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef.current?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : [{ script: ScriptField.MakeFunction(`openOnRight(self)`)!, label: "Open" }, { script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }]; - truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, 0); + truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, this.props.panelWidth()); onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); onChildDoubleClick = () => (!this.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); @@ -553,8 +557,10 @@ export class TreeView extends React.Component { moveDocument={this.move} removeDocument={this.props.removeDoc} ScreenToLocalTransform={this.getTransform} + NativeHeight={returnZero} + NativeWidth={returnZero} PanelWidth={this.truncateTitleWidth} - PanelHeight={returnZero} + PanelHeight={() => 18} contextMenuItems={this.contextMenuItems} renderDepth={1} focus={returnTrue} @@ -746,7 +752,7 @@ export class TreeView extends React.Component { const docs = TreeView.sortDocs(childDocs, StrCast(containingCollection?.[key + "-sortCriteria"])); - const rowWidth = () => panelWidth() - 20; + const rowWidth = () => panelWidth() - treeBulletWidth(); return docs.filter(child => child instanceof Doc).map((child, i) => { const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child); if (!pair.layout || pair.data instanceof Promise) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 1add65c10..0fb1c0f9c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -208,7 +208,7 @@ export class CollectionFreeFormView extends CollectionSubView { SelectionManager.DeselectAll(); - docs.map(doc => DocumentManager.Instance.getDocumentView(doc, this.props.CollectionView)).map(dv => dv && SelectionManager.SelectDoc(dv, true)); + docs.map(doc => DocumentManager.Instance.getDocumentView(doc, this.props.CollectionView)).map(dv => dv && SelectionManager.SelectView(dv, true)); } public isCurrent(doc: Doc) { return (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document._currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 47ffc48fb..d20d1abfc 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -152,7 +152,7 @@ export class MarqueeView extends React.Component SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(slide)!, false)); e.stopPropagation(); - } else if (!e.ctrlKey && !e.metaKey && SelectionManager.SelectedDocuments().length < 2) { + } else if (!e.ctrlKey && !e.metaKey && SelectionManager.Views().length < 2) { FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout && !this.props.childLayoutString ? e.key : ""; FormattedTextBox.LiveTextUndo = UndoManager.StartBatch("live text batch"); this.props.addLiveTextDocument(CurrentUserUtils.GetNewTextDoc("-typed text-", x, y, 200, 100, this.props.xMargin === 0)); diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index b2ea87c06..ccc9306c4 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -39,6 +39,7 @@ $MINIMIZED_ICON_SIZE:25; $MAX_ROW_HEIGHT: 44px; $DFLT_IMAGE_NATIVE_DIM: 900px; $MENU_PANEL_WIDTH: 60px; +$TREE_BULLET_WIDTH: 20px; :export { contextMenuZindex: $contextMenu-zindex; @@ -51,4 +52,5 @@ $MENU_PANEL_WIDTH: 60px; SEARCH_PANEL_HEIGHT: $searchpanel-height; DFLT_IMAGE_NATIVE_DIM: $DFLT_IMAGE_NATIVE_DIM; MENU_PANEL_WIDTH: $MENU_PANEL_WIDTH; + TREE_BULLET_WIDTH: $TREE_BULLET_WIDTH; } \ No newline at end of file diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/globalCssVariables.scss.d.ts index c56b75d5e..11e62e1eb 100644 --- a/src/client/views/globalCssVariables.scss.d.ts +++ b/src/client/views/globalCssVariables.scss.d.ts @@ -10,6 +10,7 @@ interface IGlobalScss { SEARCH_PANEL_HEIGHT: string; DFLT_IMAGE_NATIVE_DIM: string; MENU_PANEL_WIDTH: string; + TREE_BULLET_WIDTH: string; } declare const globalCssVariables: IGlobalScss; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 4b3c328b0..67d25e525 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -135,7 +135,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent SelectionManager.SelectedDocuments(), + this._disposers.reaction = reaction(() => SelectionManager.Views(), selected => { const sel = selected.length ? selected[0].props.Document : undefined; let link; diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index 52236a648..d5b6a269e 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -31,7 +31,7 @@ export class ColorBox extends ViewBoxBaseComponent { const targetDoc = view.props.Document.dragFactory instanceof Doc ? view.props.Document.dragFactory : view.props.Document.layout instanceof Doc ? view.props.Document.layout : @@ -54,7 +54,7 @@ export class ColorBox extends ViewBoxBaseComponent e.button === 0 && !e.ctrlKey && e.stopPropagation()} onClick={e => { (e.nativeEvent as any).stuff = true; e.stopPropagation(); }} style={{ width: `${100}%`, height: `${100}%` }} > @@ -67,7 +67,7 @@ export class ColorBox extends ViewBoxBaseComponent {ActiveInkWidth() ?? 2}
    ) => { SetActiveInkWidth(e.target.value); - SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value)); + SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value)); }} /> {/*
    {ActiveInkBezierApprox() ?? 2}
    ) => { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3c140a22a..56982bd89 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -409,7 +409,7 @@ export class DocumentViewInternal extends DocComponent { @@ -616,7 +616,7 @@ export class DocumentViewInternal extends DocComponent SelectionManager.SelectedDocuments().forEach(dv => dv.props.bringToFront(dv.rootDoc, false)), icon: "expand-arrows-alt" }); - zorderItems.push({ description: "Send to Back", event: () => SelectionManager.SelectedDocuments().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" }); + zorderItems.push({ description: "Bring to Front", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, false)), icon: "expand-arrows-alt" }); + zorderItems.push({ description: "Send to Back", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" }); zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: undoBatch(action(() => this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined)), icon: "expand-arrows-alt" }); !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" }); @@ -733,7 +733,7 @@ export class DocumentViewInternal extends DocComponent SelectionManager.SelectDoc(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. }); } @@ -983,7 +983,7 @@ export class DocumentView extends React.Component { topDoc.x = fpt[0]; topDoc.y = fpt[1]; } - setTimeout(() => SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); + setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); } } @@ -1061,7 +1061,7 @@ export class DocumentView extends React.Component { }); isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction); - select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed); + select = (ctrlPressed: boolean) => SelectionManager.SelectView(this, ctrlPressed); NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; PanelWidth = () => this.panelWidth; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index da74edbe3..42462000b 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -160,7 +160,7 @@ export class PresBox extends ViewBoxBaseComponent this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox } @computed get selectedDocumentView() { - if (SelectionManager.SelectedDocuments().length) return SelectionManager.SelectedDocuments()[0]; + if (SelectionManager.Views().length) return SelectionManager.Views()[0]; if (this._selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc); } @computed get isPres(): boolean { @@ -195,7 +195,7 @@ export class PresBox extends ViewBoxBaseComponent this.turnOffEdit(true); DocListCastAsync((Doc.UserDoc().myPresentations as Doc).data).then(pres => !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc)); - this._disposers.selection = reaction(() => SelectionManager.SelectedDocuments(), + this._disposers.selection = reaction(() => SelectionManager.Views(), views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation()); } @@ -404,7 +404,7 @@ export class PresBox extends ViewBoxBaseComponent const self = this; const resetSelection = action(() => { const presDocView = DocumentManager.Instance.getDocumentView(self.rootDoc); - if (presDocView) SelectionManager.SelectDoc(presDocView, false); + if (presDocView) SelectionManager.SelectView(presDocView, false); self.rootDoc.presStatus = presStatus; self._selectedArray.clear(); selViewCache.forEach(doc => self._selectedArray.set(doc, undefined)); @@ -761,7 +761,7 @@ export class PresBox extends ViewBoxBaseComponent @action selectPres = () => { const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc); - presDocView && SelectionManager.SelectDoc(presDocView, false); + presDocView && SelectionManager.SelectView(presDocView, false); } //Regular click diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index cf9b03308..07439825f 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -144,7 +144,7 @@ export class RichTextMenu extends AntimodeMenu { } componentDidMount() { - this._reaction = reaction(() => SelectionManager.SelectedDocuments(), + this._reaction = reaction(() => SelectionManager.Views(), () => this._delayHide && !(this._delayHide = false) && this.fadeOut(true)); } componentWillUnmount() { @@ -836,7 +836,7 @@ export class RichTextMenu extends AntimodeMenu { if (linkDoc instanceof Doc) { const anchor1 = await Cast(linkDoc.anchor1, Doc); const anchor2 = await Cast(linkDoc.anchor2, Doc); - const currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document; + const currentDoc = SelectionManager.Views().length && SelectionManager.Views()[0].props.Document; if (currentDoc && anchor1 && anchor2) { if (Doc.AreProtosEqual(currentDoc, anchor1)) { return StrCast(anchor2.title); @@ -987,11 +987,11 @@ export class RichTextMenu extends AntimodeMenu {
    , {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => { this.activeFontSize = val; - SelectionManager.SelectedDocuments().map(dv => dv.props.Document._fontSize = val); + SelectionManager.Views().map(dv => dv.props.Document._fontSize = val); })), this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => { this.activeFontFamily = val; - SelectionManager.SelectedDocuments().map(dv => dv.props.Document._fontFamily = val); + SelectionManager.Views().map(dv => dv.props.Document._fontFamily = val); })),
    , this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", () => ({})), diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index d6d500702..02f7ada96 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -150,7 +150,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent this._savedAnnotations.setValue(k, [])); PDFMenu.Instance.fadeOut(true); } - (SelectionManager.SelectedDocuments().length === 1) && this.setupPdfJsViewer(); + (SelectionManager.Views().length === 1) && this.setupPdfJsViewer(); }, { fireImmediately: true }); this._disposers.scrollY = reaction( diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index d5f852c4d..e1ab1d3d3 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1329,7 +1329,7 @@ Scripting.addGlobal(function activePresentationItem() { return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)]; }); Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { - const docs = SelectionManager.SelectedDocuments().map(dv => dv.props.Document). + const docs = SelectionManager.Views().map(dv => dv.props.Document). filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCHOLDER && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null))); return docs.length ? new List(docs) : prevValue; -- cgit v1.2.3-70-g09d2 From 568ede3e32ac0d5cbdec622961ee26af5b4da7eb Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 12:10:44 -0500 Subject: from last - fix to sidebarheight --- src/client/views/MainView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 14da5049e..23c65fa53 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -237,7 +237,7 @@ export class MainView extends React.Component { getPWidth = () => this._panelWidth - this.propertiesWidth(); getPHeight = () => this._panelHeight; - getContentsHeight = () => this._panelHeight - Number(SEARCH_PANEL_HEIGHT.replace("px", "")); + getContentsHeight = () => this._panelHeight; @computed get mainDocView() { return Date: Wed, 16 Dec 2020 15:22:14 -0500 Subject: fixed showing of snapping lines. --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0fb1c0f9c..954934dab 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1406,7 +1406,7 @@ export class CollectionFreeFormView extends CollectionSubView { - (DocumentDecorations.Instance.Interacting || (this.props.layerProvider?.(this.props.Document) === false && SnappingManager.GetIsDragging())) && this.setupDragLines(e.ctrlKey || e.shiftKey); + (DocumentDecorations.Instance.Interacting || (this.props.layerProvider?.(this.props.Document) !== false && SnappingManager.GetIsDragging())) && this.setupDragLines(e.ctrlKey || e.shiftKey); e.stopPropagation(); } @@ -1506,7 +1506,7 @@ export class CollectionFreeFormView extends CollectionSubView
    - {this.layoutDoc["_backgroundGrid-show"] ? this.backgroundGrid : (null)} + {this.layoutDoc["_backgroundGrid-show"] && (!SnappingManager.GetIsDragging() || !Doc.UserDoc().showSnapLines) ? this.backgroundGrid : (null)} Date: Wed, 16 Dec 2020 16:53:05 -0500 Subject: cleaned up some link following code. fixed problem following links from LinkAnchorBox's --- src/client/util/DocumentManager.ts | 36 +---------- src/client/util/LinkManager.ts | 73 +++++++++++++++++++++- src/client/views/MainView.tsx | 5 +- src/client/views/StyleProvider.tsx | 1 - src/client/views/collections/CollectionMapView.tsx | 12 ++-- src/client/views/linking/LinkMenuItem.tsx | 46 ++------------ src/client/views/nodes/DocumentView.tsx | 44 +++---------- src/client/views/nodes/LinkAnchorBox.tsx | 30 ++++----- src/client/views/nodes/LinkDocPreview.tsx | 18 +++--- .../views/nodes/formattedText/FormattedTextBox.tsx | 5 +- .../formattedText/FormattedTextBoxComment.tsx | 2 +- src/client/views/pdf/Annotation.tsx | 12 ++-- 12 files changed, 123 insertions(+), 161 deletions(-) (limited to 'src') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 1c81cf26c..1609e0af7 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -1,14 +1,12 @@ import { action, observable } from 'mobx'; import { Doc, DocListCast, DocListCastAsync, Opt } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; -import { Cast, NumCast, StrCast } from '../../fields/Types'; +import { Cast, NumCast } from '../../fields/Types'; import { returnFalse } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; import { CollectionView } from '../views/collections/CollectionView'; import { DocumentView } from '../views/nodes/DocumentView'; -import { FormattedTextBoxComment } from '../views/nodes/formattedText/FormattedTextBoxComment'; -import { LinkDocPreview } from '../views/nodes/LinkDocPreview'; import { LinkManager } from './LinkManager'; import { Scripting } from './Scripting'; @@ -223,37 +221,5 @@ export class DocumentManager { } } - public async FollowLink(link: Opt, doc: Doc, createViewFunc: CreateViewFunc, zoom = false, currentContext?: Doc, finished?: () => void, traverseBacklink?: boolean) { - LinkDocPreview.TargetDoc = undefined; - FormattedTextBoxComment.linkDoc = undefined; - const linkDocs = link ? [link] : DocListCast(doc.links); - const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor1 - const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor2 - const fwdLinkWithoutTargetView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0); - const backLinkWithoutTargetView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0); - const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView || backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView; - const linkDocList = linkWithoutTargetDoc ? [linkWithoutTargetDoc] : (traverseBacklink === undefined ? firstDocs.concat(secondDocs) : traverseBacklink ? secondDocs : firstDocs); - const followLinks = linkDocList.length ? (doc.isPushpin ? linkDocList : [linkDocList[0]]) : []; - followLinks.forEach(async linkDoc => { - if (linkDoc) { - const target = (doc === linkDoc.anchor1 ? linkDoc.anchor2 : doc === linkDoc.anchor2 ? linkDoc.anchor1 : - (Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc) ? linkDoc.anchor2 : linkDoc.anchor1)) as Doc; - const targetTimecode = (doc === linkDoc.anchor1 ? Cast(linkDoc.anchor2_timecode, "number") : - doc === linkDoc.anchor2 ? Cast(linkDoc.anchor1_timecode, "number") : - (Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc) ? Cast(linkDoc.anchor2_timecode, "number") : Cast(linkDoc.anchor1_timecode, "number"))); - if (target) { - const containerDoc = (await Cast(target.annotationOn, Doc)) || target; - containerDoc._currentTimecode = targetTimecode; - const targetContext = await target?.context as Doc; - const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; - DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "add:right"), finished), targetNavContext, linkDoc, undefined, doc, finished); - } else { - finished?.(); - } - } else { - finished?.(); - } - }); - } } Scripting.addGlobal(function DocFocus(doc: any) { DocumentManager.Instance.getDocumentViews(Doc.GetProto(doc)).map(view => view.props.focus(doc, true)); }); \ No newline at end of file diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 38e81cf99..accf53676 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -1,7 +1,12 @@ +import { computedFn } from "mobx-utils"; import { Doc, DocListCast, Opt } from "../../fields/Doc"; -import { Cast, StrCast } from "../../fields/Types"; +import { BoolCast, Cast, StrCast } from "../../fields/Types"; +import { DocFocusFunc, DocumentViewSharedProps } from "../views/nodes/DocumentView"; +import { FormattedTextBoxComment } from "../views/nodes/formattedText/FormattedTextBoxComment"; +import { LinkDocPreview } from "../views/nodes/LinkDocPreview"; +import { CreateViewFunc, DocumentManager } from "./DocumentManager"; import { SharingManager } from "./SharingManager"; -import { computedFn } from "mobx-utils"; +import { UndoManager } from "./UndoManager"; /* * link doc: @@ -89,4 +94,68 @@ export class LinkManager { if (Doc.AreProtosEqual(anchor, a2.annotationOn as Doc)) return a1; if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc; } + + + // follows a link - if the target is on screen, it highlights/pans to it. + // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place + // depending on the followLinkLocation property of the source (or the link itself as a fallback); + public static FollowLink = async (linkDoc: Opt, sourceDoc: Doc, docViewProps: DocumentViewSharedProps, 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>) => { + const targetFocusAfterDocFocus = () => { + const where = StrCast(sourceDoc.followLinkLocation) || followLoc; + const hackToCallFinishAfterFocus = () => { + finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. + return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false + }; + const addTab = docViewProps.addDocTab(doc, where); + addTab && setTimeout(() => { + const targDocView = DocumentManager.Instance.getFirstDocumentView(doc); + targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, false), undefined, hackToCallFinishAfterFocus); + }); // add the target and focus on it. + return where !== "inPlace" || addTab; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) + }; + if (!sourceDoc.followLinkZoom) { + targetFocusAfterDocFocus(); + } else { + // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target + docViewProps.focus(sourceDoc, BoolCast(sourceDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); + } + }; + await LinkManager.traverseLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docViewProps.ContainingCollectionDoc, batch.end, altKey ? true : undefined); + } + public static async traverseLink(link: Opt, doc: Doc, createViewFunc: CreateViewFunc, zoom = false, currentContext?: Doc, finished?: () => void, traverseBacklink?: boolean) { + LinkDocPreview.TargetDoc = undefined; + FormattedTextBoxComment.linkDoc = undefined; + const linkDocs = link ? [link] : DocListCast(doc.links); + const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor1 + const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor2 + const fwdLinkWithoutTargetView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0); + const backLinkWithoutTargetView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0); + const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView || backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView; + const linkDocList = linkWithoutTargetDoc ? [linkWithoutTargetDoc] : (traverseBacklink === undefined ? firstDocs.concat(secondDocs) : traverseBacklink ? secondDocs : firstDocs); + const followLinks = linkDocList.length ? (doc.isPushpin ? linkDocList : [linkDocList[0]]) : []; + followLinks.forEach(async linkDoc => { + if (linkDoc) { + const target = (doc === linkDoc.anchor1 ? linkDoc.anchor2 : doc === linkDoc.anchor2 ? linkDoc.anchor1 : + (Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc) ? linkDoc.anchor2 : linkDoc.anchor1)) as Doc; + const targetTimecode = (doc === linkDoc.anchor1 ? Cast(linkDoc.anchor2_timecode, "number") : + doc === linkDoc.anchor2 ? Cast(linkDoc.anchor1_timecode, "number") : + (Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc) ? Cast(linkDoc.anchor2_timecode, "number") : Cast(linkDoc.anchor1_timecode, "number"))); + if (target) { + const containerDoc = (await Cast(target.annotationOn, Doc)) || target; + containerDoc._currentTimecode = targetTimecode; + const targetContext = await target?.context as Doc; + const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; + DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "add:right"), finished), targetNavContext, linkDoc, undefined, doc, finished); + } else { + finished?.(); + } + } else { + finished?.(); + } + }); + } + } \ No newline at end of file diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 23c65fa53..0390bdf52 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -578,9 +578,8 @@ export class MainView extends React.Component { {LinkDescriptionPopup.descriptionPopup ? : null} {DocumentLinksButton.EditLink ? : (null)} - {LinkDocPreview.LinkInfo ? : (null)} + {LinkDocPreview.LinkInfo ? : (null)} {this.mainContent} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 83192164f..dd406abed 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -71,7 +71,6 @@ export function DefaultStyleProvider(doc: Opt, props: Opt; @@ -88,7 +88,7 @@ export class CollectionMapView extends CollectionSubView void) => { + await LinkManager.traverseLink(undefined, layout, (doc: Doc, where: string, finished?: () => void) => { this.props.addDocTab(doc, where); finished?.(); }, false, this.props.ContainingCollectionDoc, batch.end, undefined); diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 8e0004c87..50cb064b9 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -13,9 +13,8 @@ import { DragManager } from '../../util/DragManager'; import { Hypothesis } from '../../util/HypothesisUtils'; import { LinkManager } from '../../util/LinkManager'; import { undoBatch } from '../../util/UndoManager'; -import { ContextMenu } from '../ContextMenu'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; -import { DocumentView } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewSharedProps } from '../nodes/DocumentView'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import './LinkMenuItem.scss'; import React = require("react"); @@ -28,7 +27,7 @@ interface LinkMenuItemProps { sourceDoc: Doc; destinationDoc: Doc; showEditor: (linkDoc: Doc) => void; - addDocTab: (document: Doc, where: string) => boolean; + docprops: DocumentViewSharedProps, menuRef: React.Ref; } @@ -110,7 +109,7 @@ export class LinkMenuItem extends React.Component { 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); + LinkManager.FollowLink(this.props.linkDoc, this.props.sourceDoc, this.props.docView.props, false); e.stopPropagation(); } @@ -126,41 +125,6 @@ export class LinkMenuItem extends React.Component { e.stopPropagation(); } - @action - onContextMenu = (e: React.MouseEvent) => { - DocumentLinksButton.EditLink = undefined; - LinkDocPreview.LinkInfo = undefined; - e.preventDefault(); - ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => LinkMenuItem.followDefault(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc, this.props.addDocTab), icon: "arrow-right" }); - ContextMenu.Instance.displayMenu(e.clientX, e.clientY); - } - - - @action - public static followDefault(linkDoc: Doc, sourceDoc: Doc, destinationDoc: Doc, addDocTab: (doc: Doc, where: string) => void) { - DocumentLinksButton.EditLink = undefined; - LinkDocPreview.LinkInfo = undefined; - - if (linkDoc.followLinkLocation === "openExternal" && destinationDoc.type === DocumentType.WEB) { - window.open(`${StrCast(linkDoc.annotationUri)}#annotations:${StrCast(linkDoc.annotationId)}`, '_blank'); - } - - if (linkDoc.followLinkLocation && linkDoc.followLinkLocation !== "default") { - const annotationOn = destinationDoc.annotationOn as Doc; - addDocTab(annotationOn instanceof Doc ? annotationOn : destinationDoc, StrCast(linkDoc.followLinkLocation)); - if (annotationOn) { - setTimeout(() => { - const dv = DocumentManager.Instance.getFirstDocumentView(destinationDoc); - dv?.props.focus(destinationDoc, false); - }); - } - } else { - DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, addDocTab, false); - } - - linkDoc.linksToAnnotation && Hypothesis.scrollToAnnotation(StrCast(linkDoc.annotationId), destinationDoc); - } - @undoBatch @action deleteLink = (): void => { @@ -215,7 +179,7 @@ export class LinkMenuItem extends React.Component {
    LinkDocPreview.LinkInfo = undefined)} onPointerEnter={action(e => this.props.linkDoc && (LinkDocPreview.LinkInfo = { - addDocTab: this.props.addDocTab, + docprops: this.props.docprops, linkSrc: this.props.sourceDoc, linkDoc: this.props.linkDoc, Location: [e.clientX, e.clientY + 20] @@ -260,8 +224,6 @@ export class LinkMenuItem extends React.Component {
    - {/*
    -
    */}
    diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 56982bd89..15ba62e23 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -425,7 +425,7 @@ export class DocumentViewInternal extends DocComponent 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 @@ -785,7 +785,12 @@ export class DocumentViewInternal extends DocComponent (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, props: Opt, property: string): any => this.props.styleProvider?.(doc, props, property + ":anchor"); + anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { + switch (property.split(":")[0]) { + case StyleProp.LinkSource: return this.props.Document; // pass the LinkSource to the LinkAnchorBox + } + return this.props.styleProvider?.(doc, props, property + ":anchor"); + } @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } @@ -930,40 +935,6 @@ export class DocumentView extends React.Component { toggleNativeDimensions = () => this.docView?.toggleNativeDimensions(); contentsActive = () => this.docView?.contentsActive(); - // follows a link - if the target is on screen, it highlights/pans to it. - // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place - // depending on the followLinkLocation property of the source (or the link itself as a fallback); - public static followLinkClick = async (linkDoc: Opt, sourceDoc: Doc, docView: { - focus: DocFocusFunc, - addDocTab: (doc: Doc, where: string) => boolean, - ContainingCollectionDoc?: Doc - }, 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>) => { - const targetFocusAfterDocFocus = () => { - const where = StrCast(sourceDoc.followLinkLocation) || followLoc; - const hackToCallFinishAfterFocus = () => { - finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. - return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false - }; - const addTab = docView.addDocTab(doc, where); - addTab && setTimeout(() => { - const targDocView = DocumentManager.Instance.getFirstDocumentView(doc); - targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, false), undefined, hackToCallFinishAfterFocus); - }); // add the target and focus on it. - return where !== "inPlace" || addTab; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) - }; - if (!sourceDoc.followLinkZoom) { - targetFocusAfterDocFocus(); - } else { - // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target - docView.focus(sourceDoc, BoolCast(sourceDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); - } - }; - await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, false), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); - } - @action public float = () => { const { Document: topDoc, ContainingCollectionView: container } = this.props; const screenXf = container?.screenToLocalTransform(); @@ -1106,7 +1077,6 @@ export class DocumentView extends React.Component { } } - Scripting.addGlobal(function toggleDetail(doc: any, layoutKey: string, otherKey: string = "layout") { const dv = DocumentManager.Instance.getDocumentView(doc); if (dv?.props.Document.layoutKey === layoutKey) dv?.switchViews(otherKey !== "layout", otherKey.replace("layout_", "")); diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index f035fba33..e347d1304 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -1,25 +1,25 @@ +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast } from "../../../fields/Doc"; +import { Doc } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; +import { Id } from "../../../fields/FieldSymbols"; import { makeInterface } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; -import { Utils, setupMoveUpEvents, emptyFunction, OmitKeys } from '../../../Utils'; -import { DocumentManager } from "../../util/DocumentManager"; +import { TraceMobx } from "../../../fields/util"; +import { emptyFunction, setupMoveUpEvents, Utils } from '../../../Utils'; import { DragManager } from "../../util/DragManager"; -import { ViewBoxBaseComponent } from "../DocComponent"; -import "./LinkAnchorBox.scss"; -import { FieldView, FieldViewProps } from "./FieldView"; -import React = require("react"); -import { ContextMenuProps } from "../ContextMenuItem"; +import { LinkManager } from "../../util/LinkManager"; +import { SelectionManager } from "../../util/SelectionManager"; import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; +import { ViewBoxBaseComponent } from "../DocComponent"; import { LinkEditor } from "../linking/LinkEditor"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { SelectionManager } from "../../util/SelectionManager"; -import { TraceMobx } from "../../../fields/util"; -import { Id } from "../../../fields/FieldSymbols"; -import { LinkDocPreview } from "./LinkDocPreview"; import { StyleProp } from "../StyleProvider"; +import { FieldView, FieldViewProps } from "./FieldView"; +import "./LinkAnchorBox.scss"; +import { LinkDocPreview } from "./LinkDocPreview"; +import React = require("react"); const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -74,7 +74,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent { - DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, (doc, where) => this.props.addDocTab(doc, where), false); + LinkManager.FollowLink(this.rootDoc, anchorContainerDoc, this.props, false); this._editing = false; }), 300 - (Date.now() - this._lastTap)); } @@ -136,7 +136,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent LinkDocPreview.LinkInfo = undefined)} onPointerEnter={action(e => LinkDocPreview.LinkInfo = { - addDocTab: this.props.addDocTab, + docprops: this.props, linkSrc: linkSource, linkDoc: this.rootDoc, Location: [e.clientX, e.clientY + 20] diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index c69fb5b33..07b2b6338 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -6,25 +6,24 @@ import { Id } from '../../../fields/FieldSymbols'; import { Cast, FieldValue, NumCast } from "../../../fields/Types"; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse } from "../../../Utils"; import { Docs } from "../../documents/Documents"; -import { DocumentManager } from "../../util/DocumentManager"; +import { LinkManager } from '../../util/LinkManager'; import { Transform } from "../../util/Transform"; import { ContextMenu } from '../ContextMenu'; import { DocumentLinksButton } from './DocumentLinksButton'; -import { DocumentView, StyleProviderFunc } from "./DocumentView"; +import { DocumentView, StyleProviderFunc, DocumentViewSharedProps } from "./DocumentView"; import React = require("react"); interface Props { linkDoc?: Doc; linkSrc?: Doc; href?: string; - styleProvider?: StyleProviderFunc; - addDocTab: (document: Doc, where: string) => boolean; + docprops: DocumentViewSharedProps; location: number[]; } @observer export class LinkDocPreview extends React.Component { static TargetDoc: Doc | undefined; - @observable public static LinkInfo: Opt<{ linkDoc?: Doc; addDocTab: (document: Doc, where: string) => boolean, linkSrc: Doc; href?: string; Location: number[] }>; + @observable public static LinkInfo: Opt<{ linkDoc?: Doc; linkSrc: Doc; href?: string; Location: number[], docprops: DocumentViewSharedProps }>; @observable _targetDoc: Opt; @observable _toolTipText = ""; _editRef = React.createRef(); @@ -42,7 +41,7 @@ export class LinkDocPreview extends React.Component { async followDefault() { DocumentLinksButton.EditLink = undefined; LinkDocPreview.LinkInfo = undefined; - this._targetDoc ? DocumentManager.Instance.FollowLink(this.props.linkDoc, this._targetDoc, (doc, where) => this.props.addDocTab(doc, where), false) : null; + this._targetDoc && LinkManager.FollowLink(this.props.linkDoc, this._targetDoc, this.props.docprops, false); } componentWillUnmount() { LinkDocPreview.TargetDoc = undefined; } @@ -75,10 +74,9 @@ export class LinkDocPreview extends React.Component { } pointerDown = (e: React.PointerEvent) => { if (this.props.linkDoc && this.props.linkSrc) { - DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.linkSrc, - (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "add" : followLinkLocation)); + LinkManager.FollowLink(this.props.linkDoc, this.props.linkSrc, this.props.docprops, false); } else if (this.props.href) { - this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { _fitWidth: true, title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right"); + this.props.docprops?.addDocTab(Docs.Create.WebDocument(this.props.href, { _fitWidth: true, title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right"); } } width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225)); @@ -113,7 +111,7 @@ export class LinkDocPreview extends React.Component { focus={emptyFunction} whenActiveChanged={returnFalse} bringToFront={returnFalse} - styleProvider={this.props.styleProvider} />; + styleProvider={this.props.docprops?.styleProvider} />; } render() { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 0bb483b41..2b9910dfb 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -57,7 +57,7 @@ import { FieldView, FieldViewProps } from "../FieldView"; import "./FormattedTextBox.scss"; import { FormattedTextBoxComment, formattedTextBoxCommentPlugin, findLinkMark } from './FormattedTextBoxComment'; import React = require("react"); -import { DocumentManager } from '../../../util/DocumentManager'; +import { LinkManager } from '../../../util/LinkManager'; import { CollectionStackingView } from '../../collections/CollectionStackingView'; import { CollectionViewType, CollectionViewProps } from '../../collections/CollectionView'; import { SnappingManager } from '../../../util/SnappingManager'; @@ -1331,8 +1331,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) { this.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "add" : "add:right"); } else { - DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, this.props.Document, - (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "add" : followLinkLocation)); + LinkManager.FollowLink(FormattedTextBoxComment.linkDoc, this.props.Document, this.props, false); } } diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index c6be25dc2..038a91aa3 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -116,7 +116,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.altKey); + target && LinkManager.FollowLink(linkDoc, textBox.dataDoc, textBox.props, e.altKey); } } } diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index 20ea7bfe4..5ef57f986 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -1,14 +1,14 @@ import React = require("react"); import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, HeightSym, WidthSym, Field, Opt } from "../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; -import { Cast, FieldValue, BoolCast, NumCast, StrCast, PromiseValue } from "../../../fields/Types"; -import { DocumentManager } from "../../util/DocumentManager"; -import { PDFMenu } from "./PDFMenu"; -import "./Annotation.scss"; +import { BoolCast, Cast, FieldValue, NumCast, PromiseValue, StrCast } from "../../../fields/Types"; +import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; +import "./Annotation.scss"; +import { PDFMenu } from "./PDFMenu"; interface IAnnotationProps { anno: Doc; @@ -119,7 +119,7 @@ class RegionAnnotation extends React.Component { e.persist(); e.stopPropagation(); PromiseValue(this.props.document.group).then(annoGroup => annoGroup instanceof Doc && - DocumentManager.Instance.FollowLink(undefined, annoGroup, (doc, followLinkLocation) => this.props.addDocTab(doc, e.ctrlKey ? "add" : followLinkLocation), false, undefined, + LinkManager.traverseLink(undefined, annoGroup, (doc, followLinkLocation) => this.props.addDocTab(doc, e.ctrlKey ? "add" : followLinkLocation), false, undefined, () => this.props.select(false)) ); } -- cgit v1.2.3-70-g09d2 From f5527e423c3eaa104bec4904f6c778cf1f58a496 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 18:39:00 -0500 Subject: moved float() to collectionfreeformdocview --- src/client/views/GlobalKeyHandler.ts | 2 +- src/client/views/collections/CollectionMenu.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 25 ++++++++++++ src/client/views/nodes/DocumentView.tsx | 45 +++------------------- 4 files changed, 33 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 3311a4dcc..c38842c4f 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -180,7 +180,7 @@ export class KeyManager { case "Æ’": case "f": const dv = SelectionManager.Views()?.[0]; - UndoManager.RunInBatch(() => dv?.float(), "float"); + UndoManager.RunInBatch(() => dv.props.CollectionFreeFormDocumentView?.().float(), "float"); } return { diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3839dff8b..85fcf6384 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -514,7 +514,7 @@ export class CollectionViewBaseChrome extends React.ComponentToggle Overlay Layer
    } placement="bottom"> } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 727b25d1b..99a21fb0c 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -17,6 +17,7 @@ import { DocumentView, DocumentViewProps } from "./DocumentView"; import { FieldViewProps } from "./FieldView"; import React = require("react"); import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; +import { SelectionManager } from "../../util/SelectionManager"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; @@ -126,6 +127,30 @@ export class CollectionFreeFormDocumentView extends DocComponent { + const { Document: topDoc, ContainingCollectionView: container } = this.props; + const screenXf = container?.screenToLocalTransform(); + if (screenXf) { + SelectionManager.DeselectAll(); + 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]; + this.props.removeDocument?.(topDoc); + this.props.addDocTab(topDoc, "inParent"); + } else { + const spt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const fpt = screenXf.transformPoint(spt[0], spt[1]); + topDoc.z = 1; + topDoc.x = fpt[0]; + topDoc.y = fpt[1]; + } + setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); + } + } + + nudge = (x: number, y: number) => { this.props.Document.x = NumCast(this.props.Document.x) + x; this.props.Document.y = NumCast(this.props.Document.y) + y; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 15ba62e23..276ab35f1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -10,7 +10,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { emptyFunction, OmitKeys, returnFalse, Utils, returnVal } 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'; @@ -31,17 +31,15 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { DocComponent } from "../DocComponent"; import { EditableView } from '../EditableView'; import { InkStrokeProperties } from '../InkStrokeProperties'; -import { StyleLayers, StyleProp, testDocProps } from "../StyleProvider"; +import { StyleLayers, StyleProp } 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"); export type DocAfterFocusFunc = (notFocused: boolean) => boolean; @@ -149,10 +147,6 @@ export class DocumentViewInternal extends DocComponent): any => { this.removeMoveListeners(); this.removeEndListeners(); @@ -352,6 +345,7 @@ export class DocumentViewInternal extends DocComponent setTimeout(action(() => ffview && (ffview().props.CollectionFreeFormView.ChildDrag = undefined)))); // this needs to happen after the drop event is processed. } } + onKeyDown = (e: React.KeyboardEvent) => { if (e.altKey && !e.nativeEvent.cancelBubble) { e.stopPropagation(); @@ -791,17 +785,13 @@ export class DocumentViewInternal extends DocComponent !d.hidden && this.isNonTemporalLink(d)); return filtered.map((d, i) =>
    @@ -816,6 +806,7 @@ export class DocumentViewInternal extends DocComponent
    ); } + captionStyleProvider = (doc: Opt, props: Opt, property: string) => this.props?.styleProvider?.(doc, props, property + ":caption"); @computed get innards() { TraceMobx(); @@ -856,7 +847,6 @@ export class DocumentViewInternal extends DocComponent; } - @computed get renderDoc() { TraceMobx(); if (!(this.props.Document instanceof Doc) || GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate || this.hidden) return null; @@ -935,29 +925,6 @@ export class DocumentView extends React.Component { toggleNativeDimensions = () => this.docView?.toggleNativeDimensions(); contentsActive = () => this.docView?.contentsActive(); - @action public float = () => { - const { Document: topDoc, ContainingCollectionView: container } = this.props; - const screenXf = container?.screenToLocalTransform(); - if (screenXf) { - SelectionManager.DeselectAll(); - 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]; - this.props.removeDocument?.(topDoc); - this.props.addDocTab(topDoc, "inParent"); - } else { - const spt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - const fpt = screenXf.transformPoint(spt[0], spt[1]); - topDoc.z = 1; - topDoc.x = fpt[0]; - topDoc.y = fpt[1]; - } - setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); - } - } - get Document() { return this.props.Document; } get topMost() { return this.props.renderDepth === 0; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } -- cgit v1.2.3-70-g09d2 From 0fbfb06c499d2ee52b086427cbf1c5431fadfad9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 21:39:47 -0500 Subject: simplified DocumentView a bit more. cleaned up other code. --- src/Utils.ts | 8 ++ src/client/views/GestureOverlay.tsx | 3 +- src/client/views/PropertiesButtons.tsx | 20 +-- src/client/views/PropertiesView.tsx | 2 +- src/client/views/StyleProvider.tsx | 1 - .../CollectionFreeFormLinkView.scss | 1 - src/client/views/nodes/DocumentView.tsx | 141 ++++++--------------- src/pen-gestures/GestureUtils.ts | 1 - 8 files changed, 52 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index 1a00c0bfb..852a00406 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -592,6 +592,14 @@ export function lightOrDark(color: any) { } } +export function isTarget(x: number, y: number, target: HTMLDivElement | null) { + let entered = false; + for (let child = document.elementFromPoint(x, y); !entered && child; child = child.parentElement) { + entered = entered || child === target; + } + return entered; +} + export function setupMoveUpEvents( target: object, e: React.PointerEvent, diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 3f57d3eb9..524462401 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -550,8 +550,7 @@ export class GestureOverlay extends Touchable { detail: { points: this._points, gesture: GestureUtils.Gestures.Line, - bounds: B, - callbackFn: callback + bounds: B } }); target1?.dispatchEvent(ge); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index bc3be4076..4413d28f5 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -326,20 +326,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value); SelectionManager.Views().forEach(dv => { - if (value === "nothing") { - dv.docView?.noOnClick(); - } else if (value === "enterPortal") { - dv.docView?.noOnClick(); - dv.docView?.makeIntoPortal(); - } else if (value === "toggleDetail") { - dv.docView?.noOnClick(); - dv.docView?.toggleDetail(); - } else if (value === "linkInPlace") { - dv.docView?.noOnClick(); - dv.toggleFollowLink("inPlace", true, false); - } else if (value === "linkOnRight") { - dv.docView?.noOnClick(); - dv.toggleFollowLink("add:right", false, false); + dv.docView?.noOnClick(); + switch (value) { + case "enterPortal": dv.docView?.makeIntoPortal(); break; + case "toggleDetail": dv.docView?.toggleDetail(); break; + case "linkInPlace": dv.docView?.toggleFollowLink("inPlace", true, false); break; + case "linkOnRight": dv.docView?.toggleFollowLink("add:right", false, false); break; } }); } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 32342075c..4aeb4e63a 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -119,7 +119,7 @@ export class PropertiesView extends React.Component { if (this.dataDoc && this.selectedDoc) { const ids: { [key: string]: string } = {}; const docs = SelectionManager.Views().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : - SelectionManager.Views().map(dv => this.layoutFields ? Doc.Layout(dv.layoutDoc) : dv.dataDoc); + SelectionManager.Views().map(dv => this.layoutFields ? dv.layoutDoc : dv.dataDoc); docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key))); const rows: JSX.Element[] = []; for (const key of Object.keys(ids).slice().sort()) { diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index dd406abed..312cfc73e 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -6,7 +6,6 @@ import { Doc, Opt, StrListCast } from "../../fields/Doc"; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; -import { returnFalse } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { SnappingManager } from '../util/SnappingManager'; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss index 8cbda310a..858719a08 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss @@ -1,7 +1,6 @@ .collectionfreeformlinkview-linkLine { stroke: black; opacity: 0.8; - pointer-events: all; stroke-width: 3px; transition: opacity 0.5s ease-in; fill: transparent; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 276ab35f1..b9ca460b9 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -10,7 +10,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { emptyFunction, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; +import { emptyFunction, isTarget as hasDescendantTarget, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -119,7 +119,6 @@ export class DocumentViewInternal extends DocComponent(); private _timeout: NodeJS.Timeout | undefined; private _dropDisposer?: DragManager.DragDropDisposer; - private _gestureEventDisposer?: GestureUtils.GestureEventDisposer; private _holdDisposer?: InteractionUtils.MultiTouchEventDisposer; protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer; @@ -132,6 +131,7 @@ export class DocumentViewInternal extends DocComponent { - // continue if the event hasn't been canceled AND we are using a moues or this is has an onClick or onDragStart function (meaning it is a button document) + // continue if the event hasn't been canceled AND we are using a mouse or this has an onClick or onDragStart function (meaning it is a button document) if (!(InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE) || Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) { if (!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { e.stopPropagation(); @@ -470,7 +468,7 @@ export class DocumentViewInternal extends DocComponent 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); @@ -496,24 +494,6 @@ export class DocumentViewInternal extends DocComponent { - switch (ge.gesture) { - case GestureUtils.Gestures.Line: - ge.callbackFn && ge.callbackFn(this.props.Document); - e.stopPropagation(); - break; - } - } - - @undoBatch @action - deleteClicked = (): void => { - if (CurrentUserUtils.ActiveDashboard === this.props.Document) { - alert("Can't delete the active dashboard"); - } else { - this.props.removeDocument?.(this.props.Document); - } - } - @undoBatch @action toggleFollowLink = (location: Opt, zoom: boolean, setPushpin: boolean): void => { this.Document.ignoreClick = false; @@ -553,10 +533,9 @@ export class DocumentViewInternal extends DocComponent { - this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`); - } + @undoBatch deleteClicked = () => this.props.removeDocument?.(this.props.Document); + @undoBatch toggleDetail = () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`); + @undoBatch toggleLockPosition = () => this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { @@ -574,16 +553,6 @@ export class DocumentViewInternal extends DocComponent { - Doc.toggleNativeDimensions(this.layoutDoc, this.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); - } - - @undoBatch - toggleLockPosition = (): void => { - this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; - } - @undoBatch @action makeIntoPortal = async () => { @@ -597,14 +566,6 @@ export class DocumentViewInternal extends DocComponent { - const alias = Doc.MakeAlias(this.props.Document); - alias.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width); - alias.y = NumCast(this.props.Document.y) + 30; - this.props.addDocument?.(alias); - } - @action onContextMenu = (e?: React.MouseEvent, pageX?: number, pageY?: number) => { if (e && this.rootDoc._hideContextMenu && Doc.UserDoc().noviceMode) { @@ -618,16 +579,13 @@ export class DocumentViewInternal extends DocComponent 3 || Math.abs(this._downY - e?.clientY) > 3) { - e?.preventDefault(); - return; - } + if (!navigator.userAgent.includes("Mozilla") && (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3)) { + return; } - e.preventDefault(); } const cm = ContextMenu.Instance; @@ -693,7 +651,6 @@ export class DocumentViewInternal extends DocComponent SharingManager.Instance.open(this.props.DocumentView), icon: "users" }); - //moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); @@ -707,8 +664,7 @@ export class DocumentViewInternal extends DocComponent console.log(this.props.Document), icon: "hand-point-right" }); cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" }); - runInAction(() => { - if (!this.topMost) { - e?.stopPropagation(); // DocumentViews should stop propagation of this event - } - cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); - !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. - }); + if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event + cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); + !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView, false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. } rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; @@ -743,7 +695,7 @@ export class DocumentViewInternal extends DocComponent {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} - {this.hideLinkButton ? - (null) : - } -
    - ); + {this.hideLinkButton ? (null) : + } +
    ; } // used to decide whether a link anchor view should be created or not. @@ -780,10 +730,7 @@ export class DocumentViewInternal extends DocComponent this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { - switch (property.split(":")[0]) { - case StyleProp.LinkSource: return this.props.Document; // pass the LinkSource to the LinkAnchorBox - } - return this.props.styleProvider?.(doc, props, property + ":anchor"); + return property !== StyleProp.LinkSource ? this.props.styleProvider?.(doc, props, property + ":anchor") : this.props.Document; // pass the LinkSource to the LinkAnchorBox } @computed get directLinks() { TraceMobx(); return LinkManager.Instance.getAllDirectLinks(this.rootDoc); } @computed get allLinks() { TraceMobx(); return LinkManager.Instance.getAllRelatedLinks(this.rootDoc); } @@ -813,7 +760,7 @@ export class DocumentViewInternal extends DocComponent `} onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> -
    ); - const titleView = (!showTitle ? (null) : +
    ; + const titleView = !showTitle ? (null) :
    users.user.email === this.dataDoc.author)?.userColor || (this.rootDoc.type === DocumentType.RTF ? StrCast(Doc.SharingDoc().userColor) : "rgba(0,0,0,0.4)"), pointerEvents: this.onClickHandler || this.Document.ignoreClick ? "none" : undefined, }}> @@ -839,7 +786,7 @@ export class DocumentViewInternal extends DocComponent Field.toString((this.dataDoc || this.props.Document)[showTitle.split(";")[0]] as any as Field)} SetValue={undoBatch((value) => showTitle.includes("Date") ? true : (Doc.GetProto(this.dataDoc || this.props.Document)[showTitle] = value) ? true : true)} /> -
    ); +
    ; return this.props.hideTitle || (!showTitle && !showCaption) ? this.contents :
    @@ -878,29 +825,21 @@ export class DocumentViewInternal extends DocComponent !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))} - onPointerLeave={action(e => { - let entered = false; - for (let child = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y); !entered && child; child = child.parentElement) { - entered = entered || child === this.ContentDiv; - } - !entered && Doc.UnBrushDoc(this.props.Document); - })} + onPointerEnter={e => !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document)} + onPointerLeave={e => hasDescendantTarget(e.nativeEvent.x, e.nativeEvent.y, this.ContentDiv) && Doc.UnBrushDoc(this.props.Document)} style={{ borderRadius: this.borderRounding, pointerEvents: this.pointerEvents, outline: highlighting && !this.borderRounding ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : "solid 0px", border: highlighting && this.borderRounding && highlightStyle === "dashed" ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined, boxShadow, - }} - > + }}> {PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc}
    ; } @@ -915,32 +854,23 @@ export class DocumentView extends React.Component { @observable LinkBeingCreated: Opt; // see DocumentLinksButton for explanation of how this works @observable public docView: DocumentViewInternal | undefined | null; + get Document() { return this.props.Document; } + get topMost() { return this.props.renderDepth === 0; } get rootDoc() { return this.docView?.rootDoc || this.Document; } get dataDoc() { return this.docView?.dataDoc || this.Document; } get finalLayoutKey() { return this.docView?.finalLayoutKey || "layout"; } get ContentDiv() { return this.docView?.ContentDiv; } get allLinks() { return this.docView?.allLinks || []; } get LayoutFieldKey() { return this.docView?.LayoutFieldKey || "layout"; } - toggleFollowLink = (location: Opt, zoom: boolean, setPushpin: boolean) => this.docView?.toggleFollowLink(location, zoom, setPushpin); - toggleNativeDimensions = () => this.docView?.toggleNativeDimensions(); - contentsActive = () => this.docView?.contentsActive(); - get Document() { return this.props.Document; } - get topMost() { return this.props.renderDepth === 0; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } - @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); } @computed get nativeScaling() { - const nativeW = this.nativeWidth; - const nativeH = this.nativeHeight; - let scaling = 1; - if (nativeW && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / nativeH > this.props.PanelWidth() / nativeW)) { - scaling = this.props.PanelWidth() / nativeW; // width-limited or fitWidth - } else if (nativeW && nativeH) { - scaling = this.props.PanelHeight() / nativeH; // height-limited + if (this.nativeWidth && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / this.nativeHeight > this.props.PanelWidth() / this.nativeWidth)) { + return this.props.PanelWidth() / this.nativeWidth; // width-limited or fitWidth } - return scaling; + return this.nativeWidth && this.nativeHeight ? this.props.PanelHeight() / this.nativeHeight : 1; // height-limited or unscaled } @computed get panelWidth() { return this.nativeWidth ? this.nativeWidth * this.nativeScaling : this.props.PanelWidth(); } @@ -949,16 +879,17 @@ export class DocumentView extends React.Component { if (this.props.Document._fitWidth) { return Math.min(this.props.PanelHeight(), NumCast(this.props.Document.scrollHeight, this.props.PanelHeight())); } - else return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); + return Math.min(this.props.PanelHeight(), this.nativeHeight * this.nativeScaling); } return this.props.PanelHeight(); } - @computed get Xshift() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } @computed get YShift() { return this.nativeWidth && this.nativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.YShift; } + toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); + contentsActive = () => this.docView?.contentsActive(); getBounds = () => { if (!this.docView || !this.docView.ContentDiv || this.docView.props.renderDepth === 0 || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) { return undefined; diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 20e14a68d..e7cc89697 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -8,7 +8,6 @@ export namespace GestureUtils { readonly gesture: Gestures, readonly points: PointData[], readonly bounds: Rect, - readonly callbackFn?: Function, readonly text?: any ) { } } -- cgit v1.2.3-70-g09d2 From 5bbc8dfe46a7bb2a9e1b09a4d67ed68a7533ab78 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 22:35:44 -0500 Subject: cleaned up removing frame animation fields --- src/client/util/InteractionUtils.tsx | 9 +-- .../collectionFreeForm/CollectionFreeFormView.tsx | 90 ++++++---------------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- 3 files changed, 26 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index f58277717..01d00db30 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -364,12 +364,9 @@ export namespace InteractionUtils { export function IsType(e: PointerEvent | React.PointerEvent, type: string): boolean { switch (type) { // pen and eraser are both pointer type 'pen', but pen is button 0 and eraser is button 5. -syip2 - case PENTYPE: - return e.pointerType === PENTYPE && (e.button === -1 || e.button === 0); - case ERASERTYPE: - return e.pointerType === PENTYPE && e.button === (e instanceof PointerEvent ? ERASER_BUTTON : ERASER_BUTTON); - default: - return e.pointerType === type; + case PENTYPE: return e.pointerType === PENTYPE && (e.button === -1 || e.button === 0); + case ERASERTYPE: return e.pointerType === PENTYPE && e.button === (e instanceof PointerEvent ? ERASER_BUTTON : ERASER_BUTTON); + default: return e.pointerType === type; } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 954934dab..d2b3ed53e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -108,6 +108,7 @@ export class CollectionFreeFormView extends CollectionSubView newBox[field]); + CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[`${field}-indexed`]); + CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[field]); delete newBox.activeFrame; - newBox.x = x; - newBox.y = y; - newBox._width = w; - newBox._height = h; + CollectionFreeFormDocumentView.animFields.forEach((field, i) => field !== opacity && (newBox[field] = vals[i])); } } if (this.Document._currentFrame !== undefined && !this.props.isAnnotationOverlay) { @@ -311,13 +298,9 @@ export class CollectionFreeFormView extends CollectionSubView { const [xp, yp] = this.getTransform().transformPoint(de.x, de.y); - if (this.isAnnotationOverlay !== true && de.complete.linkDragData) { - return this.internalLinkDrop(e, de, de.complete.linkDragData, xp, yp); - } else if (de.complete.annoDragData?.dropDocument && super.onInternalDrop(e, de)) { - return this.internalPdfAnnoDrop(e, de.complete.annoDragData, xp, yp); - } else if (de.complete.docDragData?.droppedDocuments.length && this.internalDocDrop(e, de, de.complete.docDragData, xp, yp)) { - return true; - } + if (this.isAnnotationOverlay !== true && de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData, xp, yp); + if (de.complete.annoDragData?.dropDocument && super.onInternalDrop(e, de)) return this.internalPdfAnnoDrop(e, de.complete.annoDragData, xp, yp); + if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData, xp, yp); return false; } @@ -402,10 +385,10 @@ export class CollectionFreeFormView extends CollectionSubView pair.layout); if (this.props.Document._useClusters) { - this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)); + this._clusterSets.forEach(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)); const preferredInd = NumCast(doc.cluster); doc.cluster = -1; - this._clusterSets.map((set, i) => set.map(member => { + this._clusterSets.forEach((set, i) => set.forEach(member => { if (doc.cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && Doc.overlapping(doc, member, this._clusterDistance)) { doc.cluster = i; } @@ -413,7 +396,7 @@ export class CollectionFreeFormView extends CollectionSubView preferredInd && (!this._clusterSets[preferredInd] || !this._clusterSets[preferredInd].filter(member => Doc.IndexOf(member, childLayouts) !== -1).length)) { doc.cluster = preferredInd; } - this._clusterSets.map((set, i) => { + this._clusterSets.forEach((set, i) => { if (doc.cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) { doc.cluster = i; } @@ -434,7 +417,7 @@ export class CollectionFreeFormView extends CollectionSubView doc && this.updateCluster(doc), 0); + setTimeout(() => doc && this.updateCluster(doc)); } else { // choose a cluster color from a palette const colors = ["#da42429e", "#31ea318c", "rgba(197, 87, 20, 0.55)", "#4a7ae2c4", "rgba(216, 9, 255, 0.5)", "#ff7601", "#1dffff", "yellow", "rgba(27, 130, 49, 0.55)", "rgba(0, 0, 0, 0.268)"]; @@ -455,13 +438,6 @@ export class CollectionFreeFormView extends CollectionSubView FieldValue(sd.color) as string); - sets.forEach((st: string, i: number) => { - const words = st.split(","); - words.forEach(word => { - this._wordPalette.set(word, colors[i]); - }); - }); + sets.forEach((st: string, i: number) => st.split(",").forEach(word => this._wordPalette.set(word, colors[i]))); } const inks = this.getActiveDocuments().filter(doc => { if (doc.type === "ink") { @@ -627,25 +592,20 @@ export class CollectionFreeFormView extends CollectionSubView { - if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) return; - - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - this.removeMoveListeners(); - this.removeEndListeners(); + if (!InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) { + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + this.removeMoveListeners(); + this.removeEndListeners(); + } } onClick = (e: React.MouseEvent) => { if (this.layoutDoc.targetScale && (Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) { - if (Date.now() - this._lastTap < 300) { - runInAction(() => { - DocumentLinksButton.StartLink = undefined; - DocumentLinksButton.StartLinkView = undefined; - }); - const docpt = this.getTransform().transformPoint(e.clientX, e.clientY); - this.scaleAtPt(docpt, 1); + if (Date.now() - this._lastTap < 300) { // reset zoom of freeform view to 1-to-1 on a double click + runInAction(() => DocumentLinksButton.StartLink = DocumentLinksButton.StartLinkView = undefined); + this.scaleAtPt(this.getTransform().transformPoint(e.clientX, e.clientY), 1); e.stopPropagation(); e.preventDefault(); } @@ -655,9 +615,6 @@ export class CollectionFreeFormView extends CollectionSubView { - // bcz: theres should be a better way of doing these than referencing these static instances directly - MarqueeOptionsMenu.Instance?.fadeOut(true);// I think it makes sense for the marquee menu to go away when panned. -syip2 - const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); this.setPan((this.Document._panX || 0) - dx, (this.Document._panY || 0) - dy, undefined, true); this._lastX = e.clientX; @@ -963,7 +920,6 @@ export class CollectionFreeFormView extends CollectionSubView this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false; @@ -1227,7 +1182,6 @@ export class CollectionFreeFormView extends CollectionSubView(Document) { - static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; // fields that are configured to be animatable using animation frames + public static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; // fields that are configured to be animatable using animation frames @observable _animPos: number[] | undefined = undefined; @observable _contentView: DocumentView | undefined | null; random(min: number, max: number) { // min should not be equal to max -- cgit v1.2.3-70-g09d2 From 25df5c6ebc3e23d4c3dc8eaaded0eda9d9956031 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 22:47:36 -0500 Subject: from last --- src/client/views/collections/CollectionView.tsx | 2 -- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index bea5ac2ed..83c639871 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -39,8 +39,6 @@ import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; import { ScriptField } from '../../../fields/ScriptField'; -import { StyleProp } from '../StyleProvider'; -import { SnappingManager } from '../../util/SnappingManager'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3c29e0043..0823fc83a 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -7,8 +7,11 @@ import { listSpec } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; -import { numberRange, returnOne } from "../../../Utils"; +import { numberRange } from "../../../Utils"; +import { DocumentManager } from "../../util/DocumentManager"; +import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; +import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { DocComponent } from "../DocComponent"; import { InkingStroke } from "../InkingStroke"; import { StyleProp } from "../StyleProvider"; @@ -16,8 +19,6 @@ import "./CollectionFreeFormDocumentView.scss"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import { FieldViewProps } from "./FieldView"; import React = require("react"); -import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; -import { SelectionManager } from "../../util/SelectionManager"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; -- cgit v1.2.3-70-g09d2 From b19ccabeea7558e9991571063cc473f381af63fc Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 23:00:15 -0500 Subject: from last --- src/client/views/MainView.tsx | 3 +-- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 10 ++-------- 3 files changed, 4 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 0390bdf52..dbb449cbe 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -501,7 +501,6 @@ export class MainView extends React.Component { ; } - select = (ctrlPressed: boolean) => { }; @computed get search() { TraceMobx(); @@ -512,7 +511,7 @@ export class MainView extends React.Component { dropAction="move" isSelected={returnTrue} active={returnTrue} - select={this.select} + select={returnTrue} addDocument={undefined} addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d2b3ed53e..f934fcd92 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -183,7 +183,7 @@ export class CollectionFreeFormView extends CollectionSubView delete newBox[`${field}-indexed`]); CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[field]); delete newBox.activeFrame; - CollectionFreeFormDocumentView.animFields.forEach((field, i) => field !== opacity && (newBox[field] = vals[i])); + CollectionFreeFormDocumentView.animFields.forEach((field, i) => field !== "opacity" && (newBox[field] = vals[i])); } } if (this.Document._currentFrame !== undefined && !this.props.isAnnotationOverlay) { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 0823fc83a..bfb6e8fc8 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -37,12 +37,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { if (doc.appearFrame === undefined) doc.appearFrame = currTimecode; if (!doc["opacity-indexed"]) { // opacity is unlike other fields because it's value should not be undefined before it appears to enable it to fade-in - const olist = new List(numberRange(currTimecode + 1).map(t => !doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)); - doc["opacity-indexed"] = olist; + doc["opacity-indexed"] = new List(numberRange(currTimecode + 1).map(t => !doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)); } CollectionFreeFormDocumentView.animFields.forEach(val => doc[val] = ComputedField.MakeInterpolated(val, "activeFrame", doc, currTimecode)); doc.activeFrame = ComputedField.MakeFunction("self.context?._currentFrame||0"); -- cgit v1.2.3-70-g09d2 From 953068d7f2653d0d219246c07c5183ca8ffce3ea Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 23:12:55 -0500 Subject: fixed errors with linkmenu props --- src/client/util/DocumentManager.ts | 2 +- src/client/views/DocumentDecorations.tsx | 14 ++++---------- src/client/views/MainView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- src/client/views/linking/LinkMenu.tsx | 6 +++--- src/client/views/linking/LinkMenuGroup.tsx | 6 +++--- src/client/views/linking/LinkMenuItem.tsx | 2 +- 7 files changed, 14 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 1609e0af7..1f2dd350b 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -49,7 +49,7 @@ export class DocumentManager { index !== -1 && this.DocumentViews.splice(index, 1); this.LinkedDocumentViews.slice().forEach(action((pair, i) => pair.a === view || pair.b === view ? this.LinkedDocumentViews.splice(i, 1) : null)); - }) + }); //gets all views public getDocumentViewsById(id: string) { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index eed77b398..372dc5456 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -10,7 +10,7 @@ import { InkField } from "../../fields/InkField"; import { ScriptField } from '../../fields/ScriptField'; import { Cast, NumCast } from "../../fields/Types"; import { GetEffectiveAcl } from '../../fields/util'; -import { emptyFunction, returnFalse, returnVal, setupMoveUpEvents } from "../../Utils"; +import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils"; import { Docs, DocUtils } from "../documents/Documents"; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; @@ -180,20 +180,14 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b @undoBatch @action onIconifyClick = (e: PointerEvent): void => { - if (e.button === 0) { - SelectionManager.Views().forEach(dv => dv?.iconify()); - } + (e.button === 0) && SelectionManager.Views().forEach(dv => dv?.iconify()); SelectionManager.DeselectAll(); } @action onSelectorUp = (e: React.PointerEvent): void => { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e) => { - const selDoc = SelectionManager.Views()?.[0]; - if (selDoc) { - selDoc.props.ContainingCollectionView?.props.select(false); - } - })); + setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e) => + SelectionManager.Views()?.[0]?.props.ContainingCollectionView?.props.select(false))); } @action diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index dbb449cbe..5eb8429f0 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -576,7 +576,7 @@ export class MainView extends React.Component { {this.search} {LinkDescriptionPopup.descriptionPopup ? : null} - {DocumentLinksButton.EditLink ? : (null)} + {DocumentLinksButton.EditLink ? : (null)} {LinkDocPreview.LinkInfo ? : (null)} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index f51c745bb..93d3be1fc 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -65,7 +65,7 @@ export interface TreeViewProps { whenActiveChanged: (isActive: boolean) => void; } -let treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("px", "")); } +const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("px", "")); }; @observer /** diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 5fab81ba7..b32022024 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; import { LinkManager } from "../../util/LinkManager"; import { DocumentLinksButton } from "../nodes/DocumentLinksButton"; -import { DocumentView } from "../nodes/DocumentView"; +import { DocumentView, DocumentViewSharedProps } from "../nodes/DocumentView"; import { LinkDocPreview } from "../nodes/LinkDocPreview"; import { LinkEditor } from "./LinkEditor"; import './LinkMenu.scss'; @@ -13,7 +13,7 @@ import React = require("react"); interface Props { docView: DocumentView; changeFlyout: () => void; - addDocTab: (document: Doc, where: string) => boolean; + docprops: DocumentViewSharedProps; } @observer @@ -67,7 +67,7 @@ export class LinkMenu extends React.Component { group={group[1]} groupType={group[0]} showEditor={action(linkDoc => this._editingLink = linkDoc)} - addDocTab={this.props.addDocTab} />); + docprops={this.props.docprops} />); return linkItems.length ? linkItems : [

    No links have been created yet. Drag the linking button onto another document to create a link.

    ]; } diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index e53655fd3..7db908393 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -3,7 +3,7 @@ import { Doc } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { Cast } from "../../../fields/Types"; import { LinkManager } from "../../util/LinkManager"; -import { DocumentView } from "../nodes/DocumentView"; +import { DocumentView, DocumentViewSharedProps } from "../nodes/DocumentView"; import './LinkMenu.scss'; import { LinkMenuItem } from "./LinkMenuItem"; import React = require("react"); @@ -13,7 +13,7 @@ interface LinkMenuGroupProps { group: Doc[]; groupType: string; showEditor: (linkDoc: Doc) => void; - addDocTab: (document: Doc, where: string) => boolean; + docprops: DocumentViewSharedProps; docView: DocumentView; } @@ -31,7 +31,7 @@ export class LinkMenuGroup extends React.Component { if (destination && this.props.sourceDoc) { return void; - docprops: DocumentViewSharedProps, + docprops: DocumentViewSharedProps; menuRef: React.Ref; } -- cgit v1.2.3-70-g09d2 From f4f4cb6b3a639c3e1c0d291f1d290e80097cfa06 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 16 Dec 2020 23:30:57 -0500 Subject: fixed unbrushing docs --- src/Utils.ts | 2 +- src/client/views/nodes/DocumentView.tsx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index 852a00406..f160df6f7 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -592,7 +592,7 @@ export function lightOrDark(color: any) { } } -export function isTarget(x: number, y: number, target: HTMLDivElement | null) { +export function hasDescendantTarget(x: number, y: number, target: HTMLDivElement | null) { let entered = false; for (let child = document.elementFromPoint(x, y); !entered && child; child = child.parentElement) { entered = entered || child === target; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b9ca460b9..e99b0a155 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -9,8 +9,7 @@ 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, isTarget as hasDescendantTarget, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; +import { emptyFunction, hasDescendantTarget, OmitKeys, returnFalse, returnVal, Utils } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -832,7 +831,7 @@ export class DocumentViewInternal extends DocComponent !SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document)} - onPointerLeave={e => hasDescendantTarget(e.nativeEvent.x, e.nativeEvent.y, this.ContentDiv) && Doc.UnBrushDoc(this.props.Document)} + onPointerLeave={e => !hasDescendantTarget(e.nativeEvent.x, e.nativeEvent.y, this.ContentDiv) && Doc.UnBrushDoc(this.props.Document)} style={{ borderRadius: this.borderRounding, pointerEvents: this.pointerEvents, -- cgit v1.2.3-70-g09d2