aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx2
-rw-r--r--src/client/views/collections/CollectionMenu.tsx244
-rw-r--r--src/client/views/collections/CollectionSubView.tsx12
-rw-r--r--src/client/views/collections/CollectionView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx40
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx7
6 files changed, 159 insertions, 154 deletions
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 407524353..3b31947f7 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -176,7 +176,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
}}
onPointerDown={e => e.stopPropagation()} >
<span className="bottomPopup-text" >
- Creating link from: {DocumentLinksButton.StartLink.title}
+ Creating link from: {DocumentLinksButton.StartLink.props.Document.title}
</span>
<Tooltip title={<><div className="dash-tooltip">{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 1fbaaa08a..b81f00bc4 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -32,16 +32,28 @@ import { RichTextField } from "../../../fields/RichTextField";
export default class CollectionMenu extends AntimodeMenu {
static Instance: CollectionMenu;
- @observable SelectedCollection: CollectionView | undefined;
+ @observable SelectedCollection: DocumentView | undefined;
+ @observable FieldKey: string;
constructor(props: Readonly<{}>) {
super(props);
+ this.FieldKey = "";
CollectionMenu.Instance = this;
this._canFade = false; // don't let the inking menu fade away
this.Pinned = Cast(Doc.UserDoc()["menuCollections-pinned"], "boolean", true);
this.jumpTo(300, 300);
}
+ componentDidMount() {
+ reaction(() => SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0],
+ (doc) => doc && this.SetSelection(doc))
+ }
+
+ @action
+ SetSelection(view: DocumentView) {
+ this.SelectedCollection = view;
+ }
+
@action
toggleMenuPin = (e: React.MouseEvent) => {
Doc.UserDoc()["menuCollections-pinned"] = this.Pinned = !this.Pinned;
@@ -56,14 +68,18 @@ export default class CollectionMenu extends AntimodeMenu {
</button>;
return this.getElement(!this.SelectedCollection ? [button] :
- [<CollectionViewBaseChrome key="chrome" CollectionView={this.SelectedCollection} type={StrCast(this.SelectedCollection.props.Document._viewType) as CollectionViewType} />,
+ [<CollectionViewBaseChrome key="chrome"
+ docView={this.SelectedCollection}
+ fieldKey={Doc.LayoutFieldKey(this.SelectedCollection?.props.Document)}
+ type={StrCast(this.SelectedCollection?.props.Document._viewType, CollectionViewType.Invalid) as CollectionViewType} />,
button]);
}
}
interface CollectionMenuProps {
- CollectionView: CollectionView;
type: CollectionViewType;
+ fieldKey: string;
+ docView: DocumentView;
}
const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
@@ -72,7 +88,8 @@ const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
export class CollectionViewBaseChrome extends React.Component<CollectionMenuProps> {
//(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
- get target() { return this.props.CollectionView.props.Document; }
+ get document() { return this.props.docView?.props.Document; }
+ get target() { return this.document; }
_templateCommand = {
params: ["target", "source"], title: "item view",
script: "self.target.childLayoutTemplate = getDocTemplate(self.source?.[0])",
@@ -86,11 +103,21 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
initialize: emptyFunction,
};
_contentCommand = {
- params: ["target", "source"], title: "clear content",
+ params: ["target", "source"], title: "set content",
script: "getProto(self.target).data = copyField(self.source);",
immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List<Doc>(source)), // Doc.aliasDocs(source),
initialize: emptyFunction,
};
+ _onClickCommand = {
+ params: ["target", "proxy"], title: "copy onClick",
+ script: `{ if (self.proxy?.[0]) {
+ getProto(self.proxy[0]).onClick = copyField(self.target.onClick);
+ getProto(self.proxy[0]).target = self.target.target;
+ getProto(self.proxy[0]).source = copyField(self.target.source);
+ }}`,
+ immediate: undoBatch((source: Doc[]) => { }),
+ initialize: emptyFunction,
+ };
_viewCommand = {
params: ["target"], title: "bookmark view",
script: "self.target._panX = self['target-panX']; self.target._panY = self['target-panY']; self.target._viewScale = self['target-viewScale'];",
@@ -120,19 +147,20 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
_stacking_commands = [this._contentCommand, this._templateCommand];
_masonry_commands = [this._contentCommand, this._templateCommand];
_schema_commands = [this._templateCommand, this._narrativeCommand];
+ _doc_commands = [this._onClickCommand];
_tree_commands = [];
private get _buttonizableCommands() {
switch (this.props.type) {
+ default: return this._doc_commands;
+ case CollectionViewType.Freeform: return this._freeform_commands;
case CollectionViewType.Tree: return this._tree_commands;
case CollectionViewType.Schema: return this._schema_commands;
case CollectionViewType.Stacking: return this._stacking_commands;
case CollectionViewType.Masonry: return this._stacking_commands;
- case CollectionViewType.Freeform: return this._freeform_commands;
case CollectionViewType.Time: return this._freeform_commands;
case CollectionViewType.Carousel: return this._freeform_commands;
case CollectionViewType.Carousel3D: return this._freeform_commands;
}
- return [];
}
private _picker: any;
private _commandRef = React.createRef<HTMLInputElement>();
@@ -167,21 +195,16 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
@computed get subChrome() {
switch (this.props.type) {
- case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- case CollectionViewType.Carousel3D: return (<Collection3DCarouselViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- case CollectionViewType.Grid: return (<CollectionGridViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
- default: return null;
+ default:
+ case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} />);
+ case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
+ case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" {...this.props} />);
+ case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" {...this.props} />);
+ case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
+ case CollectionViewType.Carousel3D: return (<Collection3DCarouselViewChrome key="collchrome" {...this.props} />);
+ case CollectionViewType.Grid: return (<CollectionGridViewChrome key="collchrome" {...this.props} />);
}
}
-
- private get document() {
- return this.props.CollectionView.props.Document;
- }
-
private dropDisposer?: DragManager.DragDropDisposer;
protected createDropTarget = (ele: HTMLDivElement) => {
this.dropDisposer?.();
@@ -203,15 +226,15 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
dragViewDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, (e, down, delta) => {
- const vtype = this.props.CollectionView.collectionViewType;
+ const vtype = this.props.type;
const c = {
params: ["target"], title: vtype,
- script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`,
- immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]),
+ script: `this.target._viewType = '${StrCast(this.props.type)}'`,
+ immediate: (source: Doc[]) => this.document._viewType = Doc.getDocTemplate(source?.[0]),
initialize: emptyFunction,
};
DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title),
- { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY);
+ { target: this.document }, c.params, c.initialize, e.clientX, e.clientY);
return true;
}, emptyFunction, emptyFunction);
}
@@ -219,7 +242,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
setupMoveUpEvents(this, e, (e, down, delta) => {
this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c =>
DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
- { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY));
+ { target: this.document }, c.params, c.initialize, e.clientX, e.clientY));
return true;
}, emptyFunction, () => {
this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate([]));
@@ -253,7 +276,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
className="collectionViewBaseChrome-viewPicker"
onPointerDown={stopPropagation}
onChange={this.viewChanged}
- value={StrCast(this.props.CollectionView.props.Document._viewType)}>
+ value={StrCast(this.props.type)}>
{Object.values(CollectionViewType).map(type => [CollectionViewType.Invalid, CollectionViewType.Docking].includes(type) ? (null) : (
<option
key={Utils.GenerateGuid()}
@@ -286,7 +309,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
<div className="collectionMenu-cont" >
<div className="collectionMenu">
<div className="collectionViewBaseChrome">
- {!(this.isText && this.props.type === CollectionViewType.Freeform) ? this.viewModes : null}
+ {!(this.isText && this.props.type === CollectionViewType.Freeform) &&
+ !(this.props.type === CollectionViewType.Invalid) ? this.viewModes : null}
{!(this.isText && this.props.type === CollectionViewType.Freeform) ? this.templateChrome : null}
<div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: "grid" }}>
<button className={"antimodeMenu-button"} onClick={this.toggleViewSpecs} >
@@ -302,15 +326,15 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
}
@observer
-export class CollectionFreeFormViewChrome extends React.Component<CollectionMenuProps> {
+export class CollectionFreeFormViewChrome extends React.Component<CollectionMenuProps & { isOverlay: boolean }> {
public static Instance: CollectionFreeFormViewChrome;
constructor(props: any) {
super(props);
CollectionFreeFormViewChrome.Instance = this;
}
- get Document() { return this.props.CollectionView.props.Document; }
+ get document() { return this.props.docView.props.Document; }
@computed get dataField() {
- return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)];
+ return this.document[Doc.LayoutFieldKey(this.document)];
}
@computed get childDocs() {
return DocListCast(this.dataField);
@@ -332,30 +356,30 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
@undoBatch
@action
nextKeyframe = (): void => {
- const currentFrame = Cast(this.Document.currentFrame, "number", null);
+ const currentFrame = Cast(this.document.currentFrame, "number", null);
if (currentFrame === undefined) {
- this.Document.currentFrame = 0;
+ 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));
+ 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 = Cast(this.Document.currentFrame, "number", null);
+ const currentFrame = Cast(this.document.currentFrame, "number", null);
if (currentFrame === undefined) {
- this.Document.currentFrame = 0;
+ this.document.currentFrame = 0;
CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
}
CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
- this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1);
+ this.document.currentFrame = Math.max(0, (currentFrame || 0) - 1);
}
@undoBatch
@action
miniMap = (): void => {
- this.Document.hideMinimap = !this.Document.hideMinimap;
+ this.document.hideMinimap = !this.document.hideMinimap;
}
private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""];
private _width = ["1", "5", "10", "100"];
@@ -496,30 +520,40 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
}
render() {
- return this.Document.isAnnotationOverlay ? (null) :
- <div className="collectionFreeFormMenu-cont">
- {!!!this.isText ? <div key="map" title="mini map" className="backKeyframe" onClick={this.miniMap}>
+ return !this.props.docView.layoutDoc ? (null) : <div className="collectionFreeFormMenu-cont">
+ {this.props.docView.props.renderDepth !== 0 || this.isText ? (null) :
+ <div key="map" title="mini map" className="backKeyframe" onClick={this.miniMap}>
<FontAwesomeIcon icon={"map"} size={"lg"} />
- </div> : null}
- {!!!this.isText ? <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
- <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
- </div> : null}
- {!!!this.isText ? <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> : null}
- {!!!this.isText ? <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
- <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
- </div> : null}
-
- {!!!this.isText ? this.widthPicker : null}
- {!!!this.isText ? this.colorPicker : null}
- {!!!this.isText ? this.fillPicker : null}
- {!!!this.isText ? this.drawButtons : null}
- {!!!this.isText ? this.formatPane : null}
- {this.isText ? <RichTextMenu key="rich" /> : null}
-
- </div>;
+ </div>
+ }
+ {!!!this.isText ? <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
+ <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+ </div> : null}
+ {!!!this.isText ? <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> : null}
+ {!!!this.isText ? <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
+ <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+ </div> : null}
+
+ {!this.props.isOverlay || this.isText ? (null) :
+ <button className={"antimodeMenu-button"} key="hypothesis" style={{ backgroundColor: !this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined }} title="Use Hypothesis" onClick={() => this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating}>
+ <FontAwesomeIcon icon={["fab", "hire-a-helper"]} size={"lg"} />
+ </button>
+ }
+ {(!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating) && !this.isText ?
+ <>
+ {this.widthPicker}
+ {this.colorPicker}
+ {this.fillPicker}
+ {this.drawButtons}
+ {this.formatPane}
+ </> :
+ (null)
+ }
+ {this.isText ? <RichTextMenu key="rich" /> : null}
+ </div>;
}
}
@observer
@@ -527,12 +561,14 @@ export class CollectionStackingViewChrome extends React.Component<CollectionMenu
@observable private _currentKey: string = "";
@observable private suggestions: string[] = [];
- @computed private get descending() { return StrCast(this.props.CollectionView.props.Document._columnsSort) === "descending"; }
- @computed get pivotField() { return StrCast(this.props.CollectionView.props.Document._pivotField); }
+ get document() { return this.props.docView.props.Document; }
+
+ @computed private get descending() { return StrCast(this.document._columnsSort) === "descending"; }
+ @computed get pivotField() { return StrCast(this.document._pivotField); }
getKeySuggestions = async (value: string): Promise<string[]> => {
value = value.toLowerCase();
- const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
+ const docs = DocListCast(this.document[this.props.fieldKey]);
if (docs instanceof Doc) {
return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value));
} else {
@@ -567,14 +603,14 @@ export class CollectionStackingViewChrome extends React.Component<CollectionMenu
@action
setValue = (value: string) => {
- this.props.CollectionView.props.Document._pivotField = value;
+ this.document._pivotField = value;
return true;
}
@action toggleSort = () => {
- this.props.CollectionView.props.Document._columnsSort =
- this.props.CollectionView.props.Document._columnsSort === "descending" ? "ascending" :
- this.props.CollectionView.props.Document._columnsSort === "ascending" ? undefined : "descending";
+ this.document._columnsSort =
+ this.document._columnsSort === "descending" ? "ascending" :
+ this.document._columnsSort === "ascending" ? undefined : "descending";
}
@action resetValue = () => { this._currentKey = this.pivotField; };
@@ -624,35 +660,36 @@ export class CollectionStackingViewChrome extends React.Component<CollectionMenu
@observer
export class CollectionSchemaViewChrome extends React.Component<CollectionMenuProps> {
- // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
+ // private _textwrapAllRows: boolean = Cast(this.document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
+ get document() { return this.props.docView.props.Document; }
@undoBatch
togglePreview = () => {
const dividerWidth = 4;
const borderWidth = Number(COLLECTION_BORDER_WIDTH);
- const panelWidth = this.props.CollectionView.props.PanelWidth();
- const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
+ const panelWidth = this.props.docView.props.PanelWidth();
+ const previewWidth = NumCast(this.document.schemaPreviewWidth);
const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth;
- this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
+ this.document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
}
@undoBatch
@action
toggleTextwrap = async () => {
- const textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
+ const textwrappedRows = Cast(this.document.textwrappedSchemaRows, listSpec("string"), []);
if (textwrappedRows.length) {
- this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>([]);
+ this.document.textwrappedSchemaRows = new List<string>([]);
} else {
- const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
+ const docs = DocListCast(this.document[this.props.fieldKey]);
const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]);
- this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
+ this.document.textwrappedSchemaRows = new List<string>(allRows);
}
}
render() {
- const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
- const textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
+ const previewWidth = NumCast(this.document.schemaPreviewWidth);
+ const textWrapped = Cast(this.document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
return (
<div className="collectionSchemaViewChrome-cont">
@@ -672,11 +709,12 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionMenuPr
@observer
export class CollectionTreeViewChrome extends React.Component<CollectionMenuProps> {
+ get document() { return this.props.docView.props.Document; }
get sortAscending() {
- return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"];
+ return this.document[this.props.fieldKey + "-sortAscending"];
}
set sortAscending(value) {
- this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value;
+ this.document[this.props.fieldKey + "-sortAscending"] = value;
}
@computed private get ascending() {
return Cast(this.sortAscending, "boolean", null);
@@ -707,15 +745,16 @@ export class CollectionTreeViewChrome extends React.Component<CollectionMenuProp
// Enter scroll speed for 3D Carousel
@observer
export class Collection3DCarouselViewChrome extends React.Component<CollectionMenuProps> {
+ get document() { return this.props.docView.props.Document; }
@computed get scrollSpeed() {
- return this.props.CollectionView.props.Document._autoScrollSpeed;
+ return this.document._autoScrollSpeed;
}
@action
setValue = (value: string) => {
const numValue = Number(StrCast(value));
if (numValue > 0) {
- this.props.CollectionView.props.Document._autoScrollSpeed = numValue;
+ this.document._autoScrollSpeed = numValue;
return true;
}
return false;
@@ -752,13 +791,14 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
private decrementLimitReached: boolean = false;
@observable private resize = false;
private resizeListenerDisposer: Opt<Lambda>;
+ get document() { return this.props.docView.props.Document; }
componentDidMount() {
- runInAction(() => this.resize = this.props.CollectionView.props.PanelWidth() < 700);
+ runInAction(() => this.resize = this.props.docView.props.PanelWidth() < 700);
// listener to reduce text on chrome resize (panel resize)
- this.resizeListenerDisposer = computed(() => this.props.CollectionView.props.PanelWidth()).observe(({ newValue }) => {
+ this.resizeListenerDisposer = computed(() => this.props.docView.props.PanelWidth()).observe(({ newValue }) => {
runInAction(() => this.resize = newValue < 700);
});
}
@@ -767,7 +807,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
this.resizeListenerDisposer?.();
}
- get numCols() { return NumCast(this.props.CollectionView.props.Document.gridNumCols, 10); }
+ get numCols() { return NumCast(this.document.gridNumCols, 10); }
/**
* Sets the value of `numCols` on the grid's Document to the value entered.
@@ -776,7 +816,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
onNumColsEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" || e.key === "Tab") {
if (e.currentTarget.valueAsNumber > 0) {
- this.props.CollectionView.props.Document.gridNumCols = e.currentTarget.valueAsNumber;
+ this.document.gridNumCols = e.currentTarget.valueAsNumber;
}
}
@@ -788,8 +828,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
// @undoBatch
// onRowHeightEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
// if (e.key === "Enter" || e.key === "Tab") {
- // if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) {
- // this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber;
+ // if (e.currentTarget.valueAsNumber > 0 && this.document.rowHeight as number !== e.currentTarget.valueAsNumber) {
+ // this.document.rowHeight = e.currentTarget.valueAsNumber;
// }
// }
// }
@@ -799,7 +839,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
*/
@undoBatch
toggleFlex = () => {
- this.props.CollectionView.props.Document.gridFlex = !BoolCast(this.props.CollectionView.props.Document.gridFlex, true);
+ this.document.gridFlex = !BoolCast(this.document.gridFlex, true);
}
/**
@@ -807,8 +847,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
*/
onIncrementButtonClick = () => {
this.clicked = true;
- this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)--;
- undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1)();
+ this.entered && (this.document.gridNumCols as number)--;
+ undoBatch(() => this.document.gridNumCols = this.numCols + 1)();
this.entered = false;
}
@@ -818,8 +858,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
onDecrementButtonClick = () => {
this.clicked = true;
if (!this.decrementLimitReached) {
- this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)++;
- undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1)();
+ this.entered && (this.document.gridNumCols as number)++;
+ undoBatch(() => this.document.gridNumCols = this.numCols - 1)();
}
this.entered = false;
}
@@ -830,7 +870,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
incrementValue = () => {
this.entered = true;
if (!this.clicked && !this.decrementLimitReached) {
- this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1;
+ this.document.gridNumCols = this.numCols + 1;
}
this.decrementLimitReached = false;
this.clicked = false;
@@ -843,7 +883,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
this.entered = true;
if (!this.clicked) {
if (this.numCols !== 1) {
- this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1;
+ this.document.gridNumCols = this.numCols - 1;
}
else {
this.decrementLimitReached = true;
@@ -857,7 +897,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
* Toggles the value of preventCollision
*/
toggleCollisions = () => {
- this.props.CollectionView.props.Document.gridPreventCollision = !this.props.CollectionView.props.Document.gridPreventCollision;
+ this.document.gridPreventCollision = !this.document.gridPreventCollision;
}
/**
@@ -865,7 +905,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
*/
changeCompactType = (e: React.ChangeEvent<HTMLSelectElement>) => {
// need to change startCompaction so that this operation will be undoable.
- this.props.CollectionView.props.Document.gridStartCompaction = e.target.selectedOptions[0].value;
+ this.document.gridStartCompaction = e.target.selectedOptions[0].value;
}
render() {
@@ -883,10 +923,10 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
<span className="grid-icon">
<FontAwesomeIcon icon="text-height" size="1x" />
</span>
- <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
+ <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
</span> */}
<span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
- <input type="checkbox" style={{ marginRight: 5 }} onChange={this.toggleCollisions} checked={!this.props.CollectionView.props.Document.gridPreventCollision} />
+ <input type="checkbox" style={{ marginRight: 5 }} onChange={this.toggleCollisions} checked={!this.document.gridPreventCollision} />
<label className="flexLabel">{this.resize ? "Coll" : "Collisions"}</label>
</span>
@@ -894,7 +934,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
style={{ marginRight: 5 }}
onPointerDown={stopPropagation}
onChange={this.changeCompactType}
- value={StrCast(this.props.CollectionView.props.Document.gridStartCompaction, StrCast(this.props.CollectionView.props.Document.gridCompaction))}>
+ value={StrCast(this.document.gridStartCompaction, StrCast(this.document.gridCompaction))}>
{["vertical", "horizontal", "none"].map(type =>
<option className="collectionGridViewChrome-viewOption"
onPointerDown={stopPropagation}
@@ -906,11 +946,11 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
<span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
<input style={{ marginRight: 5 }} type="checkbox" onChange={this.toggleFlex}
- checked={BoolCast(this.props.CollectionView.props.Document.gridFlex, true)} />
+ checked={BoolCast(this.document.gridFlex, true)} />
<label className="flexLabel">{this.resize ? "Flex" : "Flexible"}</label>
</span>
- <button onClick={() => this.props.CollectionView.props.Document.gridResetLayout = true}>
+ <button onClick={() => this.document.gridResetLayout = true}>
{!this.resize ? "Reset" :
<FontAwesomeIcon icon="redo-alt" size="1x" />}
</button>
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 8480a56cc..99acfdcc2 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -55,17 +55,17 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
class CollectionSubView extends DocComponent<X & SubCollectionViewProps, T>(schemaCtor) {
private dropDisposer?: DragManager.DragDropDisposer;
private gestureDisposer?: GestureUtils.GestureEventDisposer;
- protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
protected _mainCont?: HTMLDivElement;
protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
this.dropDisposer?.();
this.gestureDisposer?.();
- this.multiTouchDisposer?.();
+ this._multiTouchDisposer?.();
if (ele) {
this._mainCont = ele;
this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this));
this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this));
- this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this));
+ this._multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this));
}
}
protected CreateDropTarget(ele: HTMLDivElement) { //used in schema view
@@ -74,7 +74,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
componentWillUnmount() {
this.gestureDisposer?.();
- this.multiTouchDisposer?.();
+ this._multiTouchDisposer?.();
}
@computed get dataDoc() {
@@ -292,7 +292,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
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;
+ Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc)["text"] = text;
this.props.addDocument(htmlDoc);
if (srcWeb) {
const focusNode = (SelectionManager.SelectedDocuments()[0].ContentDiv?.getElementsByTagName("iframe")[0].contentDocument?.getSelection()?.focusNode as any);
@@ -300,7 +300,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
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([], { _backgroundColor: "transparent", _width: 25, _height: 25, x, y, annotationOn: srcWeb });
+ const anchor = Docs.Create.FreeformDocument([], { _backgroundColor: "transparent", _width: 75, _height: 40, x, y, annotationOn: srcWeb });
anchor.context = srcWeb;
const key = Doc.LayoutFieldKey(srcWeb);
Doc.AddDocToList(srcWeb, key + "-annotations", anchor);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2a700be9c..ae53f5ba0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -27,12 +27,10 @@ import { InteractionUtils } from '../../util/InteractionUtils';
import { UndoManager } from '../../util/UndoManager';
import { ContextMenu } from "../ContextMenu";
import { FieldView, FieldViewProps } from '../nodes/FieldView';
-import { ScriptBox } from '../ScriptBox';
import { Touchable } from '../Touchable';
import { CollectionCarousel3DView } from './CollectionCarousel3DView';
import { CollectionCarouselView } from './CollectionCarouselView';
import { CollectionDockingView } from "./CollectionDockingView";
-import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
import { CollectionGridView } from './collectionGrid/CollectionGridView';
import { CollectionLinearView } from './CollectionLinearView';
@@ -106,7 +104,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
@observable private static _safeMode = false;
public static SetSafeMode(safeMode: boolean) { this._safeMode = safeMode; }
- protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
private AclMap = new Map<symbol, string>([
[AclPrivate, SharingPermissions.None],
@@ -290,9 +288,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" });
subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" });
subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "th-list" });
- if (addExtras && this.props.Document._viewType === CollectionViewType.Freeform) {
- subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
- }
addExtras && subItems.push({ description: "lightbox", event: action(() => this._isLightboxOpen = true), icon: "eye" });
const existingVm = ContextMenu.Instance.findByDescription(category);
@@ -580,7 +575,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
ChildLayoutTemplate: this.childLayoutTemplate,
ChildLayoutString: this.childLayoutString,
};
- setTimeout(action(() => this.props.isSelected(true) && (CollectionMenu.Instance.SelectedCollection = this)), 0);
const 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")}`;
return (<div className={"collectionView"} onContextMenu={this.onContextMenu}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index a4fd5384f..b00074cc6 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -142,9 +142,16 @@ export function computePivotLayout(
const fieldKey = "data";
const pivotColumnGroups = new Map<FieldResult<Field>, PivotColumn>();
+ let nonNumbers = 0;
const pivotFieldKey = toLabel(pivotDoc._pivotField);
childPairs.map(pair => {
- const lval = Cast(pair.layout[pivotFieldKey], listSpec("string"), null);
+ const lval = pivotFieldKey === "#" ? Array.from(Object.keys(Doc.GetProto(pair.layout))).filter(k => k.startsWith("#")).map(k => k.substring(1)) :
+ Cast(pair.layout[pivotFieldKey], listSpec("string"), null);
+
+ const num = toNumber(pair.layout[pivotFieldKey]);
+ if (num === undefined || Number.isNaN(num)) {
+ nonNumbers++;
+ }
const val = Field.toString(pair.layout[pivotFieldKey] as Field);
if (lval) {
lval.forEach((val, i) => {
@@ -168,13 +175,6 @@ export function computePivotLayout(
});
}
});
- let nonNumbers = 0;
- childPairs.map(pair => {
- const num = toNumber(pair.layout[pivotFieldKey]);
- if (num === undefined || Number.isNaN(num)) {
- nonNumbers++;
- }
- });
const pivotNumbers = nonNumbers / childPairs.length < .1;
if (pivotColumnGroups.size > 10) {
const arrayofKeys = Array.from(pivotColumnGroups.keys());
@@ -434,27 +434,3 @@ function normalizeResults(
payload: gname.payload
})));
}
-
-export function AddCustomFreeFormLayout(doc: Doc, dataKey: string): () => void {
- return () => {
- const addOverlay = (key: "arrangeScript" | "arrangeInit", options: OverlayElementOptions, params?: Record<string, string>, requiredType?: string) => {
- let overlayDisposer: () => void = emptyFunction; // filled in below after we have a reference to the scriptingBox
- const scriptField = Cast(doc[key], ScriptField);
- const scriptingBox = <ScriptBox initialText={scriptField && scriptField.script.originalScript}
- // tslint:disable-next-line: no-unnecessary-callback-wrapper
- onCancel={() => overlayDisposer()} // don't get rid of the function wrapper-- we don't want to use the current value of overlayDiposer, but the one set below
- onSave={(text, onError) => {
- const script = CompileScript(text, { params, requiredType, typecheck: false });
- if (!script.compiled) {
- onError(script.errors.map(error => error.messageText).join("\n"));
- } else {
- doc[key] = new ScriptField(script);
- overlayDisposer();
- }
- }} />;
- overlayDisposer = OverlayView.Instance.addWindow(scriptingBox, options);
- };
- addOverlay("arrangeInit", { x: 400, y: 100, width: 400, height: 300, title: "Layout Initialization" }, { collection: "Doc", docs: "Doc[]" }, undefined);
- addOverlay("arrangeScript", { x: 400, y: 500, width: 400, height: 300, title: "Layout Script" }, { doc: "Doc", index: "number", collection: "Doc", state: "any", docs: "Doc[]" }, "{x: number, y: number, width?: number, height?: number}");
- };
-}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index daa6e7440..57336131a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -57,7 +57,6 @@ export const panZoomSchema = createSchema({
currentTimecode: "number",
displayTimecode: "number",
currentFrame: "number",
- arrangeScript: ScriptField,
arrangeInit: ScriptField,
useClusters: "boolean",
fitToBox: "boolean",
@@ -892,7 +891,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.props.focus(doc);
} else {
const contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn._height);
- const offset = annotOn && (contextHgt / 2 * 96 / 72);
+ const offset = annotOn && (contextHgt / 2);
this.props.Document._scrollY = NumCast(doc.y) - offset;
}
@@ -1005,10 +1004,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return this.props.addDocTab(doc, where);
});
getCalculatedPositions(params: { pair: { layout: Doc, data?: Doc }, index: number, collection: Doc, docs: Doc[], state: any }): PoolData {
- const result = this.Document.arrangeScript?.script.run(params, console.log);
- if (result?.success) {
- return { x: 0, y: 0, transition: "transform 1s", ...result, pair: params.pair, replica: "" };
- }
const layoutDoc = Doc.Layout(params.pair.layout);
const { x, y, opacity } = this.Document.currentFrame === undefined ? params.pair.layout :
CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document.currentFrame || 0);