aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorAndy Rickert <andrew_rickert@brown.edu>2020-06-03 16:40:09 -0400
committerAndy Rickert <andrew_rickert@brown.edu>2020-06-03 16:40:09 -0400
commit954948ddd511578af4ca2c50c960765a5a7bc637 (patch)
tree16fafd254a5db95d5c39838d4313d7ddf59753af /src/client/views/collections
parent6d8d3c00587c43ae61392db4fe6915ee492c2e4a (diff)
parent9588e56079f7e4ab98da1849f44996656649bc06 (diff)
merge
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx15
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx32
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx10
-rw-r--r--src/client/views/collections/CollectionMapView.tsx29
-rw-r--r--src/client/views/collections/CollectionMasonryViewFieldRow.tsx22
-rw-r--r--src/client/views/collections/CollectionPileView.scss3
-rw-r--r--src/client/views/collections/CollectionPileView.tsx63
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx8
-rw-r--r--src/client/views/collections/CollectionSchemaHeaders.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaMovableTableHOC.tsx6
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx14
-rw-r--r--src/client/views/collections/CollectionStackingView.scss42
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx21
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx18
-rw-r--r--src/client/views/collections/CollectionStaffView.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx65
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx12
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx25
-rw-r--r--src/client/views/collections/CollectionView.tsx47
-rw-r--r--src/client/views/collections/CollectionViewChromes.scss60
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx212
-rw-r--r--src/client/views/collections/ParentDocumentSelector.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx18
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx12
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx192
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx149
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx10
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx10
-rw-r--r--src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx4
-rw-r--r--src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx4
-rw-r--r--src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx4
-rw-r--r--src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx4
35 files changed, 692 insertions, 440 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index a04136e51..f65a89422 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -2,18 +2,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { observable, computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { documentSchema, collectionSchema } from '../../../new_fields/documentSchemas';
-import { makeInterface } from '../../../new_fields/Schema';
-import { NumCast, StrCast, ScriptCast, Cast } from '../../../new_fields/Types';
+import { documentSchema, collectionSchema } from '../../../fields/documentSchemas';
+import { makeInterface } from '../../../fields/Schema';
+import { NumCast, StrCast, ScriptCast, Cast } from '../../../fields/Types';
import { DragManager } from '../../util/DragManager';
import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
import "./CollectionCarouselView.scss";
import { CollectionSubView } from './CollectionSubView';
-import { faCaretLeft, faCaretRight } from '@fortawesome/free-solid-svg-icons';
-import { Doc } from '../../../new_fields/Doc';
+import { Doc } from '../../../fields/Doc';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { ContextMenu } from '../ContextMenu';
-import { ObjectField } from '../../../new_fields/ObjectField';
+import { ObjectField } from '../../../fields/ObjectField';
import { returnFalse } from '../../../Utils';
type CarouselDocument = makeInterface<[typeof documentSchema, typeof collectionSchema]>;
@@ -76,10 +75,10 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
@computed get buttons() {
return <>
<div key="back" className="carouselView-back" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={this.goback}>
- <FontAwesomeIcon icon={faCaretLeft} size={"2x"} />
+ <FontAwesomeIcon icon={"caret-left"} size={"2x"} />
</div>
<div key="fwd" className="carouselView-fwd" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={this.advance}>
- <FontAwesomeIcon icon={faCaretRight} size={"2x"} />
+ <FontAwesomeIcon icon={"caret-right"} size={"2x"} />
</div>
</>;
}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 581625222..6f5a3dfe4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,5 +1,3 @@
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faFile } from '@fortawesome/free-solid-svg-icons';
import 'golden-layout/src/css/goldenlayout-base.css';
import 'golden-layout/src/css/goldenlayout-dark-theme.css';
import { action, computed, Lambda, observable, reaction, runInAction, trace } from "mobx";
@@ -7,13 +5,13 @@ import { observer } from "mobx-react";
import * as ReactDOM from 'react-dom';
import Measure from "react-measure";
import * as GoldenLayout from "../../../client/goldenLayout";
-import { DateField } from '../../../new_fields/DateField';
-import { Doc, DocListCast, Field, Opt, DataSym } from "../../../new_fields/Doc";
-import { Id } from '../../../new_fields/FieldSymbols';
-import { List } from '../../../new_fields/List';
-import { FieldId } from "../../../new_fields/RefField";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { TraceMobx } from '../../../new_fields/util';
+import { DateField } from '../../../fields/DateField';
+import { Doc, DocListCast, Field, Opt, DataSym } from "../../../fields/Doc";
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { FieldId } from "../../../fields/RefField";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from '../../../fields/util';
import { emptyFunction, returnOne, returnTrue, Utils, returnZero } from "../../../Utils";
import { DocServer } from "../../DocServer";
import { Docs } from '../../documents/Documents';
@@ -31,7 +29,6 @@ import { DockingViewButtonSelector } from './ParentDocumentSelector';
import React = require("react");
import { CollectionViewType } from './CollectionView';
import { SnappingManager } from '../../util/SnappingManager';
-library.add(faFile);
const _global = (window /* browser */ || global /* node */) as any;
@observer
@@ -196,15 +193,16 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
if (!CollectionDockingView.Instance) return undefined;
const instance = CollectionDockingView.Instance;
const replaceTab = (doc: Doc, child: any): Opt<Doc> => {
- for (let i = 0; i < child.contentItems.length; i++) {
- if (child.contentItems[i].isRow || child.contentItems[i].isColumn || child.contentItems[i].isStack) {
- const val = replaceTab(doc, child.contentItems[i]);
+ for (const contentItem of child.contentItems) {
+ const { config, isStack, isRow, isColumn } = contentItem;
+ if (isRow || isColumn || isStack) {
+ const val = replaceTab(doc, contentItem);
if (val) return val;
- } else if (child.contentItems[i].config.component === "DocumentFrameRenderer" &&
- child.contentItems[i].config.props.documentId === doc[Id]) {
+ } else if (config.component === "DocumentFrameRenderer" &&
+ config.props.documentId === doc[Id]) {
const alias = Doc.MakeAlias(doc);
- child.contentItems[i].config.props.documentId = alias[Id];
- child.contentItems[i].config.title = alias.title;
+ config.props.documentId = alias[Id];
+ config.title = alias.title;
instance.stateChanged();
return alias;
}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 344dca23a..f1002044a 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -1,9 +1,9 @@
import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc';
-import { makeInterface } from '../../../new_fields/Schema';
-import { BoolCast, NumCast, StrCast, Cast, ScriptCast } from '../../../new_fields/Types';
+import { Doc, HeightSym, WidthSym } from '../../../fields/Doc';
+import { makeInterface } from '../../../fields/Schema';
+import { BoolCast, NumCast, StrCast, Cast, ScriptCast } from '../../../fields/Types';
import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils, returnFalse, returnZero } from '../../../Utils';
import { DragManager } from '../../util/DragManager';
import { Transform } from '../../util/Transform';
@@ -11,8 +11,8 @@ import "./CollectionLinearView.scss";
import { CollectionViewType } from './CollectionView';
import { CollectionSubView } from './CollectionSubView';
import { DocumentView } from '../nodes/DocumentView';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { Id } from '../../../fields/FieldSymbols';
type LinearDocument = makeInterface<[typeof documentSchema,]>;
diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx
index 971224482..a0b7cd8a8 100644
--- a/src/client/views/collections/CollectionMapView.tsx
+++ b/src/client/views/collections/CollectionMapView.tsx
@@ -1,10 +1,10 @@
import { GoogleApiWrapper, Map as GeoMap, IMapProps, Marker } from "google-maps-react";
import { observer } from "mobx-react";
-import { Doc, Opt, DocListCast, FieldResult, Field } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types";
+import { Doc, Opt, DocListCast, FieldResult, Field } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
+import { makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
import "./CollectionMapView.scss";
import { CollectionSubView } from "./CollectionSubView";
import React = require("react");
@@ -47,7 +47,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
private _cancelAddrReq = new Map<string, boolean>();
private _cancelLocReq = new Map<string, boolean>();
private _initialLookupPending = new Map<string, boolean>();
- private responders: { location: Lambda, address: Lambda }[] = [];
+ private responders: { locationDisposer: Lambda, addressDisposer: Lambda }[] = [];
/**
* Note that all the uses of runInAction below are not included
@@ -176,13 +176,16 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
}
@computed get reactiveContents() {
- this.responders.forEach(({ location, address }) => { location(); address(); });
+ this.responders.forEach(({ locationDisposer, addressDisposer }) => {
+ locationDisposer();
+ addressDisposer();
+ });
this.responders = [];
return this.childLayoutPairs.map(({ layout }) => {
const fieldKey = Doc.LayoutFieldKey(layout);
const id = layout[Id];
this.responders.push({
- location: computed(() => ({ lat: layout[`${fieldKey}-lat`], lng: layout[`${fieldKey}-lng`] }))
+ locationDisposer: computed(() => ({ lat: layout[`${fieldKey}-lat`], lng: layout[`${fieldKey}-lng`] }))
.observe(({ oldValue, newValue }) => {
if (this._cancelLocReq.get(id)) {
this._cancelLocReq.set(id, false);
@@ -190,7 +193,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
this.respondToLocationChange(layout, fieldKey, newValue, oldValue);
}
}),
- address: computed(() => Cast(layout[`${fieldKey}-address`], "string", null))
+ addressDisposer: computed(() => Cast(layout[`${fieldKey}-address`], "string", null))
.observe(({ oldValue, newValue }) => {
if (this._cancelAddrReq.get(id)) {
this._cancelAddrReq.set(id, false);
@@ -206,7 +209,8 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
render() {
const { childLayoutPairs } = this;
const { Document, fieldKey, active, google } = this.props;
- let center = this.getLocation(Document, `${fieldKey}-mapCenter`, false);
+ const mapLoc = this.getLocation(this.rootDoc, `${fieldKey}-mapCenter`, false);
+ let center = mapLoc;
if (center === undefined) {
const childLocations = childLayoutPairs.map(({ layout }) => this.getLocation(layout, Doc.LayoutFieldKey(layout), false));
center = childLocations.find(location => location) || defaultLocation;
@@ -222,7 +226,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
initialCenter={center}
center={center}
onIdle={(_props?: IMapProps, map?: google.maps.Map) => {
- if (this.layoutDoc.lockedTransform) {
+ if (this.layoutDoc._lockedTransform) {
// reset zoom (ideally, we could probably can tell the map to disallow zooming somehow instead)
map?.setZoom(center?.zoom || 10);
map?.setCenter({ lat: center?.lat!, lng: center?.lng! });
@@ -234,7 +238,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
}
}}
onDragend={(_props?: IMapProps, map?: google.maps.Map) => {
- if (this.layoutDoc.lockedTransform) {
+ if (this.layoutDoc._lockedTransform) {
// reset the drag (ideally, we could probably can tell the map to disallow dragging somehow instead)
map?.setCenter({ lat: center?.lat!, lng: center?.lng! });
} else {
@@ -246,6 +250,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
}}
>
{this.reactiveContents}
+ {mapLoc ? this.renderMarker(this.rootDoc) : undefined}
</GeoMap>
</div>
</div>;
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 95c7643c9..cc7a9f5ac 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -1,13 +1,11 @@
import React = require("react");
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faPalette } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { StrCast, NumCast } from "../../../new_fields/Types";
+import { Doc } from "../../../fields/Doc";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ScriptField } from "../../../fields/ScriptField";
+import { StrCast, NumCast } from "../../../fields/Types";
import { numberRange, setupMoveUpEvents, emptyFunction } from "../../../Utils";
import { Docs } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
@@ -22,8 +20,6 @@ const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
-library.add(faPalette);
-
interface CMVFieldRowProps {
rows: () => number;
headings: () => object[];
@@ -244,13 +240,15 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
toggle: this.toggleVisibility,
color: this.color
};
+ const showChrome = (chromeStatus !== 'view-mode' && chromeStatus !== 'disabled');
+ const stackPad = showChrome ? `0px ${this.props.parent.xMargin}px` : `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px 0px ${this.props.parent.xMargin}px `;
return this.collapsed ? (null) :
<div style={{ position: "relative" }}>
- {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ?
+ {showChrome ?
<div className="collectionStackingView-addDocumentButton"
style={{
- width: style.columnWidth / style.numGroupColumns,
- padding: NumCast(this.props.parent.layoutDoc._yPadding)
+ //width: style.columnWidth / style.numGroupColumns,
+ padding: `${NumCast(this.props.parent.layoutDoc._yPadding, this.props.parent.yMargin)}px 0px 0px 0px`
}}>
<EditableView {...newEditableViewProps} />
</div> : null
@@ -258,7 +256,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
<div className={`collectionStackingView-masonryGrid`}
ref={this._contRef}
style={{
- padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
+ padding: stackPad,
width: this.props.parent.NodeWidth,
gridGap: this.props.parent.gridGap,
gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
diff --git a/src/client/views/collections/CollectionPileView.scss b/src/client/views/collections/CollectionPileView.scss
index ac874b663..48d07e42b 100644
--- a/src/client/views/collections/CollectionPileView.scss
+++ b/src/client/views/collections/CollectionPileView.scss
@@ -5,4 +5,7 @@
height: 100%;
width: 100%;
overflow: visible;
+ .collectionPileView-innards {
+ width:100%;
+ }
}
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index d3ae21f3a..fc48e0327 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,18 +1,17 @@
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { HeightSym, Opt, WidthSym } from "../../../new_fields/Doc";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { BoolCast, NumCast, StrCast } from "../../../new_fields/Types";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
+import { HeightSym, Opt, WidthSym, Doc } from "../../../fields/Doc";
+import { ScriptField } from "../../../fields/ScriptField";
+import { BoolCast, NumCast, StrCast } from "../../../fields/Types";
import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionPileView.scss";
import React = require("react");
import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../../Utils";
import { SelectionManager } from "../../util/SelectionManager";
-import { UndoManager } from "../../util/UndoManager";
+import { UndoManager, undoBatch } from "../../util/UndoManager";
import { SnappingManager } from "../../util/SnappingManager";
+import { DragManager } from "../../util/DragManager";
@observer
export class CollectionPileView extends CollectionSubView(doc => doc) {
@@ -20,10 +19,12 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
_doubleTap: boolean | undefined = false;
_originalChrome: string = "";
@observable _contentsActive = true;
- @observable _layoutEngine = "pass";
@observable _collapsed: boolean = false;
@observable _childClickedScript: Opt<ScriptField>;
componentDidMount() {
+ if (this.layoutEngine() !== "pass" && this.layoutEngine() !== "starburst") {
+ this.Document._pileLayoutEngine = "pass";
+ }
this._originalChrome = StrCast(this.layoutDoc._chromeStatus);
this.layoutDoc._chromeStatus = "disabled";
this.layoutDoc.hideFilterView = true;
@@ -33,49 +34,54 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
this.layoutDoc._chromeStatus = this._originalChrome;
}
- layoutEngine = () => this._layoutEngine;
+ layoutEngine = () => StrCast(this.Document._pileLayoutEngine);
@computed get contents() {
- return <div className="collectionPileView-innards" style={{
- width: "100%",
- pointerEvents: this.layoutEngine() !== "pass" && (this.props.active() || this.layoutEngine() === "starburst") ? undefined : "none"
- }} >
+ return <div className="collectionPileView-innards" style={{ pointerEvents: this.layoutEngine() === "starburst" ? undefined : "none" }} >
<CollectionFreeFormView {...this.props} layoutEngine={this.layoutEngine} />
</div>;
}
-
- specificMenu = (e: React.MouseEvent) => {
- const layoutItems: ContextMenuProps[] = [];
- const doc = this.props.Document;
-
- ContextMenu.Instance.addItem({ description: "Options...", subitems: layoutItems, icon: "eye" });
- }
-
toggleStarburst = action(() => {
- if (this._layoutEngine === 'starburst') {
+ if (this.layoutEngine() === 'starburst') {
const defaultSize = 110;
this.layoutDoc._overflow = undefined;
+ this.childDocs.forEach(d => Doc.iconify(d));
this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - NumCast(this.layoutDoc._starburstPileWidth, defaultSize) / 2;
this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - NumCast(this.layoutDoc._starburstPileHeight, defaultSize) / 2;
this.layoutDoc._width = NumCast(this.layoutDoc._starburstPileWidth, defaultSize);
this.layoutDoc._height = NumCast(this.layoutDoc._starburstPileHeight, defaultSize);
- this._layoutEngine = 'pass';
+ Doc.pileup(this.childDocs);
+ this.layoutDoc._panX = 0;
+ this.layoutDoc._panY = -10;
+ this.props.Document._pileLayoutEngine = 'pass';
} else {
const defaultSize = 25;
this.layoutDoc._overflow = 'visible';
!this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 500);
!this.layoutDoc._starburstDocScale && (this.layoutDoc._starburstDocScale = 2.5);
- if (this._layoutEngine === 'pass') {
+ if (this.layoutEngine() === 'pass') {
this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - defaultSize / 2;
this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - defaultSize / 2;
this.layoutDoc._starburstPileWidth = this.layoutDoc[WidthSym]();
this.layoutDoc._starburstPileHeight = this.layoutDoc[HeightSym]();
}
+ this.layoutDoc._panX = this.layoutDoc._panY = 0;
this.layoutDoc._width = this.layoutDoc._height = defaultSize;
- this._layoutEngine = 'starburst';
+ this.props.Document._pileLayoutEngine = 'starburst';
}
});
+ @undoBatch
+ @action
+ onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+ if (super.onInternalDrop(e, de)) {
+ if (de.complete.docDragData) {
+ Doc.pileup(this.childDocs);
+ }
+ }
+ return true;
+ }
+
_undoBatch: UndoManager.Batch | undefined;
pointerDown = (e: React.PointerEvent) => {
let dist = 0;
@@ -107,20 +113,17 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
}
onClick = (e: React.MouseEvent) => {
- if (e.button === 0 && (this._doubleTap || this.layoutEngine() === "starburst")) {
+ if (e.button === 0 && this._doubleTap) {
SelectionManager.DeselectAll();
this.toggleStarburst();
e.stopPropagation();
}
- // else if (this.layoutEngine() === "pass") {
- // runInAction(() => this._contentsActive = false);
- // setTimeout(action(() => this._contentsActive = true), 300);
- // }
}
render() {
- return <div className={"collectionPileView"} onContextMenu={this.specificMenu} onClick={this.onClick} onPointerDown={this.pointerDown}
+ return <div className={"collectionPileView"} onClick={this.onClick} onPointerDown={this.pointerDown}
+ ref={this.createDashEventsTarget}
style={{ width: this.props.PanelWidth(), height: `calc(100% - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
{this.contents}
</div>;
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 8a5450b0c..62aed67ed 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -4,8 +4,8 @@ import { observer } from "mobx-react";
import { CellInfo } from "react-table";
import "react-table/react-table.css";
import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils";
-import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
import { KeyCodes } from "../../util/KeyCodes";
import { SetupDrag, DragManager } from "../../util/DragManager";
import { CompileScript } from "../../util/Scripting";
@@ -16,11 +16,11 @@ import { EditableView } from "../EditableView";
import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./CollectionSchemaView.scss";
import { CollectionView } from "./CollectionView";
-import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_fields/Types";
+import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../fields/Types";
import { Docs } from "../../documents/Documents";
import { library } from '@fortawesome/fontawesome-svg-core';
import { faExpand } from '@fortawesome/free-solid-svg-icons';
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { undoBatch } from "../../util/UndoManager";
import { SnappingManager } from "../../util/SnappingManager";
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 507ee89e4..dae0600b1 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -7,7 +7,7 @@ import { library, IconProp } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ColumnType } from "./CollectionSchemaView";
import { faFile } from "@fortawesome/free-regular-svg-icons";
-import { SchemaHeaderField, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHeaderField";
import { undoBatch } from "../../util/UndoManager";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 5aec46a83..6f1e8ac1f 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -2,16 +2,16 @@ import React = require("react");
import { ReactTableDefaults, TableCellRenderer, RowInfo } from "react-table";
import "./CollectionSchemaView.scss";
import { Transform } from "../../util/Transform";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc } from "../../../fields/Doc";
import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager";
-import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
+import { Cast, FieldValue, StrCast } from "../../../fields/Types";
import { ContextMenu } from "../ContextMenu";
import { action } from "mobx";
import { library } from '@fortawesome/fontawesome-svg-core';
import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { DocumentManager } from "../../util/DocumentManager";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { undoBatch } from "../../util/UndoManager";
import { SnappingManager } from "../../util/SnappingManager";
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 51ad6c81b..35f892d65 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -6,13 +6,13 @@ import { action, computed, observable, untracked } 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 } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, FieldValue, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
+import { 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, BoolCast } from "../../../fields/Types";
import { Docs, DocumentOptions } from "../../documents/Documents";
import { CompileScript, Transformer, ts } from "../../util/Scripting";
import { Transform } from "../../util/Transform";
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 5eaf29316..203c51163 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -7,11 +7,13 @@
.collectionStackingView {
display: flex;
}
+
.collectionStackingMasonry-cont {
- position:relative;
- height:100%;
- width:100%;
+ position: relative;
+ height: 100%;
+ width: 100%;
}
+
.collectionStackingView,
.collectionMasonryView {
height: 100%;
@@ -22,12 +24,17 @@
overflow-x: hidden;
flex-wrap: wrap;
transition: top .5s;
+
>div {
position: relative;
display: block;
}
+
.collectionStackingViewFieldColumn {
- height:max-content;
+ height: max-content;
+ }
+ .collectionStackingViewFieldColumnDragging {
+ height:100%;
}
.collectionSchemaView-previewDoc {
@@ -129,27 +136,34 @@
background: red;
}
}
+
.collectionStackingView-miniHeader {
width: 100%;
+
.editableView-container-editing-oneLine {
min-height: 20px;
display: flex;
align-items: center;
flex-direction: row;
}
- span::before , span::after{
+
+ span::before,
+ span::after {
content: "";
width: 50%;
border-top: dashed gray 1px;
position: relative;
display: inline-block;
}
+
span::before {
margin-right: 10px;
}
- span::after{
+
+ span::after {
margin-left: 10px;
}
+
span {
position: relative;
text-align: center;
@@ -157,10 +171,11 @@
overflow: visible;
width: 100%;
display: flex;
- color:gray;
+ color: gray;
align-items: center;
}
}
+
.collectionStackingView-sectionHeader {
text-align: center;
margin: auto;
@@ -277,7 +292,7 @@
height: 20px;
border-radius: 10px;
margin: 3px;
- width:max-content;
+ width: max-content;
&.active {
color: red;
@@ -294,15 +309,18 @@
display: none;
}
}
+
.collectionStackingView-sectionHeader:hover {
.collectionStackingView-sectionColor {
- display:unset;
+ display: unset;
}
+
.collectionStackingView-sectionOptions {
- display:unset;
+ display: unset;
}
+
.collectionStackingView-sectionDelete {
- display:unset;
+ display: unset;
}
}
@@ -403,4 +421,4 @@
.rc-switch-checked .rc-switch-inner {
left: 8px;
}
-}
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 376e7c087..b84fc9266 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,14 +4,14 @@ 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 "../../../new_fields/Doc";
-import { collectionSchema, documentSchema } from "../../../new_fields/documentSchemas";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec, makeInterface } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types";
-import { TraceMobx } from "../../../new_fields/util";
+import { DataSym, Doc, HeightSym, WidthSym } from "../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+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 } from "../../../Utils";
import { DragManager, dropActionType } from "../../util/DragManager";
import { Transform } from "../../util/Transform";
@@ -26,6 +26,7 @@ import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewField
import { CollectionSubView } from "./CollectionSubView";
import { CollectionViewType } from "./CollectionView";
import { SnappingManager } from "../../util/SnappingManager";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
const _global = (window /* browser */ || global /* node */) as any;
type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
@@ -194,8 +195,8 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
}
getDisplayDoc(doc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
- const layoutDoc = Doc.Layout(doc, this.props.ChildLayoutTemplate?.());
const height = () => this.getDocHeight(doc);
+ const opacity = () => this.Document.currentFrame === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document.currentFrame))?.opacity;
return <ContentFittingDocumentView
Document={doc}
DataDoc={dataDoc || (doc[DataSym] !== doc && doc[DataSym])}
@@ -210,11 +211,13 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
NativeHeight={returnZero}
NativeWidth={returnZero}
fitToBox={false}
+ dontRegisterView={this.props.dontRegisterView}
rootSelected={this.rootSelected}
dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
onClick={this.onChildClickHandler}
onDoubleClick={this.onChildDoubleClickHandler}
ScreenToLocalTransform={dxf}
+ opacity={opacity}
focus={this.focusDocument}
ContainingCollectionDoc={this.props.CollectionView?.props.Document}
ContainingCollectionView={this.props.CollectionView}
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index dccef7983..a269b21f5 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -4,13 +4,13 @@ import { faPalette } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { NumCast, StrCast, Cast } from "../../../new_fields/Types";
-import { ImageField } from "../../../new_fields/URLField";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { RichTextField } from "../../../fields/RichTextField";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ScriptField } from "../../../fields/ScriptField";
+import { NumCast, StrCast, Cast } from "../../../fields/Types";
+import { ImageField } from "../../../fields/URLField";
+import { TraceMobx } from "../../../fields/util";
import { Docs, DocUtils } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
import { Transform } from "../../util/Transform";
@@ -21,7 +21,7 @@ import { EditableView } from "../EditableView";
import { CollectionStackingView } from "./CollectionStackingView";
import { setupMoveUpEvents, emptyFunction } from "../../../Utils";
import "./CollectionStackingView.scss";
-import { listSpec } from "../../../new_fields/Schema";
+import { listSpec } from "../../../fields/Schema";
import { SnappingManager } from "../../util/SnappingManager";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
@@ -352,7 +352,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
const chromeStatus = this.props.parent.props.Document._chromeStatus;
return (
- <div className="collectionStackingViewFieldColumn" key={heading}
+ <div className={"collectionStackingViewFieldColumn" + (SnappingManager.GetIsDragging() ? "Dragging" : "")} key={heading}
style={{
width: `${100 / ((uniqueHeadings.length + ((chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`,
height: undefined, // DraggingManager.GetIsDragging() ? "100%" : undefined,
diff --git a/src/client/views/collections/CollectionStaffView.tsx b/src/client/views/collections/CollectionStaffView.tsx
index 5b9a69bf7..c5c3f96e8 100644
--- a/src/client/views/collections/CollectionStaffView.tsx
+++ b/src/client/views/collections/CollectionStaffView.tsx
@@ -1,7 +1,7 @@
import { CollectionSubView } from "./CollectionSubView";
import React = require("react");
import { computed, action, IReactionDisposer, reaction, runInAction, observable } from "mobx";
-import { NumCast } from "../../../new_fields/Types";
+import { NumCast } from "../../../fields/Types";
import "./CollectionStaffView.scss";
import { observer } from "mobx-react";
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 8b50bd8fc..423eb1d90 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,19 +1,19 @@
import { action, computed, IReactionDisposer, reaction } from "mobx";
import { basename } from 'path';
-import CursorField from "../../../new_fields/CursorField";
-import { Doc, Opt } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, ScriptCast } from "../../../new_fields/Types";
+import CursorField from "../../../fields/CursorField";
+import { Doc, Opt } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { ScriptField } from "../../../fields/ScriptField";
+import { Cast, ScriptCast, NumCast } from "../../../fields/Types";
import { GestureUtils } from "../../../pen-gestures/GestureUtils";
-import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
import { Upload } from "../../../server/SharedMediaTypes";
import { Utils } from "../../../Utils";
import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
import { DocServer } from "../../DocServer";
-import { Docs, DocumentOptions } from "../../documents/Documents";
+import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents";
import { DocumentType } from "../../documents/DocumentTypes";
import { Networking } from "../../Network";
import { DragManager, dropActionType } from "../../util/DragManager";
@@ -25,6 +25,8 @@ import { FieldViewProps } from "../nodes/FieldView";
import { FormattedTextBox, GoogleRef } from "../nodes/formattedText/FormattedTextBox";
import { CollectionView } from "./CollectionView";
import React = require("react");
+import { SelectionManager } from "../../util/SelectionManager";
+import { WebField } from "../../../fields/URLField";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc | Doc[]) => boolean;
@@ -44,6 +46,7 @@ export interface SubCollectionViewProps extends CollectionViewProps {
CollectionView: Opt<CollectionView>;
children?: never | (() => JSX.Element[]) | React.ReactNode;
ChildLayoutTemplate?: () => Doc;
+ childOpacity?: () => number;
ChildLayoutString?: string;
childClickScript?: ScriptField;
childDoubleClickScript?: ScriptField;
@@ -206,6 +209,8 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
}
}
+ addDocument = (doc: Doc | Doc[]) => this.props.addDocument(doc);
+
@undoBatch
@action
protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
@@ -213,22 +218,23 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
if (docDragData) {
let added = false;
- if (docDragData.dropAction || docDragData.userDropAction) {
- added = this.props.addDocument(docDragData.droppedDocuments);
+ const dropaction = docDragData.dropAction || docDragData.userDropAction;
+ if (dropaction && dropaction !== "move") {
+ added = this.addDocument(docDragData.droppedDocuments);
} else if (docDragData.moveDocument) {
const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
- const res = addedDocs.length ? this.props.addDocument(addedDocs) : true;
- added = movedDocs.length ? docDragData.moveDocument(movedDocs, this.props.Document, this.props.addDocument) : res;
+ const res = addedDocs.length ? this.addDocument(addedDocs) : true;
+ added = movedDocs.length ? docDragData.moveDocument(movedDocs, this.props.Document, this.addDocument) : res;
} else {
- added = this.props.addDocument(docDragData.droppedDocuments);
+ added = this.addDocument(docDragData.droppedDocuments);
}
e.stopPropagation();
return added;
}
else if (de.complete.annoDragData) {
e.stopPropagation();
- return this.props.addDocument(de.complete.annoDragData.dropDocument);
+ return this.addDocument(de.complete.annoDragData.dropDocument);
}
return false;
}
@@ -265,7 +271,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
e.stopPropagation();
e.preventDefault();
- const { addDocument } = this.props;
+ const { addDocument } = this;
if (!addDocument) {
alert("this.props.addDocument does not exist. Aborting drop operation.");
return;
@@ -321,9 +327,30 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
}
});
} else {
- const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", _width: 300, _height: 300 });
+ let srcUrl: string | undefined;
+ let srcWeb: Doc | undefined;
+ if (SelectionManager.SelectedDocuments().length) {
+ srcWeb = SelectionManager.SelectedDocuments()[0].props.Document;
+ srcUrl = (srcWeb.data as WebField).url.href?.match(/http[s]?:\/\/[^/]*/)?.[0];
+ }
+ const reg = new RegExp(Utils.prepend(""), "g");
+ 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"] = text;
this.props.addDocument(htmlDoc);
+ if (srcWeb) {
+ const focusNode = (SelectionManager.SelectedDocuments()[0].ContentDiv?.getElementsByTagName("iframe")[0].contentDocument?.getSelection()?.focusNode as any);
+ if (focusNode) {
+ const rect = "getBoundingClientRect" in focusNode ? focusNode.getBoundingClientRect() : focusNode?.parentElement.getBoundingClientRect();
+ const x = (rect?.x || 0);
+ const y = NumCast(srcWeb.scrollTop) + (rect?.y || 0);
+ const anchor = Docs.Create.FreeformDocument([], { _LODdisable: true, _backgroundColor: "transparent", _width: 25, _height: 25, x, y, annotationOn: srcWeb });
+ anchor.context = srcWeb;
+ const key = Doc.LayoutFieldKey(srcWeb);
+ Doc.AddDocToList(srcWeb, key + "-annotations", anchor);
+ DocUtils.MakeLink({ doc: htmlDoc }, { doc: anchor });
+ }
+ }
}
return;
}
@@ -332,7 +359,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if (text) {
if (text.includes("www.youtube.com/watch")) {
- const url = text.replace("youtube.com/watch?v=", "youtube.com/embed/");
+ const url = text.replace("youtube.com/watch?v=", "youtube.com/embed/").split("&")[0];
addDocument(Docs.Create.VideoDocument(url, {
...options,
title: url,
@@ -425,7 +452,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if (generatedDocuments.length) {
const set = generatedDocuments.length > 1 && generatedDocuments.map(d => Doc.iconify(d));
if (set) {
- addDocument(Doc.pileup(generatedDocuments, options.x!, options.y!));
+ addDocument(Doc.pileup(generatedDocuments, options.x!, options.y!)!);
} else {
generatedDocuments.forEach(addDocument);
}
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index a2d4774c8..15bc0bfd5 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,11 +1,11 @@
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Opt, DocCastAsync } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { ObjectField } from "../../../new_fields/ObjectField";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { ComputedField, ScriptField } from "../../../new_fields/ScriptField";
-import { NumCast, StrCast, BoolCast, Cast } from "../../../new_fields/Types";
+import { Doc, Opt, DocCastAsync } from "../../../fields/Doc";
+import { List } from "../../../fields/List";
+import { ObjectField } from "../../../fields/ObjectField";
+import { RichTextField } from "../../../fields/RichTextField";
+import { ComputedField, ScriptField } from "../../../fields/ScriptField";
+import { NumCast, StrCast, BoolCast, Cast } from "../../../fields/Types";
import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils";
import { Scripting } from "../../util/Scripting";
import { ContextMenu } from "../ContextMenu";
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 2f332e77d..b2e1c0f73 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,13 +1,13 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { List } from '../../../new_fields/List';
-import { PrefetchProxy } from '../../../new_fields/Proxy';
-import { Document, listSpec } from '../../../new_fields/Schema';
-import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types';
+import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { PrefetchProxy } from '../../../fields/Proxy';
+import { Document, listSpec } from '../../../fields/Schema';
+import { ComputedField, ScriptField } from '../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from "../../documents/DocumentTypes";
@@ -32,7 +32,7 @@ import "./CollectionTreeView.scss";
import { CollectionViewType } from './CollectionView';
import React = require("react");
import { makeTemplate } from '../../util/DropConverter';
-import { TraceMobx } from '../../../new_fields/util';
+import { TraceMobx } from '../../../fields/util';
export interface TreeViewProps {
document: Doc;
@@ -717,7 +717,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
}
ContextMenu.Instance.addItem({
description: "Buxton Layout", icon: "eye", event: () => {
- const { ImageDocument } = Docs.Create;
+ const { ImageDocument, PdfDocument } = Docs.Create;
const { Document } = this.props;
const fallbackImg = "http://www.cs.brown.edu/~bcz/face.gif";
const detailView = Cast(Cast(Doc.UserDoc()["template-button-detail"], Doc, null)?.dragFactory, Doc, null);
@@ -726,13 +726,14 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
heroView._showTitle = "title";
heroView._showTitleHover = "titlehover";
- const doubleClickView = ImageDocument("http://cs.brown.edu/~bcz/face.gif", { _width: 400 }); // replace with desired double click target
+ const fallback = ImageDocument("http://cs.brown.edu/~bcz/face.gif", { _width: 400 }); // replace with desired double click target
+ let pdfContent: string;
DocListCast(this.dataDoc[this.props.fieldKey]).map(d => {
DocListCast(d.data).map((img, i) => {
const caption = (d.captions as any)[i];
if (caption) {
Doc.GetProto(img).caption = caption;
- Doc.GetProto(img).doubleClickView = doubleClickView;
+ Doc.GetProto(img).doubleClickView = (pdfContent = StrCast(img.additionalMedia_pdfs)) ? PdfDocument(pdfContent, { title: pdfContent }) : fallback;
}
});
Doc.GetProto(d).type = "buxton";
@@ -748,7 +749,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
Document.childLayoutTemplate = heroView;
Document.childClickedOpenTemplateView = new PrefetchProxy(detailView);
Document._viewType = CollectionViewType.Time;
- Document._forceActive = true;
+ Document.forceActive = true;
Document._pivotField = "company";
Document.childDropAction = "alias";
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0f239d385..7acb3457b 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -7,12 +7,12 @@ import { observer } from "mobx-react";
import * as React from 'react';
import Lightbox from 'react-image-lightbox-with-rotate';
import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app
-import { DateField } from '../../../new_fields/DateField';
-import { DataSym, Doc, DocListCast, Field, Opt } from '../../../new_fields/Doc';
-import { List } from '../../../new_fields/List';
-import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../new_fields/Types';
-import { ImageField } from '../../../new_fields/URLField';
-import { TraceMobx } from '../../../new_fields/util';
+import { DateField } from '../../../fields/DateField';
+import { DataSym, Doc, DocListCast, Field, Opt, AclSym, AclAddonly, AclReadonly } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
+import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../fields/Types';
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
import { Utils, setupMoveUpEvents, returnFalse, returnZero, emptyPath, emptyFunction, returnOne } from '../../../Utils';
import { DocumentType } from '../../documents/DocumentTypes';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
@@ -35,13 +35,13 @@ import { CollectionTimeView } from './CollectionTimeView';
import { CollectionTreeView } from "./CollectionTreeView";
import './CollectionView.scss';
import { CollectionViewBaseChrome } from './CollectionViewChromes';
-import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { listSpec } from '../../../new_fields/Schema';
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
+import { Id } from '../../../fields/FieldSymbols';
+import { listSpec } from '../../../fields/Schema';
import { Docs } from '../../documents/Documents';
-import { ScriptField, ComputedField } from '../../../new_fields/ScriptField';
+import { ScriptField, ComputedField } from '../../../fields/ScriptField';
import { InteractionUtils } from '../../util/InteractionUtils';
-import { ObjectField } from '../../../new_fields/ObjectField';
+import { ObjectField } from '../../../fields/ObjectField';
import CollectionMapView from './CollectionMapView';
import { CollectionPileView } from './CollectionPileView';
const higflyout = require("@hig/flyout");
@@ -69,9 +69,10 @@ export enum CollectionViewType {
Pile = "pileup"
}
export interface CollectionViewCustomProps {
- 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)
+ 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)
childLayoutTemplate?: () => Opt<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
+ childOpacity?: () => number;
}
export interface CollectionRenderProps {
@@ -117,20 +118,24 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
@action.bound
addDocument = (doc: Doc | Doc[]): boolean => {
- if (doc instanceof Doc) {
- if (this.props.filterAddDocument?.(doc) === false) {
- return false;
- }
+ if (this.props.filterAddDocument?.(doc) === false) {
+ return false;
}
const docs = doc instanceof Doc ? [doc] : doc;
const targetDataDoc = this.props.Document[DataSym];
const docList = DocListCast(targetDataDoc[this.props.fieldKey]);
const added = docs.filter(d => !docList.includes(d));
if (added.length) {
- added.map(doc => doc.context = this.props.Document);
- added.map(add => Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add));
- targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, ...added]);
- targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+ if (this.dataDoc[AclSym] === AclReadonly) {
+ return false;
+ } else if (this.dataDoc[AclSym] === AclAddonly) {
+ added.map(doc => Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc));
+ } else {
+ added.map(doc => doc.context = this.props.Document);
+ added.map(add => Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add));
+ targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, ...added]);
+ targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+ }
}
return true;
}
@@ -494,7 +499,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
return (<div className={"collectionView"}
style={{
pointerEvents: this.props.Document.isBackground ? "none" : undefined,
- boxShadow: this.props.Document.isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
+ boxShadow: Doc.UserDoc().renderStyle === "comic" || this.props.Document.isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
`${Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "rgb(30, 32, 31)" : "#9c9396"} ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}`
}}
onContextMenu={this.onContextMenu}>
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index e4581eb46..03bd9a01a 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -8,10 +8,12 @@
z-index: 9001;
transition: top .5s;
background: lightgrey;
+ transform-origin: top left;
.collectionViewChrome {
display: flex;
- padding-bottom: 10px;
+ padding-bottom: 1px;
+ height:32px;
border-bottom: .5px solid rgb(180, 180, 180);
overflow: hidden;
@@ -21,12 +23,12 @@
.collectionViewBaseChrome-viewPicker {
font-size: 75%;
//text-transform: uppercase;
- letter-spacing: 2px;
+ //letter-spacing: 2px;
background: rgb(238, 238, 238);
color: grey;
outline-color: black;
border: none;
- padding: 12px 10px 11px 10px;
+ //padding: 12px 10px 11px 10px;
}
.collectionViewBaseChrome-viewPicker:active {
@@ -47,6 +49,7 @@
.collectionViewBaseChrome-cmdPicker {
margin-left: 3px;
margin-right: 0px;
+ font-size: 75%;
background: rgb(238, 238, 238);
border: none;
color: grey;
@@ -56,6 +59,7 @@
background-color: gray;
display: flex;
flex-direction: row;
+ height:30px;
.commandEntry-drop {
color:white;
width:25px;
@@ -95,8 +99,8 @@
margin: auto;
background: gray;
color: white;
- width: 40px;
- height: 40px;
+ width: 30px;
+ height: 30px;
align-items: center;
justify-content: center;
}
@@ -195,8 +199,7 @@
.collectionTreeViewChrome-pivotField-label {
vertical-align: center;
padding-left: 10px;
- padding-top: 10px;
- padding-bottom: 10px;
+ margin:auto;
}
.collectionStackingViewChrome-pivotField,
@@ -204,14 +207,15 @@
color: white;
width:100%;
min-width: 100px;
- text-align: center;
+ display: flex;
+ align-items: center;
background: rgb(238, 238, 238);
.editable-view-input,
input,
.editableView-container-editing-oneLine,
.editableView-container-editing {
- padding: 12px 10px 11px 10px;
+ margin:auto;
border: 0px;
color: grey;
text-align: center;
@@ -235,6 +239,44 @@
}
}
+.collectionFreeFormViewChrome-cont {
+ width: 60px;
+ display: flex;
+ position: relative;
+ align-items: center;
+ .fwdKeyframe, .numKeyframe, .backKeyframe {
+ cursor: pointer;
+ position: absolute;
+ width: 20;
+ height: 30;
+ bottom: 0;
+ background: gray;
+ display: flex;
+ align-items: center;
+ color:white;
+ }
+ .backKeyframe {
+ left:0;
+ svg {
+ display:block;
+ margin:auto;
+ }
+ }
+ .numKeyframe {
+ left:20;
+ display: flex;
+ flex-direction: column;
+ padding: 5px;
+ }
+ .fwdKeyframe {
+ left:40;
+ svg {
+ display:block;
+ margin:auto;
+ }
+ }
+}
+
.collectionSchemaViewChrome-cont {
display: flex;
font-size: 10.5px;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 62b03bbdc..29a3e559a 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -2,11 +2,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
import { Utils, emptyFunction, setupMoveUpEvents } from "../../../Utils";
import { DragManager } from "../../util/DragManager";
import { undoBatch } from "../../util/UndoManager";
@@ -15,6 +15,7 @@ import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
import { CollectionViewType } from "./CollectionView";
import { CollectionView } from "./CollectionView";
import "./CollectionViewChromes.scss";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
const datepicker = require('js-datepicker');
interface CollectionViewChromeProps {
@@ -44,7 +45,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
initialize: emptyFunction,
};
_narrativeCommand = {
- params: ["target", "source"], title: "=> click clicked open view",
+ params: ["target", "source"], title: "=> child click view",
script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])",
immediate: (source: Doc[]) => this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]),
initialize: emptyFunction,
@@ -83,22 +84,16 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
private _viewRef = React.createRef<HTMLInputElement>();
@observable private _currentKey: string = "";
- componentDidMount = () => {
- runInAction(() => {
- // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
- const chromeStatus = this.props.CollectionView.props.Document._chromeStatus;
- if (chromeStatus) {
- if (chromeStatus === "disabled") {
- throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
- }
- else if (chromeStatus === "collapsed") {
- if (this.props.collapse) {
- this.props.collapse(true);
- }
- }
- }
- });
- }
+ componentDidMount = action(() => {
+ // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
+ switch (this.props.CollectionView.props.Document._chromeStatus) {
+ case "disabled":
+ throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
+ case "collapsed":
+ this.props.collapse?.(true);
+ break;
+ }
+ })
@undoBatch
viewChanged = (e: React.ChangeEvent) => {
@@ -197,10 +192,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
- subChrome = () => {
+ @computed get subChrome() {
const collapsed = this.document._chromeStatus !== "enabled";
if (collapsed) return null;
switch (this.props.type) {
+ case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
@@ -236,7 +232,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
const vtype = this.props.CollectionView.collectionViewType;
const c = {
params: ["target"], title: vtype,
- script: `this.target._viewType = ${StrCast(this.props.CollectionView.props.Document._viewType)}`,
+ script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`,
immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]),
initialize: emptyFunction,
};
@@ -254,14 +250,61 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}, emptyFunction, emptyFunction);
}
+ @computed get templateChrome() {
+ const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
+ return <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} style={{ display: collapsed ? "none" : undefined }}>
+ <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
+ <div className="commandEntry-drop">
+ <FontAwesomeIcon icon="bullseye" size="2x" />
+ </div>
+ <select
+ className="collectionViewBaseChrome-cmdPicker"
+ onPointerDown={stopPropagation}
+ onChange={this.commandChanged}
+ value={this._currentKey}>
+ <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={"empty"} value={""} />
+ {this._buttonizableCommands.map(cmd =>
+ <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={cmd.title} value={cmd.title}>{cmd.title}</option>
+ )}
+ </select>
+ </div>
+ </div>;
+ }
+
+ @computed get viewModes() {
+ const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
+ return <div className="collectionViewBaseChrome-viewModes" style={{ display: collapsed ? "none" : undefined }}>
+ <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._viewRef} onPointerDown={this.dragViewDown}>
+ <div className="commandEntry-drop">
+ <FontAwesomeIcon icon="bullseye" size="2x" />
+ </div>
+ <select
+ className="collectionViewBaseChrome-viewPicker"
+ onPointerDown={stopPropagation}
+ onChange={this.viewChanged}
+ value={StrCast(this.props.CollectionView.props.Document._viewType)}>
+ {Object.values(CollectionViewType).map(type => ["invalid", "docking"].includes(type) ? (null) : (
+ <option
+ key={Utils.GenerateGuid()}
+ className="collectionViewBaseChrome-viewOption"
+ onPointerDown={stopPropagation}
+ value={type}>
+ {type[0].toUpperCase() + type.substring(1)}
+ </option>
+ ))}
+ </select>
+ </div>
+ </div>;
+ }
+
render() {
const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
+ const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale);
return (
<div className="collectionViewChrome-cont" style={{
top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined,
- transform: collapsed ? "" : `scale(${Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale)})`,
- transformOrigin: "top left",
- width: `${this.props.PanelWidth() / Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale)}px`
+ transform: collapsed ? "" : `scale(${scale})`,
+ width: `${this.props.PanelWidth() / scale}px`
}}>
<div className="collectionViewChrome" style={{ border: "unset", pointerEvents: collapsed ? "none" : undefined }}>
<div className="collectionViewBaseChrome">
@@ -276,52 +319,15 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
title="Collapse collection chrome" onClick={this.toggleCollapse}>
<FontAwesomeIcon icon="caret-up" size="2x" />
</button>
- <div className="collectionViewBaseChrome-viewModes" style={{ display: collapsed ? "none" : undefined }}>
- <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._viewRef} onPointerDown={this.dragViewDown}>
- <div className="commandEntry-drop">
- <FontAwesomeIcon icon="bullseye" size="2x"></FontAwesomeIcon>
- </div>
- <select
- className="collectionViewBaseChrome-viewPicker"
- onPointerDown={stopPropagation}
- onChange={this.viewChanged}
- value={StrCast(this.props.CollectionView.props.Document._viewType)}>
- {Object.values(CollectionViewType).map(type => ["invalid", "docking"].includes(type) ? (null) : (
- <option
- key={Utils.GenerateGuid()}
- className="collectionViewBaseChrome-viewOption"
- onPointerDown={stopPropagation}
- value={type}>
- {type[0].toUpperCase() + type.substring(1)}
- </option>
- ))}
- </select>
- </div>
- </div>
+ {this.viewModes}
<div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: collapsed ? "none" : "grid" }}>
<div className="collectionViewBaseChrome-filterIcon" onPointerDown={this.toggleViewSpecs} >
<FontAwesomeIcon icon="filter" size="2x" />
</div>
</div>
- <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} style={{ display: collapsed ? "none" : undefined }}>
- <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
- <div className="commandEntry-drop">
- <FontAwesomeIcon icon="bullseye" size="2x" />
- </div>
- <select
- className="collectionViewBaseChrome-cmdPicker"
- onPointerDown={stopPropagation}
- onChange={this.commandChanged}
- value={this._currentKey}>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={"empty"} value={""}>{""}</option>
- {this._buttonizableCommands.map(cmd =>
- <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={cmd.title} value={cmd.title}>{cmd.title}</option>
- )}
- </select>
- </div>
- </div>
+ {this.templateChrome}
</div>
- {this.subChrome()}
+ {this.subChrome}
</div>
</div>
);
@@ -329,6 +335,56 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
@observer
+export class CollectionFreeFormViewChrome extends React.Component<CollectionViewChromeProps> {
+
+ get Document() { return this.props.CollectionView.props.Document; }
+ @computed get dataField() {
+ return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)];
+ }
+ @computed get childDocs() {
+ return DocListCast(this.dataField);
+ }
+ @undoBatch
+ @action
+ nextKeyframe = (): void => {
+ const currentFrame = NumCast(this.Document.currentFrame);
+ if (currentFrame === undefined) {
+ this.Document.currentFrame = 0;
+ CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
+ }
+ CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0);
+ this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1);
+ this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame));
+ }
+ @undoBatch
+ @action
+ prevKeyframe = (): void => {
+ const currentFrame = NumCast(this.Document.currentFrame);
+ if (currentFrame === undefined) {
+ this.Document.currentFrame = 0;
+ CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
+ }
+ CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
+ this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1);
+ }
+ render() {
+ return this.Document.isAnnotationOverlay ? (null) :
+ <div className="collectionFreeFormViewChrome-cont">
+ <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
+ <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+ </div>
+ <div key="num" title="toggle view all" className="numKeyframe" style={{ backgroundColor: this.Document.editing ? "#759c75" : "#c56565" }}
+ onClick={action(() => this.Document.editing = !this.Document.editing)} >
+ {NumCast(this.Document.currentFrame)}
+ </div>
+ <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
+ <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+ </div>
+ </div>;
+ }
+}
+
+@observer
export class CollectionStackingViewChrome extends React.Component<CollectionViewChromeProps> {
@observable private _currentKey: string = "";
@observable private suggestions: string[] = [];
@@ -371,6 +427,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
this.suggestions = [];
}
+ @action
setValue = (value: string) => {
this.props.CollectionView.props.Document._pivotField = value;
return true;
@@ -473,19 +530,20 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
@observer
export class CollectionTreeViewChrome extends React.Component<CollectionViewChromeProps> {
- get dataExtension() {
- return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "_ext"] as Doc;
+ get sortAscending() {
+ return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"];
}
- @computed private get descending() {
- return this.dataExtension && Cast(this.dataExtension.sortAscending, "boolean", null);
+ set sortAscending(value) {
+ this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value;
+ }
+ @computed private get ascending() {
+ return Cast(this.sortAscending, "boolean", null);
}
@action toggleSort = () => {
- if (this.dataExtension) {
- if (this.dataExtension.sortAscending) this.dataExtension.sortAscending = undefined;
- else if (this.dataExtension.sortAscending === undefined) this.dataExtension.sortAscending = false;
- else this.dataExtension.sortAscending = true;
- }
+ if (this.sortAscending) this.sortAscending = undefined;
+ else if (this.sortAscending === undefined) this.sortAscending = false;
+ else this.sortAscending = true;
}
render() {
@@ -495,7 +553,7 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro
<div className="collectionTreeViewChrome-sortLabel">
Sort
</div>
- <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.descending === undefined ? "90" : this.descending ? "180" : "0"}deg)` }}>
+ <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.ascending === undefined ? "90" : this.ascending ? "180" : "0"}deg)` }}>
<FontAwesomeIcon icon="caret-up" size="2x" color="white" />
</div>
</button>
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 6e4f801c0..649406e6c 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -1,12 +1,12 @@
import * as React from "react";
import './ParentDocumentSelector.scss';
-import { Doc } from "../../../new_fields/Doc";
+import { Doc } from "../../../fields/Doc";
import { observer } from "mobx-react";
import { observable, action, runInAction, trace, computed, reaction, IReactionDisposer } from "mobx";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
import { SearchUtil } from "../../util/SearchUtil";
import { CollectionDockingView } from "./CollectionDockingView";
-import { NumCast, StrCast } from "../../../new_fields/Types";
+import { NumCast, StrCast } from "../../../fields/Types";
import { CollectionViewType } from "./CollectionView";
import { DocumentButtonBar } from "../DocumentButtonBar";
import { DocumentManager } from "../../util/DocumentManager";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 9a864078a..a4fd5384f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -1,15 +1,15 @@
-import { Doc, Field, FieldResult, WidthSym, HeightSym } from "../../../../new_fields/Doc";
-import { NumCast, StrCast, Cast } from "../../../../new_fields/Types";
+import { Doc, Field, FieldResult, WidthSym, HeightSym } from "../../../../fields/Doc";
+import { NumCast, StrCast, Cast } from "../../../../fields/Types";
import { ScriptBox } from "../../ScriptBox";
import { CompileScript } from "../../../util/Scripting";
-import { ScriptField } from "../../../../new_fields/ScriptField";
+import { ScriptField } from "../../../../fields/ScriptField";
import { OverlayView, OverlayElementOptions } from "../../OverlayView";
import { emptyFunction, aggregateBounds } from "../../../../Utils";
import React = require("react");
-import { Id, ToString } from "../../../../new_fields/FieldSymbols";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { RefField } from "../../../../new_fields/RefField";
-import { listSpec } from "../../../../new_fields/Schema";
+import { Id, ToString } from "../../../../fields/FieldSymbols";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { RefField } from "../../../../fields/RefField";
+import { listSpec } from "../../../../fields/Schema";
export interface ViewDefBounds {
type: string;
@@ -25,6 +25,7 @@ export interface ViewDefBounds {
fontSize?: number;
highlight?: boolean;
color?: string;
+ opacity?: number;
replica?: string;
pair?: { layout: Doc, data?: Doc };
}
@@ -37,6 +38,7 @@ export interface PoolData {
width?: number;
height?: number;
color?: string;
+ opacity?: number;
transition?: string;
highlight?: boolean;
replica: string;
@@ -416,7 +418,7 @@ function normalizeResults(
height: newPosRaw.height! * scale,
pair: ele[1].pair
};
- poolData.set(newPos.pair.layout[Id] + (newPos.replica || ""), { transition: "transform 1s", ...newPos });
+ poolData.set(newPos.pair.layout[Id] + (newPos.replica || ""), { transition: "all 1s", ...newPos });
}
});
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index ba71aff32..f3fc04752 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -1,5 +1,5 @@
import { observer } from "mobx-react";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
import { Utils } from '../../../../Utils';
import { DocumentView } from "../../nodes/DocumentView";
import "./CollectionFreeFormLinkView.scss";
@@ -7,8 +7,8 @@ import React = require("react");
import v5 = require("uuid/v5");
import { DocumentType } from "../../../documents/DocumentTypes";
import { observable, action, reaction, IReactionDisposer } from "mobx";
-import { StrCast, Cast } from "../../../../new_fields/Types";
-import { Id } from "../../../../new_fields/FieldSymbols";
+import { StrCast, Cast } from "../../../../fields/Types";
+import { Id } from "../../../../fields/FieldSymbols";
import { SnappingManager } from "../../../util/SnappingManager";
export interface CollectionFreeFormLinkViewProps {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 1208fb324..ae81b4b36 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -1,7 +1,7 @@
import { computed } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
+import { Doc } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
import { DocumentManager } from "../../../util/DocumentManager";
import { DocumentView } from "../../nodes/DocumentView";
import "./CollectionFreeFormLinksView.scss";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 92fa2781c..548ad78a5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -1,16 +1,16 @@
import { observer } from "mobx-react";
import * as mobxUtils from 'mobx-utils';
-import CursorField from "../../../../new_fields/CursorField";
-import { listSpec } from "../../../../new_fields/Schema";
-import { Cast } from "../../../../new_fields/Types";
-import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
+import CursorField from "../../../../fields/CursorField";
+import { listSpec } from "../../../../fields/Schema";
+import { Cast } from "../../../../fields/Types";
+import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
import { CollectionViewProps } from "../CollectionSubView";
import "./CollectionFreeFormView.scss";
import React = require("react");
import v5 = require("uuid/v5");
import { computed } from "mobx";
-import { FieldResult } from "../../../../new_fields/Doc";
-import { List } from "../../../../new_fields/List";
+import { FieldResult } from "../../../../fields/Doc";
+import { List } from "../../../../fields/List";
@observer
export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 60c39c825..d9011c9d3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -41,6 +41,7 @@
// touch action none means that the browser will handle none of the touch actions. this allows us to implement our own actions.
touch-action: none;
+
.collectionfreeformview-placeholder {
background: gray;
width: 100%;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 6caee960d..c753a703d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,24 +1,24 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons";
import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed, trace } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
-import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../new_fields/Doc";
-import { documentSchema, collectionSchema } from "../../../../new_fields/documentSchemas";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { InkData, InkField, InkTool, PointData } from "../../../../new_fields/InkField";
-import { List } from "../../../../new_fields/List";
-import { RichTextField } from "../../../../new_fields/RichTextField";
-import { createSchema, listSpec, makeInterface } from "../../../../new_fields/Schema";
-import { ScriptField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../new_fields/Types";
-import { TraceMobx } from "../../../../new_fields/util";
+import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../fields/Doc";
+import { documentSchema, collectionSchema } from "../../../../fields/documentSchemas";
+import { Id } from "../../../../fields/FieldSymbols";
+import { InkData, InkField, InkTool, PointData } from "../../../../fields/InkField";
+import { List } from "../../../../fields/List";
+import { RichTextField } from "../../../../fields/RichTextField";
+import { createSchema, listSpec, makeInterface } from "../../../../fields/Schema";
+import { ScriptField, ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
+import { TraceMobx } from "../../../../fields/util";
import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { aggregateBounds, intersectRect, returnOne, Utils, returnZero, returnFalse } from "../../../../Utils";
+import { aggregateBounds, intersectRect, returnOne, Utils, returnZero, returnFalse, numberRange } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
-import { Docs } from "../../../documents/Documents";
+import { Docs, DocUtils } from "../../../documents/Documents";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager, dropActionType } from "../../../util/DragManager";
import { HistoryUtil } from "../../../util/History";
@@ -46,6 +46,7 @@ import React = require("react");
import { CollectionViewType } from "../CollectionView";
import { Timeline } from "../../animationtimeline/Timeline";
import { SnappingManager } from "../../../util/SnappingManager";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
@@ -53,6 +54,9 @@ export const panZoomSchema = createSchema({
_panX: "number",
_panY: "number",
scale: "number",
+ currentTimecode: "number",
+ displayTimecode: "number",
+ currentFrame: "number",
arrangeScript: ScriptField,
arrangeInit: ScriptField,
useClusters: "boolean",
@@ -72,6 +76,7 @@ const PanZoomDocument = makeInterface(panZoomSchema, collectionSchema, documentS
export type collectionFreeformViewProps = {
forceScaling?: boolean; // whether to force scaling of content (needed by ImageBox)
viewDefDivClick?: ScriptField;
+ childPointerEvents?: boolean;
};
@observer
@@ -113,27 +118,66 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)) :
this.Document.scale || 1)
- private centeringShiftX = () => !this.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / this.contentScaling : 0; // shift so pan position is at center of window for non-overlay collections
- private centeringShiftY = () => !this.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / this.contentScaling : 0;// shift so pan position is at center of window for non-overlay collections
- private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
- private getTransformOverlay = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1);
- private getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
- private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
+ @computed get cachedCenteringShiftX(): number {
+ return !this.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / this.contentScaling : 0; // shift so pan position is at center of window for non-overlay collections
+ }
+ @computed get cachedCenteringShiftY(): number {
+ return !this.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / this.contentScaling : 0;// shift so pan position is at center of window for non-overlay collections
+ }
+ @computed get cachedGetLocalTransform(): Transform {
+ return Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
+ }
+ @computed get cachedGetContainerTransform(): Transform {
+ return this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
+ }
+ @computed get cachedGetTransform(): Transform {
+ return this.getTransformOverlay().translate(- this.cachedCenteringShiftX, - this.cachedCenteringShiftY).transform(this.cachedGetLocalTransform);
+ }
+
+ private centeringShiftX = () => this.cachedCenteringShiftX;
+ private centeringShiftY = () => this.cachedCenteringShiftY;
+ private getTransform = () => this.cachedGetTransform.copy();
+ private getLocalTransform = () => this.cachedGetLocalTransform.copy();
+ private getContainerTransform = () => this.cachedGetContainerTransform.copy();
+ private getTransformOverlay = () => this.getContainerTransform().translate(1, 1);
private addLiveTextBox = (newBox: Doc) => {
FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newBox);
}
- private addDocument = (newBox: Doc | Doc[]) => {
+ addDocument = action((newBox: Doc | Doc[]) => {
+ let retVal = false;
if (newBox instanceof Doc) {
- const added = this.props.addDocument(newBox);
- added && this.bringToFront(newBox);
- added && this.updateCluster(newBox);
- return added;
+ retVal = this.props.addDocument(newBox);
+ retVal && this.bringToFront(newBox);
+ retVal && this.updateCluster(newBox);
} else {
- return this.props.addDocument(newBox);
+ retVal = this.props.addDocument(newBox);
// bcz: deal with clusters
}
- }
+ if (retVal) {
+ const newBoxes = (newBox instanceof Doc) ? [newBox] : newBox;
+ for (let i = 0; i < newBoxes.length; i++) {
+ const newBox = newBoxes[i];
+ if (newBox.activeFrame !== undefined) {
+ const x = newBox.x;
+ const y = newBox.y;
+ delete newBox["x-indexed"];
+ delete newBox["y-indexed"];
+ delete newBox["opacity-indexed"];
+ delete newBox.x;
+ delete newBox.y;
+ delete newBox.activeFrame;
+ newBox.x = x;
+ newBox.y = y;
+ }
+ }
+ if (this.Document.currentFrame !== undefined && !this.props.isAnnotationOverlay) {
+ CollectionFreeFormDocumentView.setupKeyframes(newBoxes, this.Document.currentFrame);
+ }
+ }
+ return retVal;
+ })
+
private selectDocuments = (docs: Doc[]) => {
SelectionManager.DeselectAll();
docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).map(dv => dv && SelectionManager.SelectDoc(dv, true));
@@ -159,6 +203,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const [xp, yp] = xf.transformPoint(de.x, de.y);
const [xpo, ypo] = xfo.transformPoint(de.x, de.y);
const zsorted = this.childLayoutPairs.map(pair => pair.layout).slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
+ if (!this.isAnnotationOverlay && de.complete.linkDragData && de.complete.linkDragData.linkSourceDocument !== this.props.Document) {
+ const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
+ this.props.addDocument(source);
+ (de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: de.complete.linkDragData.linkSourceDocument },
+ "doc annotation")); // TODODO this is where in text links get passed
+ e.stopPropagation();
+ return true;
+ }
if (super.onInternalDrop(e, de)) {
if (de.complete.docDragData) {
if (de.complete.docDragData.droppedDocuments.length) {
@@ -174,8 +226,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
for (let i = 0; i < droppedDocs.length; i++) {
const d = droppedDocs[i];
const layoutDoc = Doc.Layout(d);
- d.x = x + NumCast(d.x) - dropX;
- d.y = y + NumCast(d.y) - dropY;
+ if (this.Document.currentFrame !== undefined && !this.props.isAnnotationOverlay) {
+ const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000));
+ CollectionFreeFormDocumentView.setValues(this.Document.currentFrame, d, x + vals.x - dropX, y + vals.y - dropY, vals.opacity);
+ } else {
+ d.x = x + NumCast(d.x) - dropX;
+ d.y = y + NumCast(d.y) - dropY;
+ }
if (!NumCast(layoutDoc._width)) {
layoutDoc._width = 300;
}
@@ -401,7 +458,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
case GestureUtils.Gestures.Stroke:
const points = ge.points;
const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
- const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { title: "ink stroke", x: B.x, y: B.y, _width: B.width, _height: B.height });
+ const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, InkingControl.Instance.selectedWidth, points, { title: "ink stroke", x: B.x, y: B.y, _width: B.width, _height: B.height });
this.addDocument(inkDoc);
e.stopPropagation();
break;
@@ -437,9 +494,9 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
console.log("end");
if (this._inkToTextStartX && this._inkToTextStartY) {
const end = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y)));
- const setDocs = this.getActiveDocuments().filter(s => s.proto?.type === "text" && s.color);
+ const setDocs = this.getActiveDocuments().filter(s => s.proto?.type === "rtf" && s.color);
const sets = setDocs.map((sd) => {
- return Cast(sd.data, RichTextField)?.Text as string;
+ return Cast(sd.text, RichTextField)?.Text as string;
});
if (sets.length && sets[0]) {
this._wordPalette.clear();
@@ -475,6 +532,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
});
+ console.log(this._wordPalette)
CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then((results) => {
console.log(results);
const wordResults = results.filter((r: any) => r.category === "inkWord");
@@ -733,7 +791,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@action
onPointerWheel = (e: React.WheelEvent): void => {
- if (this.props.Document.lockedTransform || this.props.Document.inOverlay) return;
+ if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay) return;
if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming
e.stopPropagation();
}
@@ -769,7 +827,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
else if (ranges.yrange.max <= (panY - panelDim[1] / 2)) panY = ranges.yrange.min - panelDim[1] / 2;
}
}
- if (!this.Document.lockedTransform || this.Document.inOverlay) {
+ if (!this.layoutDoc._lockedTransform || this.Document.inOverlay) {
this.Document.panTransformType = panType;
const scale = this.getLocalTransform().inverse().Scale;
const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
@@ -893,6 +951,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
FreezeDimensions: this.props.freezeChildDimensions,
layoutKey: undefined,
setupDragLines: this.setupDragLines,
+ dontRegisterView: this.props.dontRegisterView,
rootSelected: childData ? this.rootSelected : returnFalse,
dropAction: StrCast(this.props.Document.childDropAction) as dropActionType,
onClick: this.onChildClickHandler,
@@ -941,9 +1000,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return { x: 0, y: 0, transition: "transform 1s", ...result, pair: params.pair, replica: "" };
}
const layoutDoc = Doc.Layout(params.pair.layout);
- const { x, y, z, color, zIndex } = params.pair.layout;
+ const { x, y, opacity } = this.Document.currentFrame === undefined ? params.pair.layout :
+ CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document.currentFrame || 0);
+ const { z, color, zIndex } = params.pair.layout;
return {
x: NumCast(x), y: NumCast(y), z: Cast(z, "number"), color: StrCast(color), zIndex: Cast(zIndex, "number"),
+ transition: StrCast(layoutDoc.transition), opacity: this.Document.editing ? 1 : Cast(opacity, "number", null),
width: Cast(layoutDoc._width, "number"), height: Cast(layoutDoc._height, "number"), pair: params.pair, replica: ""
};
}
@@ -1003,8 +1065,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
doFreeformLayout(poolData: Map<string, PoolData>) {
const layoutDocs = this.childLayoutPairs.map(pair => pair.layout);
const initResult = this.Document.arrangeInit && this.Document.arrangeInit.script.run({ docs: layoutDocs, collection: this.Document }, console.log);
- const state = initResult && initResult.success ? initResult.result.scriptState : undefined;
- const elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
+ const state = initResult?.success ? initResult.result.scriptState : undefined;
+ const elements = initResult?.success ? this.viewDefsToJSX(initResult.result.views) : [];
this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => {
const pos = this.getCalculatedPositions({ pair, index: i, collection: this.Document, docs: layoutDocs, state });
@@ -1032,11 +1094,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const { newPool, computedElementData } = this.doInternalLayoutComputation;
const array = Array.from(newPool.entries());
runInAction(() => {
- for (let i = 0; i < array.length; i++) {
- const entry = array[i];
+ for (const entry of array) {
const lastPos = this._cachedPool.get(entry[0]); // last computed pos
const newPos = entry[1];
- if (!lastPos || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.zIndex !== lastPos.zIndex) {
+ if (!lastPos || newPos.opacity !== lastPos.opacity || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.zIndex !== lastPos.zIndex) {
this._layoutPoolData.set(entry[0], newPos);
}
if (!lastPos || newPos.height !== lastPos.height || newPos.width !== lastPos.width) {
@@ -1056,11 +1117,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
replica={entry[1].replica}
dataProvider={this.childDataProvider}
sizeProvider={this.childSizeProvider}
- pointerEvents={
- this.backgroundActive ?
- true :
- (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? false : undefined}
- jitterRotation={NumCast(this.props.Document._jitterRotation)}
+ pointerEvents={this.backgroundActive || this.props.childPointerEvents ?
+ true :
+ (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? false : 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.freezeChildDimensions)} // bcz: check this
FreezeDimensions={BoolCast(this.props.freezeChildDimensions)}
@@ -1130,6 +1190,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth(), this.props.NativeHeight());
}
+ @undoBatch
+ @action
+ toggleLockTransform = (): void => {
+ this.layoutDoc._lockedTransform = this.layoutDoc._lockedTransform ? undefined : true;
+ }
+
private thumbIdentifier?: number;
onContextMenu = (e: React.MouseEvent) => {
@@ -1145,11 +1211,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" });
+ optionItems.push({ description: "toggle snap line display", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" });
optionItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
optionItems.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
optionItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
optionItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
this.props.ContainingCollectionView && optionItems.push({ description: "Promote 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" });
optionItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
// layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" });
optionItems.push({
@@ -1275,8 +1343,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
getContainerTransform={this.getContainerTransform}
getTransform={this.getTransform}
isAnnotationOverlay={this.isAnnotationOverlay}>
- <CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY} shifted={!this.nativeHeight && !this.isAnnotationOverlay}
- easing={this.easing} viewDefDivClick={this.props.viewDefDivClick} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
+ <CollectionFreeFormViewPannableContents
+ centeringShiftX={this.centeringShiftX}
+ centeringShiftY={this.centeringShiftY}
+ shifted={!this.nativeHeight && !this.isAnnotationOverlay}
+ easing={this.easing}
+ transition={Cast(this.layoutDoc.transition, "string", null)}
+ viewDefDivClick={this.props.viewDefDivClick}
+ zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
{this.children}
</CollectionFreeFormViewPannableContents>
{this._timelineVisible ? <Timeline ref={this._timelineRef} {...this.props} /> : (null)}
@@ -1295,18 +1369,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
render() {
TraceMobx();
const clientRect = this._mainCont?.getBoundingClientRect();
- // update the actual dimensions of the collection so that they can inquired (e.g., by a minimap)
- // this.Document.fitX = this.contentBounds && this.contentBounds.x;
- // this.Document.fitY = this.contentBounds && this.contentBounds.y;
- // this.Document.fitW = this.contentBounds && (this.contentBounds.r - this.contentBounds.x);
- // this.Document.fitH = this.contentBounds && (this.contentBounds.b - this.contentBounds.y);
- // if isAnnotationOverlay is set, then children will be stored in the extension document for the fieldKey.
- // otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document
- return <div className={"collectionfreeformview-container"}
- ref={this.createDashEventsTarget}
+ return <div className={"collectionfreeformview-container"} ref={this.createDashEventsTarget}
onPointerOver={this.onPointerOver}
- onWheel={this.onPointerWheel} onClick={this.onClick} //pointerEvents: DraggingManager.GetIsDragging() ? "all" : undefined,
- onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onExternalDrop.bind(this)} onContextMenu={this.onContextMenu}
+ onWheel={this.onPointerWheel}
+ onClick={this.onClick}
+ onPointerDown={this.onPointerDown}
+ onPointerMove={this.onCursorMove}
+ onDrop={this.onExternalDrop.bind(this)}
+ onDragOver={e => {
+ e.preventDefault();
+ }}
+ onContextMenu={this.onContextMenu}
style={{
pointerEvents: this.backgroundEvents ? "all" : undefined,
transform: this.contentScaling ? `scale(${this.contentScaling})` : "",
@@ -1322,7 +1395,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
style={{
display: this._pullDirection ? "block" : "none",
top: clientRect ? this._pullDirection === "bottom" ? this._pullCoords[1] - clientRect.y : 0 : "auto",
- // left: clientRect ? this._pullDirection === "right" ? this._pullCoords[0] - clientRect.x - MainView.Instance.flyoutWidth : 0 : "auto",
left: clientRect ? this._pullDirection === "right" ? this._pullCoords[0] - clientRect.x : 0 : "auto",
width: clientRect ? this._pullDirection === "left" ? this._pullCoords[0] - clientRect.left : this._pullDirection === "right" ? clientRect.right - this._pullCoords[0] : clientRect.width : 0,
height: clientRect ? this._pullDirection === "top" ? this._pullCoords[1] - clientRect.top : this._pullDirection === "bottom" ? clientRect.bottom - this._pullCoords[1] : clientRect.height : 0,
@@ -1361,6 +1433,7 @@ interface CollectionFreeFormViewPannableContentsProps {
viewDefDivClick?: ScriptField;
children: () => JSX.Element[];
shifted: boolean;
+ transition?: string;
}
@observer
@@ -1375,7 +1448,8 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
return <div className={freeformclass}
style={{
width: this.props.shifted ? 0 : undefined, height: this.props.shifted ? 0 : undefined,
- transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`
+ transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`,
+ transition: this.props.transition
}}>
{this.props.children()}
</div>;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 8e20b39d2..cdfeeaa6b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,11 +1,11 @@
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Opt } from "../../../../new_fields/Doc";
-import { InkData, InkField } from "../../../../new_fields/InkField";
-import { List } from "../../../../new_fields/List";
-import { RichTextField } from "../../../../new_fields/RichTextField";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc, Opt } from "../../../../fields/Doc";
+import { InkData, InkField } from "../../../../fields/InkField";
+import { List } from "../../../../fields/List";
+import { RichTextField } from "../../../../fields/RichTextField";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types";
import { Utils } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents";
@@ -65,58 +65,69 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
//make textbox and add it to this collection
// tslint:disable-next-line:prefer-const
let [x, y] = this.props.getTransform().transformPoint(this._downX, this._downY);
- if (e.key === ":") {
- DocUtils.addDocumentCreatorMenuItems(this.props.addLiveTextDocument, this.props.addDocument, x, y);
+ if (e.key === "?") {
+ ContextMenu.Instance.setDefaultItem("?", (str: string) => {
+ const textDoc = Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, {
+ _width: 200, x, y, _nativeHeight: 962, _nativeWidth: 800, isAnnotating: false,
+ title: "bing", UseCors: true
+ });
+ this.props.addDocTab(textDoc, "onRight");
+ });
ContextMenu.Instance.displayMenu(this._downX, this._downY);
- } else if (e.key === "q" && e.ctrlKey) {
- e.preventDefault();
- (async () => {
- const text: string = await navigator.clipboard.readText();
- const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
- for (let i = 0; i < ns.length - 1; i++) {
- while (!(ns[i].trim() === "" || ns[i].endsWith("-\r") || ns[i].endsWith("-") ||
- ns[i].endsWith(";\r") || ns[i].endsWith(";") ||
- ns[i].endsWith(".\r") || ns[i].endsWith(".") ||
- ns[i].endsWith(":\r") || ns[i].endsWith(":")) && i < ns.length - 1) {
- const sub = ns[i].endsWith("\r") ? 1 : 0;
- const br = ns[i + 1].trim() === "";
- ns.splice(i, 2, ns[i].substr(0, ns[i].length - sub) + ns[i + 1].trimLeft());
- if (br) break;
+ } else
+ if (e.key === ":") {
+ DocUtils.addDocumentCreatorMenuItems(this.props.addLiveTextDocument, this.props.addDocument, x, y);
+
+ ContextMenu.Instance.displayMenu(this._downX, this._downY);
+ } else if (e.key === "q" && e.ctrlKey) {
+ e.preventDefault();
+ (async () => {
+ const text: string = await navigator.clipboard.readText();
+ const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
+ for (let i = 0; i < ns.length - 1; i++) {
+ while (!(ns[i].trim() === "" || ns[i].endsWith("-\r") || ns[i].endsWith("-") ||
+ ns[i].endsWith(";\r") || ns[i].endsWith(";") ||
+ ns[i].endsWith(".\r") || ns[i].endsWith(".") ||
+ ns[i].endsWith(":\r") || ns[i].endsWith(":")) && i < ns.length - 1) {
+ const sub = ns[i].endsWith("\r") ? 1 : 0;
+ const br = ns[i + 1].trim() === "";
+ ns.splice(i, 2, ns[i].substr(0, ns[i].length - sub) + ns[i + 1].trimLeft());
+ if (br) break;
+ }
+ }
+ ns.map(line => {
+ const indent = line.search(/\S|$/);
+ const newBox = Docs.Create.TextDocument(line, { _width: 200, _height: 35, x: x + indent / 3 * 10, y: y, title: line });
+ this.props.addDocument(newBox);
+ y += 40 * this.props.getTransform().Scale;
+ });
+ })();
+ } else if (e.key === "b" && e.ctrlKey) {
+ e.preventDefault();
+ navigator.clipboard.readText().then(text => {
+ const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
+ if (ns.length === 1 && text.startsWith("http")) {
+ this.props.addDocument(Docs.Create.ImageDocument(text, { _nativeWidth: 300, _width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer
+ } else {
+ this.pasteTable(ns, x, y);
}
- }
- ns.map(line => {
- const indent = line.search(/\S|$/);
- const newBox = Docs.Create.TextDocument(line, { _width: 200, _height: 35, x: x + indent / 3 * 10, y: y, title: line });
- this.props.addDocument(newBox);
- y += 40 * this.props.getTransform().Scale;
});
- })();
- } else if (e.key === "b" && e.ctrlKey) {
- e.preventDefault();
- navigator.clipboard.readText().then(text => {
- const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
- if (ns.length === 1 && text.startsWith("http")) {
- this.props.addDocument(Docs.Create.ImageDocument(text, { _nativeWidth: 300, _width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer
- } else {
- this.pasteTable(ns, x, y);
+ } else if (!e.ctrlKey) {
+ FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout ? e.key : "";
+ const tbox = Docs.Create.TextDocument("", {
+ _width: 200, _height: 100, x: x, y: y, _autoHeight: true, _fontSize: NumCast(Doc.UserDoc().fontSize),
+ _fontFamily: StrCast(Doc.UserDoc().fontFamily), _backgroundColor: StrCast(Doc.UserDoc().backgroundColor),
+ title: "-typed text-"
+ });
+ const template = FormattedTextBox.DefaultLayout;
+ if (template instanceof Doc) {
+ tbox._width = NumCast(template._width);
+ tbox.layoutKey = "layout_" + StrCast(template.title);
+ Doc.GetProto(tbox)[StrCast(tbox.layoutKey)] = template;
}
- });
- } else if (!e.ctrlKey) {
- FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout ? e.key : "";
- const tbox = Docs.Create.TextDocument("", {
- _width: 200, _height: 100, x: x, y: y, _autoHeight: true, _fontSize: NumCast(Doc.UserDoc().fontSize),
- _backgroundColor: StrCast(Doc.UserDoc().backgroundColor),
- title: "-typed text-"
- });
- const template = FormattedTextBox.DefaultLayout;
- if (template instanceof Doc) {
- tbox._width = NumCast(template._width);
- tbox.layoutKey = "layout_" + StrCast(template.title);
- Doc.GetProto(tbox)[StrCast(tbox.layoutKey)] = template;
+ this.props.addLiveTextDocument(tbox);
}
- this.props.addLiveTextDocument(tbox);
- }
e.stopPropagation();
}
//heuristically converts pasted text into a table.
@@ -164,12 +175,13 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
onPointerDown = (e: React.PointerEvent): void => {
this._downX = this._lastX = e.clientX;
this._downY = this._lastY = e.clientY;
- if (e.button === 2 || (e.button === 0 && (e.altKey || MarqueeView.DragMarquee))) {
- if (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))) {
- this.setPreviewCursor(e.clientX, e.clientY, true);
- // (!e.altKey) && e.stopPropagation(); // bcz: removed so that you can alt-click on button in a collection to switch link following behaviors.
- e.preventDefault();
- }
+ // allow marquee if right click OR alt+left click OR space bar + left click
+ if (e.button === 2 || (e.button === 0 && (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))))) {
+ // if (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))) {
+ this.setPreviewCursor(e.clientX, e.clientY, true);
+ // (!e.altKey) && e.stopPropagation(); // bcz: removed so that you can alt-click on button in a collection to switch link following behaviors.
+ e.preventDefault();
+ // }
// bcz: do we need this? it kills the context menu on the main collection if !altKey
// e.stopPropagation();
}
@@ -322,9 +334,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
_LODdisable: true,
title: "a nested collection",
});
- // const dataExtensionField = Doc.CreateDocumentExtensionForField(newCollection, "data");
- // dataExtensionField.ink = inkData ? new InkField(this.marqueeInkSelect(inkData)) : undefined;
- // this.marqueeInkDelete(inkData);
+ selected.forEach(d => d.context = newCollection);
this.hideMarquee();
return newCollection;
}
@@ -335,8 +345,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
SelectionManager.DeselectAll();
selected.forEach(d => this.props.removeDocument(d));
const newCollection = Doc.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2);
- this.props.addDocument(newCollection);
- this.props.selectDocuments([newCollection], []);
+ this.props.addDocument(newCollection!);
+ this.props.selectDocuments([newCollection!], []);
MarqueeOptionsMenu.Instance.fadeOut(true);
this.hideMarquee();
}
@@ -347,10 +357,14 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const selected = this.marqueeSelect(false);
if (e instanceof KeyboardEvent ? e.key === "c" : true) {
selected.map(action(d => {
- //this.props.removeDocument(d);
- d.x = NumCast(d.x) - bounds.left - bounds.width / 2;
- d.y = NumCast(d.y) - bounds.top - bounds.height / 2;
- d.displayTimecode = undefined; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+ const dx = NumCast(d.x);
+ const dy = NumCast(d.y);
+ delete d.x;
+ delete d.y;
+ delete d.activeFrame;
+ delete d.displayTimecode; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+ d.x = dx - bounds.left - bounds.width / 2;
+ d.y = dy - bounds.top - bounds.height / 2;
return d;
}));
this.props.removeDocument(selected);
@@ -612,6 +626,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
render() {
return <div className="marqueeView"
style={{ overflow: 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}
{this.props.children}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index a09124304..c0e1a0232 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,10 +1,10 @@
import { action, computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from "react";
-import { Doc } from '../../../../new_fields/Doc';
-import { documentSchema } from '../../../../new_fields/documentSchemas';
-import { makeInterface } from '../../../../new_fields/Schema';
-import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../new_fields/Types';
+import { Doc } from '../../../../fields/Doc';
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { makeInterface } from '../../../../fields/Schema';
+import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../fields/Types';
import { DragManager, dropActionType } from '../../../util/DragManager';
import { Transform } from '../../../util/Transform';
import { undoBatch } from '../../../util/UndoManager';
@@ -13,7 +13,7 @@ import { CollectionSubView } from '../CollectionSubView';
import "./collectionMulticolumnView.scss";
import ResizeBar from './MulticolumnResizer';
import WidthLabel from './MulticolumnWidthLabel';
-import { List } from '../../../../new_fields/List';
+import { List } from '../../../../fields/List';
import { returnZero, returnFalse, returnOne } from '../../../../Utils';
type MulticolumnDocument = makeInterface<[typeof documentSchema]>;
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 4326723b1..602246d07 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -1,10 +1,10 @@
import { observer } from 'mobx-react';
-import { makeInterface } from '../../../../new_fields/Schema';
-import { documentSchema } from '../../../../new_fields/documentSchemas';
+import { makeInterface } from '../../../../fields/Schema';
+import { documentSchema } from '../../../../fields/documentSchemas';
import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import * as React from "react";
-import { Doc } from '../../../../new_fields/Doc';
-import { NumCast, StrCast, BoolCast, ScriptCast } from '../../../../new_fields/Types';
+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";
@@ -14,7 +14,7 @@ import HeightLabel from './MultirowHeightLabel';
import ResizeBar from './MultirowResizer';
import { undoBatch } from '../../../util/UndoManager';
import { DragManager, dropActionType } from '../../../util/DragManager';
-import { List } from '../../../../new_fields/List';
+import { List } from '../../../../fields/List';
type MultirowDocument = makeInterface<[typeof documentSchema]>;
const MultirowDocument = makeInterface(documentSchema);
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index a24eb1631..734915a93 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -1,8 +1,8 @@
import * as React from "react";
import { observer } from "mobx-react";
import { observable, action } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast } from "../../../../fields/Types";
import { DimUnit } from "./CollectionMulticolumnView";
import { UndoManager } from "../../../util/UndoManager";
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
index 5b2054428..9985a9fba 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
@@ -1,8 +1,8 @@
import * as React from "react";
import { observer } from "mobx-react";
import { computed } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast, BoolCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast, BoolCast } from "../../../../fields/Types";
import { EditableView } from "../../EditableView";
import { DimUnit } from "./CollectionMulticolumnView";
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
index 899577fd5..aa5439fa4 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
@@ -1,8 +1,8 @@
import * as React from "react";
import { observer } from "mobx-react";
import { computed } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast, BoolCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast, BoolCast } from "../../../../fields/Types";
import { EditableView } from "../../EditableView";
import { DimUnit } from "./CollectionMultirowView";
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index 5f00b18b9..d0bc4d01c 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -1,8 +1,8 @@
import * as React from "react";
import { observer } from "mobx-react";
import { observable, action } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast } from "../../../../fields/Types";
import { DimUnit } from "./CollectionMultirowView";
import { UndoManager } from "../../../util/UndoManager";