aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx6
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx21
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx8
-rw-r--r--src/client/views/collections/CollectionMenu.tsx4
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx11
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx22
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.scss2
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx5
-rw-r--r--src/client/views/collections/CollectionView.tsx11
-rw-r--r--src/client/views/collections/SchemaTable.tsx24
-rw-r--r--src/client/views/collections/TabDocView.tsx148
-rw-r--r--src/client/views/collections/TreeView.tsx24
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx12
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx7
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx76
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx25
-rw-r--r--src/client/views/collections/collectionGrid/CollectionGridView.tsx8
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx12
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx26
20 files changed, 219 insertions, 235 deletions
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 <ContentFittingDocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ return <DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
onDoubleClick={this.onChildDoubleClick}
onClick={onChildClick}
renderDepth={this.props.renderDepth + 1}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 26c36507a..512328835 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -1,21 +1,18 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { observable, computed } from 'mobx';
+import { computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { documentSchema, collectionSchema } from '../../../fields/documentSchemas';
+import { Doc } from '../../../fields/Doc';
+import { collectionSchema, documentSchema } from '../../../fields/documentSchemas';
import { makeInterface } from '../../../fields/Schema';
-import { NumCast, StrCast, ScriptCast, Cast } from '../../../fields/Types';
+import { NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { OmitKeys, returnFalse } from '../../../Utils';
import { DragManager } from '../../util/DragManager';
-import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
-import "./CollectionCarouselView.scss";
-import { CollectionSubView } from './CollectionSubView';
-import { Doc } from '../../../fields/Doc';
+import { DocumentView } from '../nodes/DocumentView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import { ContextMenu } from '../ContextMenu';
-import { ObjectField } from '../../../fields/ObjectField';
-import { returnFalse, returnZero, OmitKeys } from '../../../Utils';
-import { ScriptField } from '../../../fields/ScriptField';
import { StyleProp } from '../StyleProvider';
+import "./CollectionCarouselView.scss";
+import { CollectionSubView } from './CollectionSubView';
type CarouselDocument = makeInterface<[typeof documentSchema, typeof collectionSchema]>;
const CarouselDocument = makeInterface(documentSchema, collectionSchema);
@@ -50,7 +47,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
return !(curDoc?.layout instanceof Doc) ? (null) :
<>
<div className="collectionCarouselView-image" key="image">
- <ContentFittingDocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ <DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
onDoubleClick={this.onContentDoubleClick}
onClick={this.onContentClick}
renderDepth={this.props.renderDepth + 1}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index c7c510306..756346356 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -7,11 +7,11 @@ import { documentSchema } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
import { makeInterface } from '../../../fields/Schema';
import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnOne, returnTrue, Utils } from '../../../Utils';
+import { emptyFunction, returnTrue, Utils } from '../../../Utils';
import { DragManager } from '../../util/DragManager';
import { Transform } from '../../util/Transform';
-import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
+import { DocumentView } from '../nodes/DocumentView';
import { LinkDescriptionPopup } from '../nodes/LinkDescriptionPopup';
import "./CollectionLinearView.scss";
import { CollectionSubView } from './CollectionSubView';
@@ -137,7 +137,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
width: nested ? pair.layout[WidthSym]() : this.dimension(),
height: nested && pair.layout.linearViewIsExpanded ? pair.layout[HeightSym]() : this.dimension(),
}} >
- <ContentFittingDocumentView
+ <DocumentView
Document={pair.layout}
DataDoc={pair.data}
addDocument={this.props.addDocument}
@@ -146,9 +146,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
pinToPres={emptyFunction}
rootSelected={this.props.isSelected}
removeDocument={this.props.removeDocument}
- onClick={undefined}
ScreenToLocalTransform={this.getTransform(dref)}
- ContentScaling={returnOne}
PanelWidth={nested ? pair.layout[WidthSym] : this.dimension}
PanelHeight={nested ? pair.layout[HeightSym] : this.dimension}
renderDepth={this.props.renderDepth + 1}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 833fc0007..20b4fa2d7 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -11,6 +11,7 @@ import { Id } from "../../../fields/FieldSymbols";
import { InkTool } from "../../../fields/InkField";
import { List } from "../../../fields/List";
import { ObjectField } from "../../../fields/ObjectField";
+import { RichTextField } from "../../../fields/RichTextField";
import { listSpec } from "../../../fields/Schema";
import { ScriptField } from "../../../fields/ScriptField";
import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
@@ -33,7 +34,6 @@ import { PresBox } from "../nodes/PresBox";
import "./CollectionMenu.scss";
import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
import { TabDocView } from "./TabDocView";
-import { RichTextField } from "../../../fields/RichTextField";
@observer
export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -514,7 +514,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
<Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom">
<button className={"antimodeMenu-button"} key="float"
style={{ backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined, borderRight: "1px solid gray" }}
- onClick={() => DocumentView.FloatDoc(this.props.docView)}>
+ onClick={undoBatch(() => this.props.docView.float())}>
<FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} />
</button>
</Tooltip>}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index c64048345..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,7 +20,8 @@ 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";
@@ -397,10 +398,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
get previewPanel() {
return <div ref={this.createTarget} style={{ width: `${this.previewWidth()}px` }}>
{!this.previewDocument ? (null) :
- <ContentFittingDocumentView
+ <DocumentView
Document={this.previewDocument}
DataDoc={undefined}
- fitToBox={true}
+ fitContentsToDoc={true}
freezeDimensions={true}
dontCenter={"y"}
focus={emptyFunction}
@@ -412,6 +413,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}
@@ -422,7 +424,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
addDocTab={this.props.addDocTab}
pinToPres={this.props.pinToPres}
bringToFront={returnFalse}
- ContentScaling={returnOne}
/>}
</div>;
}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e8165f673..d8a8723cd 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, Opt } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
@@ -11,7 +11,7 @@ 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, returnVal, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils";
+import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils";
import { DocUtils } from "../../documents/Documents";
import { DragManager, dropActionType } from "../../util/DragManager";
import { SnappingManager } from "../../util/SnappingManager";
@@ -21,14 +21,14 @@ import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
import { EditableView } from "../EditableView";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
-import { DocAfterFocusFunc, DocumentViewProps } from "../nodes/DocumentView";
+import { DocumentView, DocAfterFocusFunc, DocumentViewProps } from "../nodes/DocumentView";
+import { FieldViewProps } from "../nodes/FieldView";
+import { StyleProp } from "../StyleProvider";
import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
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]>;
@@ -61,7 +61,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
@computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
@computed get showAddAGroup() { return (this.pivotField && (this.chromeStatus !== 'view-mode' && this.chromeStatus !== 'disabled')); }
@computed get columnWidth() {
- return Math.min(this.props.PanelWidth() / this.props.ContentScaling() /* / NumCast(this.layoutDoc._viewScale, 1)*/ - 2 * this.xMargin,
+ return Math.min(this.props.PanelWidth() /* / NumCast(this.layoutDoc._viewScale, 1)*/ - 2 * this.xMargin,
this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
}
@computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; }
@@ -189,7 +189,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
getDisplayDoc(doc: Doc, dxf: () => 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<DocumentViewProps>, property: string) => {
+ const styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => {
if (property === StyleProp.Opacity && doc) {
if (this.props.childOpacity) {
return this.props.childOpacity();
@@ -200,7 +200,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
}
return this.props.styleProvider?.(doc, props, property);
};
- return <ContentFittingDocumentView
+ return <DocumentView
Document={doc}
DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
renderDepth={this.props.renderDepth + 1}
@@ -213,7 +213,6 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
NativeWidth={this.props.childIgnoreNativeSize ? returnZero : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
NativeHeight={this.props.childIgnoreNativeSize ? returnZero : undefined}
dontCenter={this.props.childIgnoreNativeSize ? "xy" : undefined}
- fitToBox={false}
dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.dontRegisterChildViews, this.props.dontRegisterView)}
rootSelected={this.rootSelected}
dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
@@ -234,7 +233,6 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
whenActiveChanged={this.props.whenActiveChanged}
addDocTab={this.addDocTab}
bringToFront={returnFalse}
- ContentScaling={returnOne}
scriptContext={this.props.scriptContext}
pinToPres={this.props.pinToPres}
/>;
@@ -481,8 +479,8 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
}
- @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc)); }
- @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc)); }
+ @computed get nativeWidth() { return Doc.NativeWidth(this.layoutDoc); }
+ @computed get nativeHeight() { return Doc.NativeHeight(this.layoutDoc); }
@computed get scaling() { return !this.nativeWidth ? 1 : this.props.PanelHeight() / this.nativeHeight; }
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index c7a826669..cc625e12e 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -86,7 +86,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
@computed get contents() {
return <div className="collectionTimeView-innards" key="timeline" style={{ width: "100%", pointerEvents: this.props.active() ? undefined : "none" }} onPointerDown={this.contentsDown}>
<CollectionFreeFormView {...this.props}
- fitToBox={true}
+ fitContentsToDoc={true}
childClickScript={this._childClickedScript}
viewDefDivClick={this._viewDefDivClick}
childFreezeDimensions={true}
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;
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 0fd263402..a90edc2c9 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -8,7 +8,7 @@ import { Document } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, Utils } from '../../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, Utils } from '../../../Utils';
import { DocUtils } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType } from "../../util/DragManager";
@@ -20,11 +20,11 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from "../EditableView";
import { DocumentView } from '../nodes/DocumentView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import { StyleProp } from '../StyleProvider';
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import { TreeView } from "./TreeView";
import React = require("react");
-import { StyleProp } from '../StyleProvider';
export type collectionTreeViewProps = {
treeViewHideTitle?: boolean;
@@ -182,7 +182,6 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
addDocTab={this.props.addDocTab}
pinToPres={this.props.pinToPres}
bringToFront={returnFalse}
- ContentScaling={returnOne}
/>
</div>;
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 04edc3d09..bea5ac2ed 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');
@@ -107,7 +108,7 @@ export class CollectionView extends Touchable<CollectionViewProps> {
active = (outsideReaction?: boolean) => (this.props.isSelected(outsideReaction) ||
this.props.rootSelected(outsideReaction) ||
- this.props.Document.forceActive ||
+ (this.props.layerProvider?.(this.props.Document) !== false && (this.props.Document.forceActive || this.props.Document._isGroup)) ||
this._isChildActive ||
this.props.renderDepth === 0) ?
true :
@@ -146,7 +147,7 @@ export class CollectionView extends Touchable<CollectionViewProps> {
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;
});
@@ -171,7 +172,7 @@ export class CollectionView extends Touchable<CollectionViewProps> {
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<Doc>).push(...added);
targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
}
@@ -385,10 +386,8 @@ export class CollectionView extends Touchable<CollectionViewProps> {
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 (<div className={"collectionView"} onContextMenu={this.onContextMenu}
- style={{ pointerEvents: this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined, boxShadow }}>
+ 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/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 24a67faaf..d77f70607 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -5,31 +5,31 @@ import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
import ReactTable, { CellInfo, Column, ComponentPropsGetterR, Resize, SortingRule } from "react-table";
import "react-table/react-table.css";
-import { Doc, DocListCast, Field, Opt, AclPrivate, AclReadonly, DataSym } from "../../../fields/Doc";
+import { DateField } from "../../../fields/DateField";
+import { AclPrivate, AclReadonly, DataSym, Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { ComputedField } from "../../../fields/ScriptField";
import { Cast, FieldValue, NumCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero, returnEmptyDoclist } from "../../../Utils";
+import { ImageField } from "../../../fields/URLField";
+import { GetEffectiveAcl } from "../../../fields/util";
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse } from "../../../Utils";
import { Docs, DocumentOptions } from "../../documents/Documents";
+import { DocumentType } from "../../documents/DocumentTypes";
import { CompileScript, Transformer, ts } from "../../util/Scripting";
import { Transform } from "../../util/Transform";
import { undoBatch } from "../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss';
import { ContextMenu } from "../ContextMenu";
import '../DocumentDecorations.scss';
-import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
-import { CellProps, CollectionSchemaButtons, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDateCell, CollectionSchemaDocCell, CollectionSchemaImageCell, CollectionSchemaListCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell } from "./CollectionSchemaCells";
+import { DocumentView } from "../nodes/DocumentView";
+import { CellProps, CollectionSchemaButtons, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDateCell, CollectionSchemaDocCell, CollectionSchemaImageCell, CollectionSchemaListCell, CollectionSchemaNumberCell, CollectionSchemaStringCell } from "./CollectionSchemaCells";
import { CollectionSchemaAddColumnHeader, KeysDropdown } from "./CollectionSchemaHeaders";
import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC";
import "./CollectionSchemaView.scss";
import { CollectionView } from "./CollectionView";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { GetEffectiveAcl } from "../../../fields/util";
-import { DateField } from "../../../fields/DateField";
-import { ImageField } from "../../../fields/URLField";
enum ColumnType {
@@ -567,10 +567,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
background: "dimGray", display: "block", top: 0, left: 0,
transform: `translate(${this._showDocPos[0]}px, ${this._showDocPos[1] - 180}px)`
}}
- ref="overlay"><ContentFittingDocumentView
+ ref="overlay"><DocumentView
Document={this._showDoc}
DataDoc={this._showDataDoc}
- fitToBox={true}
freezeDimensions={true}
focus={emptyFunction}
renderDepth={this.props.renderDepth}
@@ -588,9 +587,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
whenActiveChanged={emptyFunction}
addDocTab={this.props.addDocTab}
pinToPres={this.props.pinToPres}
- bringToFront={returnFalse}
- ContentScaling={returnOne}>
- </ContentFittingDocumentView>
+ bringToFront={returnFalse}>
+ </DocumentView>
</div>}
</div>;
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 8b5143013..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,17 +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';
const _global = (window /* browser */ || global /* node */) as any;
interface TabDocViewProps {
@@ -51,6 +51,16 @@ export class TabDocView extends React.Component<TabDocViewProps> {
@observable private _document: Doc | 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))); }
+ @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; }
get view() { return this._view; }
@@ -105,14 +115,15 @@ export class TabDocView extends React.Component<TabDocViewProps> {
};
// 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) SelectionManager.SelectDoc(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),
action((selected) => {
if (selected) this._activated = true;
@@ -239,48 +250,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
}
- 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
@@ -303,14 +272,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
}
- @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) => {
@@ -352,10 +313,9 @@ export class TabDocView extends React.Component<TabDocViewProps> {
addDocument={returnFalse}
moveDocument={returnFalse}
removeDocument={returnFalse}
- ContentScaling={returnOne}
PanelWidth={this.returnMiniSize}
PanelHeight={this.returnMiniSize}
- ScreenToLocalTransform={this.ScreenToLocalTransform}
+ ScreenToLocalTransform={Transform.Identity}
renderDepth={0}
whenActiveChanged={emptyFunction}
focus={emptyFunction}
@@ -365,7 +325,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
docFilters={CollectionDockingView.Instance.docFilters}
docRangeFilters={CollectionDockingView.Instance.docRangeFilters}
searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
- fitToBox={true}
+ fitContentsToDoc={true}
/>
<div className="miniOverlay" onPointerDown={this.miniDown} >
<div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% `, }} />
@@ -387,9 +347,14 @@ export class TabDocView extends React.Component<TabDocViewProps> {
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<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
+ static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string): any => {
if (doc) {
switch (property.split(":")[0]) {
default: return DefaultStyleProvider(doc, props, property);
@@ -408,31 +373,29 @@ export class TabDocView extends React.Component<TabDocViewProps> {
TraceMobx();
return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) :
<><DocumentView key={this._document[Id]} ref={action((r: DocumentView) => 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}
+ 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()}
<Tooltip key="ttip" title={<div className="dash-tooltip">{"toggle minimap"}</div>}>
@@ -445,18 +408,15 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
render() {
- return (<div className="collectionDockingView-content" ref={ref => {
- 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}
- </div >);
+ return (
+ <div className="collectionDockingView-content" style={{ height: "100%", width: "100%" }} ref={ref => {
+ 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}
+ </div >
+ );
}
} \ No newline at end of file
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 843bec6de..e289f24a9 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,16 +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 } from '../StyleProvider';
export interface TreeViewProps {
document: Doc;
@@ -83,7 +83,7 @@ export class TreeView extends React.Component<TreeViewProps> {
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
@@ -497,13 +497,13 @@ export class TreeView extends React.Component<TreeViewProps> {
e.preventDefault();
}
}
- titleStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => {
+ titleStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps | FieldViewProps>, 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) :
<div className="treeView-label" style={{ // just render a title for a tree view label (identified by treeViewDoc being set in 'props')
maxWidth: props?.PanelWidth() || undefined,
background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor),
@@ -513,7 +513,7 @@ export class TreeView extends React.Component<TreeViewProps> {
case StyleProp.Decorations: return (null);
}
}
- embeddedStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => {
+ embeddedStyleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps | FieldViewProps>, 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
}
@@ -553,7 +553,6 @@ export class TreeView extends React.Component<TreeViewProps> {
moveDocument={this.move}
removeDocument={this.props.removeDoc}
ScreenToLocalTransform={this.getTransform}
- ContentScaling={returnOne}
PanelWidth={this.truncateTitleWidth}
PanelHeight={returnZero}
contextMenuItems={this.contextMenuItems}
@@ -609,14 +608,14 @@ export class TreeView extends React.Component<TreeViewProps> {
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 <ContentFittingDocumentView key={this.doc[Id]} ref={action((r: ContentFittingDocumentView | null) => this._dref = r)}
+ return <DocumentView key={this.doc[Id]} ref={action((r: DocumentView | null) => this._dref = r)}
Document={this.doc}
DataDoc={undefined}
PanelWidth={panelWidth}
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}
+ fitContentsToDoc={true}
hideTitle={asText}
LayoutTemplateString={asText ? FormattedTextBox.LayoutString("text") : undefined}
focus={asText ? this.refocus : returnFalse}
@@ -638,7 +637,6 @@ export class TreeView extends React.Component<TreeViewProps> {
addDocTab={this.props.addDocTab}
pinToPres={this.props.pinToPres}
bringToFront={returnFalse}
- ContentScaling={returnOne}
/>;
}
@@ -672,7 +670,7 @@ export class TreeView extends React.Component<TreeViewProps> {
else this._editMaxWidth = "";
const hideTitle = this.doc.treeViewHideHeader || this.outlineMode;
- return <div className={`treeView-container${this._dref?.docView?.contentsActive() ? "-active" : ""}`}
+ return <div className={`treeView-container${this._dref?.contentsActive() ? "-active" : ""}`}
ref={this.createTreeDropTarget}
onPointerDown={e => 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 b8576681d..1add65c10 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";
@@ -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",
@@ -115,11 +116,11 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@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; }
+ @computed get fitToContent() { return (this.props.fitContentsToDoc || this.Document._fitToBox) && !this.isAnnotationOverlay; }
+ @computed get parentScaling() { return 1; }
@computed get contentBounds() { return aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc._xPadding, 10), NumCast(this.layoutDoc._yPadding, 10)); }
- @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; }
@@ -219,8 +220,28 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return (pt => 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.layerProvider?.(this.props.Document) !== false && 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);
@@ -251,6 +272,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
!StrListCast(d.layers).includes(StyleLayers.Background) && (d._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : d._raiseWhenDragged) && (d.zIndex = zsorted.length + 1 + i); // bringToFront
}
+ this.updateGroupBounds();
+
(docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments);
return true;
}
@@ -279,7 +302,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
} else {
const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
this.props.addDocument?.(source);
- linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation", ""); // TODODO this is where in text links get passed
+ de.complete.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation", ""); // TODODO this is where in text links get passed
e.stopPropagation();
return true;
}
@@ -321,7 +344,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const clusterDocs = eles.map(ele => 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].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 });
@@ -405,7 +428,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}
- getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => {
+ getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, 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);
@@ -421,7 +444,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
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) styleProp = "gray";
+ } //else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray";
return styleProp;
}
@@ -653,6 +676,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return;
}
if (!e.cancelBubble) {
+ if (this.props.Document._isGroup) return; // groups don't pan when dragged -- instead let the event go through to allow the group itself to drag
if (Doc.GetSelectedTool() === InkTool.None) {
if (this.tryDragCluster(e, this._hitCluster)) {
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
@@ -986,6 +1010,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height)));
}
+ @observable ChildDrag: DocumentView | undefined;
onChildClickHandler = () => 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;
@@ -997,7 +1022,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
pinToPres: this.props.pinToPres,
whenActiveChanged: this.props.whenActiveChanged,
parentActive: this.parentActive,
- fitToBox: false,
DataDoc: childData,
Document: childLayout,
ContainingCollectionView: this.props.CollectionView,
@@ -1010,7 +1034,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
ScreenToLocalTransform: childLayout.z ? this.getTransformOverlay : this.getTransform,
PanelWidth: childLayout[WidthSym],
PanelHeight: childLayout[HeightSym],
- ContentScaling: returnOne,
docFilters: this.docFilters,
docRangeFilters: this.docRangeFilters,
searchFilterDocs: this.searchFilterDocs,
@@ -1166,6 +1189,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
key={entry[1].pair.layout[Id] + (entry[1].replica || "")}
{...this.getChildDocumentViewProps(entry[1].pair.layout, entry[1].pair.data)}
replica={entry[1].replica}
+ CollectionFreeFormView={this}
dataProvider={this.childDataProvider}
sizeProvider={this.childSizeProvider}
layerProvider={this.props.layerProvider}
@@ -1174,7 +1198,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
(this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : undefined}
jitterRotation={NumCast(this.props.Document._jitterRotation) || ((Doc.UserDoc().renderStyle === "comic" ? 10 : 0))}
//fitToBox={this.props.fitToBox || BoolCast(this.props.freezeChildDimensions)} // bcz: check this
- fitToBox={BoolCast(this.props.childFreezeDimensions)} // bcz: check this
freezeDimensions={BoolCast(this.props.childFreezeDimensions)}
/>,
bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica)
@@ -1204,6 +1227,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}));
}
+ //this.updateGroupBounds();
this._marqueeRef.current?.addEventListener("dashDragAutoScroll", this.onDragAutoScroll as any);
}
@@ -1277,7 +1301,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@undoBatch
@action
toggleNativeDimensions = () => {
- Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth?.() || 0, this.props.NativeHeight?.() || 0);
+ Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight);
}
@undoBatch
@@ -1294,6 +1318,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
!Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
+ 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" });
@@ -1308,8 +1334,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const optionItems = options && "subitems" in options ? options.subitems : [];
!this.props.isAnnotationOverlay && !Doc.UserDoc().noviceMode &&
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" });
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) {
@@ -1382,7 +1406,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
onPointerOver = (e: React.PointerEvent) => {
- (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();
}
@@ -1470,6 +1494,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@computed get marqueeView() {
return <MarqueeView
{...this.props}
+ ungroup={this.props.Document._isGroup ? this.promoteCollection : undefined}
nudge={this.isAnnotationOverlay || this.props.renderDepth > 0 ? undefined : this.nudge}
addDocTab={this.addDocTab}
trySelectCluster={this.trySelectCluster}
@@ -1501,8 +1526,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@computed get contentScaling() {
if (this.props.isAnnotationOverlay && !this.props.forceScaling) return 0;
- const nw = returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document));
- const nh = returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.Document));
+ const nw = this.nativeWidth;
+ const nh = this.nativeHeight;
const hscale = nh ? this.props.PanelHeight() / nh : 1;
const wscale = nw ? this.props.PanelWidth() / nw : 1;
return wscale < hscale ? wscale : hscale;
@@ -1549,6 +1574,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
{this._vLines?.map(l => <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />)}
</svg>
</div>}
+
+ {this.props.Document._isGroup && SnappingManager.GetIsDragging() && (this.ChildDrag || this.props.layerProvider?.(this.props.Document) === false) ?
+ <div className="collectionFreeForm-groupDropper" ref={this.createDashEventsTarget} style={{
+ width: this.ChildDrag ? "10000" : "100%",
+ height: this.ChildDrag ? "10000" : "100%",
+ left: this.ChildDrag ? "-5000" : 0,
+ top: this.ChildDrag ? "-5000" : 0,
+ position: "absolute",
+ background: "#0009930",
+ pointerEvents: "all"
+ }} /> : (null)}
</div >;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index f1f190bff..47ffc48fb 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<SubCollectionViewProps & Marque
cm.displayMenu(this._downX, this._downY);
e.stopPropagation();
} else
- if (e.key === ":") {
+ if (e.key === "u" && this.props.ungroup) {
+ e.stopPropagation();
+ this.props.ungroup();
+ }
+ else if (e.key === ":") {
DocUtils.addDocumentCreatorMenuItems(this.props.addLiveTextDocument, this.props.addDocument || returnFalse, x, y);
cm.displayMenu(this._downX, this._downY);
@@ -341,10 +346,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, layers: string[]) => {
+ getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, layers: string[], makeGroup: Opt<boolean>) => {
const newCollection = creator ? creator(selected, { title: "nested stack", }) : ((doc: Doc) => {
Doc.GetProto(doc).data = new List<Doc>(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));
@@ -352,6 +357,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
newCollection.layers = new List<string>(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<SubCollectionViewProps & Marque
@undoBatch
@action
- collection = (e: KeyboardEvent | React.PointerEvent | undefined) => {
+ 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<SubCollectionViewProps & Marque
}));
this.props.removeDocument?.(selected);
}
- const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === "t" ? Docs.Create.StackingDocument : undefined, []);
+ const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === "t" ? Docs.Create.StackingDocument : undefined, [], group);
this.props.addDocument?.(newCollection);
this.props.selectDocuments([newCollection]);
MarqueeOptionsMenu.Instance.fadeOut(true);
@@ -523,7 +529,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
@action
background = (e: KeyboardEvent | React.PointerEvent | undefined) => {
- 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<SubCollectionViewProps & Marque
this.delete();
e.stopPropagation();
}
- if ("cbtsSp".indexOf(e.key) !== -1) {
+ if ("cbtsSpg".indexOf(e.key) !== -1) {
this._commandExecuted = true;
e.stopPropagation();
e.preventDefault();
(e as any).propagationIsStopped = true;
+ if (e.key === "g") this.collection(e, true);
if (e.key === "c" || e.key === "t") this.collection(e);
if (e.key === "s" || e.key === "S") this.summary(e);
if (e.key === "b") this.background(e);
@@ -634,7 +641,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
render() {
return <div className="marqueeView"
- style={{ overflow: !this.props.ContainingCollectionView && this.props.isAnnotationOverlay ? "visible" : StrCast(this.props.Document._overflow), cursor: MarqueeView.DragMarquee && this ? "crosshair" : "hand" }}
+ style={{ overflow: (!this.props.ContainingCollectionView && this.props.isAnnotationOverlay) ? "visible" : StrCast(this.props.Document._overflow), cursor: MarqueeView.DragMarquee && this ? "crosshair" : "hand" }}
onDragOver={e => 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/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 1a4eb8b7b..58db080ad 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -6,7 +6,7 @@ import { documentSchema } from '../../../../fields/documentSchemas';
import { Id } from '../../../../fields/FieldSymbols';
import { makeInterface } from '../../../../fields/Schema';
import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
+import { emptyFunction, OmitKeys, returnFalse, setupMoveUpEvents } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
import { DragManager } from '../../../util/DragManager';
import { SnappingManager } from '../../../util/SnappingManager';
@@ -14,7 +14,7 @@ import { Transform } from '../../../util/Transform';
import { undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { ContextMenuProps } from '../../ContextMenuItem';
-import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { CollectionSubView } from '../CollectionSubView';
import "./CollectionGridView.scss";
@@ -161,15 +161,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
* @returns the `ContentFittingDocumentView` of the node
*/
getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) {
- return <ContentFittingDocumentView
+ return <DocumentView
{...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
Document={layout}
DataDoc={layout.resolvedDataDoc as Doc}
PanelWidth={width}
PanelHeight={height}
- ContentScaling={returnOne}
freezeDimensions={true}
- fitToBox={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..85013b960 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -3,18 +3,18 @@ import { observer } from 'mobx-react';
import * as React from "react";
import { Doc } from '../../../../fields/Doc';
import { documentSchema } from '../../../../fields/documentSchemas';
+import { List } from '../../../../fields/List';
import { makeInterface } from '../../../../fields/Schema';
-import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../fields/Types';
+import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { returnFalse } from '../../../../Utils';
import { DragManager, dropActionType } from '../../../util/DragManager';
import { Transform } from '../../../util/Transform';
import { undoBatch } from '../../../util/UndoManager';
-import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
import { CollectionSubView } from '../CollectionSubView';
import "./CollectionMulticolumnView.scss";
import ResizeBar from './MulticolumnResizer';
import WidthLabel from './MulticolumnWidthLabel';
-import { List } from '../../../../fields/List';
-import { returnZero, returnFalse, returnOne } from '../../../../Utils';
type MulticolumnDocument = makeInterface<[typeof documentSchema]>;
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 <ContentFittingDocumentView
+ return <DocumentView
Document={layout}
DataDoc={layout.resolvedDataDoc as Doc}
styleProvider={this.props.styleProvider}
@@ -223,7 +223,6 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
renderDepth={this.props.renderDepth + 1}
PanelWidth={width}
PanelHeight={height}
- fitToBox={false}
rootSelected={this.rootSelected}
dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
onClick={this.onChildClickHandler}
@@ -243,7 +242,6 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
addDocTab={this.addDocTab}
pinToPres={this.props.pinToPres}
bringToFront={returnFalse}
- ContentScaling={returnOne}
/>;
}
/**
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 9039090d1..4f5c8af95 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -1,20 +1,20 @@
+import { action, computed } from 'mobx';
import { observer } from 'mobx-react';
-import { makeInterface } from '../../../../fields/Schema';
-import { documentSchema } from '../../../../fields/documentSchemas';
-import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import * as React from "react";
import { Doc } from '../../../../fields/Doc';
-import { NumCast, StrCast, BoolCast, ScriptCast } from '../../../../fields/Types';
-import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
-import { Utils, returnZero, returnFalse, returnOne } from '../../../../Utils';
-import "./CollectionMultirowView.scss";
-import { computed, trace, observable, action } from 'mobx';
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { List } from '../../../../fields/List';
+import { makeInterface } from '../../../../fields/Schema';
+import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { returnFalse } from '../../../../Utils';
+import { DragManager, dropActionType } from '../../../util/DragManager';
import { Transform } from '../../../util/Transform';
+import { undoBatch } from '../../../util/UndoManager';
+import { DocumentView } from '../../nodes/DocumentView';
+import { CollectionSubView } from '../CollectionSubView';
+import "./CollectionMultirowView.scss";
import HeightLabel from './MultirowHeightLabel';
import ResizeBar from './MultirowResizer';
-import { undoBatch } from '../../../util/UndoManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
-import { List } from '../../../../fields/List';
type MultirowDocument = makeInterface<[typeof documentSchema]>;
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 <ContentFittingDocumentView
+ return <DocumentView
Document={layout}
DataDoc={layout.resolvedDataDoc as Doc}
styleProvider={this.props.styleProvider}
@@ -223,7 +223,6 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
renderDepth={this.props.renderDepth + 1}
PanelWidth={width}
PanelHeight={height}
- fitToBox={false}
rootSelected={this.rootSelected}
dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
onClick={this.onChildClickHandler}
@@ -243,7 +242,6 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
addDocTab={this.addDocTab}
pinToPres={this.props.pinToPres}
bringToFront={returnFalse}
- ContentScaling={returnOne}
/>;
}
/**