aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-06-19 22:40:54 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-06-19 22:40:54 -0400
commit118ecb14ce519bcbade12b3d52e11b22fcc371b3 (patch)
tree3c5200b30d18da1e4e60652338a0b441a2f5afd1 /src
parent96c26c57527d443784bde9752551bfa10b3ce4d2 (diff)
cleaned up and enhanced tree view
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts1
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.scss5
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx347
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
5 files changed, 158 insertions, 202 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fcd1010c6..de6c5bc6a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -18,7 +18,6 @@ import { action } from "mobx";
import { ColumnAttributeModel } from "../northstar/core/attribute/AttributeModel";
import { AttributeTransformationModel } from "../northstar/core/attribute/AttributeTransformationModel";
import { AggregateFunction } from "../northstar/model/idea/idea";
-import { Template } from "../views/Templates";
import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss";
import { IconBox } from "../views/nodes/IconBox";
import { Field, Doc, Opt } from "../../new_fields/Doc";
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index faea8d44d..9cc8961e3 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -385,7 +385,7 @@ interface CollectionSchemaPreviewProps {
Document?: Doc;
width: () => number;
height: () => number;
- CollectionView: CollectionView | CollectionPDFView | CollectionVideoView;
+ CollectionView?: CollectionView | CollectionPDFView | CollectionVideoView;
getTransform: () => Transform;
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
moveDocument: (document: Doc, target: Doc, addDoc: ((doc: Doc) => boolean)) => boolean;
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index ec78fdb80..a85604e58 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -4,10 +4,10 @@
border-width: $COLLECTION_BORDER_WIDTH;
border-color: transparent;
border-style: solid;
- border-radius: $border-radius;
+ border-radius: inherit;
box-sizing: border-box;
height: 100%;
- padding: 20px;
+ padding-top: 20px;
padding-left: 10px;
padding-right: 0px;
background: $light-color-secondary;
@@ -56,6 +56,7 @@
font-size: 8pt;
margin-left: 3px;
display:none;
+ background: lightgray;
}
.docContainer {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 1eab541b3..856430036 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,38 +1,35 @@
-import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
-import { faAngleRight, faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faAngleRight, faCaretDown, faCaretRight, faTrashAlt, faCaretSquareRight, faCaretSquareDown } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable, trace, computed } from "mobx";
+import { action, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, WidthSym, HeightSym } from '../../../new_fields/Doc';
+import { Doc, DocListCast, HeightSym, WidthSym } from '../../../new_fields/Doc';
import { Id } from '../../../new_fields/FieldSymbols';
+import { List } from '../../../new_fields/List';
import { Document, listSpec } from '../../../new_fields/Schema';
-import { BoolCast, Cast, NumCast, StrCast, PromiseValue } from '../../../new_fields/Types';
+import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { emptyFunction, Utils } from '../../../Utils';
import { Docs } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
+import { SelectionManager } from '../../util/SelectionManager';
+import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { EditableView } from "../EditableView";
import { MainView } from '../MainView';
+import { Templates } from '../Templates';
import { CollectionViewType } from './CollectionBaseView';
import { CollectionDockingView } from './CollectionDockingView';
-import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView";
+import { CollectionSchemaPreview } from './CollectionSchemaView';
+import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
-import { Transform } from '../../util/Transform';
-import { SelectionManager } from '../../util/SelectionManager';
-import { emptyFunction, returnFalse, Utils, returnOne, returnZero } from '../../../Utils';
-import { List } from '../../../new_fields/List';
-import { Templates } from '../Templates';
-import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
-import { number } from 'prop-types';
-import ReactTable from 'react-table';
-import { MainOverlayTextBox } from '../MainOverlayTextBox';
export interface TreeViewProps {
document: Doc;
- deleteDoc: (doc: Doc) => void;
+ deleteDoc: (doc: Doc) => boolean;
moveDocument: DragManager.MoveFunction;
dropAction: "alias" | "copy" | undefined;
addDocTab: (doc: Doc, where: string) => void;
@@ -41,22 +38,18 @@ export interface TreeViewProps {
addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
indentDocument?: () => void;
ScreenToLocalTransform: () => Transform;
- outerXf: () => number[];
+ outerXf: () => { translateX: number, translateY: number };
treeViewId: string;
parentKey: string;
active: () => boolean;
}
-export enum BulletType {
- Collapsed,
- Collapsible,
- List
-}
-
library.add(faTrashAlt);
library.add(faAngleRight);
library.add(faCaretDown);
library.add(faCaretRight);
+library.add(faCaretSquareDown);
+library.add(faCaretSquareRight);
@observer
/**
@@ -64,25 +57,22 @@ library.add(faCaretRight);
*/
class TreeView extends React.Component<TreeViewProps> {
private _header?: React.RefObject<HTMLDivElement> = React.createRef();
- private treedropDisposer?: DragManager.DragDropDisposer;
- private _mainEle?: HTMLDivElement;
+ private _treedropDisposer?: DragManager.DragDropDisposer;
+ private _dref = React.createRef<HTMLDivElement>();
+ @observable _chosenKey: string = "data";
+ @observable _collapsed: boolean = true;
+
protected createTreeDropTarget = (ele: HTMLDivElement) => {
- this.treedropDisposer && this.treedropDisposer();
+ this._treedropDisposer && this._treedropDisposer();
if (ele) {
- this.treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } });
+ this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } });
}
- this._mainEle = ele;
}
- @observable _isOver: boolean = false;
- @observable _collapsed: boolean = true;
-
@undoBatch delete = () => this.props.deleteDoc(this.props.document);
@undoBatch openRight = async () => this.props.addDocTab(this.props.document, "openRight");
- @action onMouseEnter = () => { this._isOver = true; };
- @action onMouseLeave = () => { this._isOver = false; };
-
+ onPointerDown = (e: React.PointerEvent) => e.stopPropagation()
onPointerEnter = (e: React.PointerEvent): void => {
this.props.active() && (this.props.document.libraryBrush = true);
if (e.buttons === 1 && SelectionManager.GetIsDragging()) {
@@ -101,80 +91,60 @@ class TreeView extends React.Component<TreeViewProps> {
let rect = this._header!.current!.getBoundingClientRect();
let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
let before = x[1] < bounds[1];
- let inside = x[0] > bounds[0] + 75 || (!before && this._bulletType === BulletType.Collapsible);
+ let inside = x[0] > bounds[0] + 75 || (!before && !this._collapsed);
this._header!.current!.className = "treeViewItem-header";
- if (inside && this._bulletType !== BulletType.List) this._header!.current!.className += " treeViewItem-header-inside";
+ if (inside) this._header!.current!.className += " treeViewItem-header-inside";
else if (before) this._header!.current!.className += " treeViewItem-header-above";
else if (!before) this._header!.current!.className += " treeViewItem-header-below";
e.stopPropagation();
}
- onPointerDown = (e: React.PointerEvent) => {
- e.stopPropagation();
- }
@action
- remove = (document: Document, key: string) => {
+ remove = (document: Document, key: string): boolean => {
let children = Cast(this.props.document[key], listSpec(Doc), []);
- children.indexOf(document) !== -1 && children.splice(children.indexOf(document), 1);
+ if (children.indexOf(document) !== -1) {
+ children.splice(children.indexOf(document), 1);
+ return true;
+ }
+ return false;
}
@action
- move: DragManager.MoveFunction = (document: Doc, target: Doc, addDoc) => {
- if (this.props.document !== target) {
- //TODO This should check if it was removed
- this.props.deleteDoc(document);
- return addDoc(document);
- }
- return true;
+ move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
+ return this.props.document !== target && this.props.deleteDoc(doc) && addDoc(doc);
}
@action
- indent = () => {
- this.props.addDocument(this.props.document);
- this.delete();
- }
-
+ indent = () => this.props.addDocument(this.props.document) && this.delete();
- renderBullet(type: BulletType) {
- let onClicked = action(() => this._collapsed = !this._collapsed);
- let bullet: IconProp | undefined = undefined;
- switch (type) {
- case BulletType.Collapsed: bullet = "caret-right"; break;
- case BulletType.Collapsible: bullet = "caret-down"; break;
- }
- return <div className="bullet" onClick={onClicked}>{bullet ? <FontAwesomeIcon icon={bullet} /> : ""} </div>;
+ renderBullet() {
+ let docList = Cast(this.props.document["data"], listSpec(Doc));
+ let doc = Cast(this.props.document["data"], Doc);
+ let isDoc = doc instanceof Doc || docList;
+ return <div className="bullet" onClick={action(() => this._collapsed = !this._collapsed)}>
+ {<FontAwesomeIcon icon={this._collapsed ? (isDoc ? "caret-square-right" : "caret-right") : (isDoc ? "caret-square-down" : "caret-down")} />}
+ </div>;
}
- static loadId = "";
- editableView = (key: string, style?: string) =>
- (<EditableView
- oneLine={true}
- display={"inline"}
- editing={this.props.document[Id] === TreeView.loadId}
- contents={StrCast(this.props.document[key])}
- height={36}
- fontStyle={style}
- GetValue={() => StrCast(this.props.document[key])}
- OnFillDown={(value: string) => {
- Doc.GetProto(this.props.document)[key] = value;
- let doc = Docs.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25 });
- TreeView.loadId = doc[Id];
- doc.templates = new List<string>([Templates.Title.Layout]);
- this.props.addDocument(doc);
- return true;
- }}
- OnTab={() => this.props.indentDocument && this.props.indentDocument()}
- SetValue={(value: string) => {
- Doc.GetProto(this.props.document)[key] = value;
- return true;
- }}
- />)
- /**
- * Renders the EditableView title element for placement into the tree.
- */
- renderTitle() {
- let reference = React.createRef<HTMLDivElement>();
- let onItemDown = SetupDrag(reference, () => this.props.document, this.move, this.props.dropAction, this.props.treeViewId, true);
+ static loadId = "";
+ editableView = (key: string, style?: string) => (<EditableView
+ oneLine={true}
+ display={"inline"}
+ editing={this.props.document[Id] === TreeView.loadId}
+ contents={StrCast(this.props.document[key])}
+ height={36}
+ fontStyle={style}
+ GetValue={() => StrCast(this.props.document[key])}
+ SetValue={(value: string) => (Doc.GetProto(this.props.document)[key] = value) ? true : true}
+ OnFillDown={(value: string) => {
+ Doc.GetProto(this.props.document)[key] = value;
+ let doc = Docs.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+ TreeView.loadId = doc[Id];
+ return this.props.addDocument(doc);
+ }}
+ OnTab={() => this.props.indentDocument && this.props.indentDocument()}
+ />)
+ get keyList() {
let keyList: string[] = [];
let keys = Array.from(Object.keys(this.props.document));
if (this.props.document.proto instanceof Doc) {
@@ -192,19 +162,26 @@ class TreeView extends React.Component<TreeViewProps> {
keyList.push(key);
}
});
- let headerElements = this._bulletType === BulletType.List ? (null) : [this._chosenKey].map(key =>
- <span className="collectionTreeView-keyHeader" key={key} onPointerDown={action(() => { this._chosenKey = key; this.props.document.embed = !BoolCast(this.props.document.embed, false) })}
- style={{ background: key === this._chosenKey ? "lightgray" : undefined }}>
- {key}
+ return keyList;
+ }
+ /**
+ * Renders the EditableView title element for placement into the tree.
+ */
+ renderTitle() {
+ let reference = React.createRef<HTMLDivElement>();
+ let onItemDown = SetupDrag(reference, () => this.props.document, this.move, this.props.dropAction, this.props.treeViewId, true);
+
+ let headerElements = (
+ <span className="collectionTreeView-keyHeader" key={this._chosenKey} onPointerDown={action(() => this.props.document.embed = !BoolCast(this.props.document.embed))} >
+ {this._chosenKey}
</span>);
let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document.data, listSpec(Doc), []) : [];
let openRight = dataDocs && dataDocs.indexOf(this.props.document) !== -1 ? (null) : (
<div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
<FontAwesomeIcon icon="angle-right" size="lg" />
- {/* <FontAwesomeIcon icon="angle-right" size="lg" /> */}
</div>);
return <>
- <div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}
+ <div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown}
style={{
background: BoolCast(this.props.document.protoBrush, false) ? "#06123232" : BoolCast(this.props.document.libraryBrush, false) ? "#06121212" : "0",
pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
@@ -241,7 +218,7 @@ class TreeView extends React.Component<TreeViewProps> {
let rect = this._header!.current!.getBoundingClientRect();
let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
let before = x[1] < bounds[1];
- let inside = x[0] > bounds[0] + 75 || (!before && this._bulletType === BulletType.Collapsible);
+ let inside = x[0] > bounds[0] + 75 || (!before && !this._collapsed);
if (de.data instanceof DragManager.DocumentDragData) {
let addDoc = (doc: Doc) => this.props.addDocument(doc, this.props.document, before);
if (inside) {
@@ -250,18 +227,13 @@ class TreeView extends React.Component<TreeViewProps> {
addDoc = (doc: Doc) => { docList && docList.push(doc); return true; };
}
}
- let added = false;
- if (de.data.dropAction || de.data.userDropAction) {
- added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d, this.props.document, before) || added, false);
- } else if (de.data.moveDocument) {
- let movedDocs = de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments;
- added = movedDocs.reduce((added: boolean, d) =>
- de.data.moveDocument(d, this.props.document, addDoc) || added, false);
- } else {
- added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d, this.props.document, before), false);
- }
e.stopPropagation();
- return added;
+ let movedDocs = (de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments);
+ return (de.data.dropAction || de.data.userDropAction) ?
+ de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d, this.props.document, before) || added, false)
+ : (de.data.moveDocument) ?
+ movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, this.props.document, addDoc) || added, false)
+ : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d, this.props.document, before), false);
}
return false;
}
@@ -279,62 +251,47 @@ class TreeView extends React.Component<TreeViewProps> {
docTransform = () => {
let { scale, translateX, translateY } = Utils.GetScreenTransform(this._dref.current!);
let outerXf = this.props.outerXf();
- let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf[0] - translateX, outerXf[1] - translateY);
+ let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]);
return finalXf;
}
- @observable _chosenKey: string = "data";
- _bulletType: BulletType = BulletType.List;
- _dref = React.createRef<HTMLDivElement>();
render() {
- let bulletType = BulletType.List;
- let contentElement: (JSX.Element | null)[] = [];
- [this._chosenKey].map(key => {
- let docList = Cast(this.props.document[key], listSpec(Doc));
- let remDoc = (doc: Doc) => this.remove(doc, key);
- let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.document, key, doc, addBefore, before);
- let doc = Cast(this.props.document[key], Doc);
- if (doc instanceof Doc || (docList && (DocListCast(docList).length > 0 || key === "data"))) {
- if (!this._collapsed) {
- bulletType = BulletType.Collapsible;
- if (this.props.document.embed) {
- contentElement.push(
- <div ref={this._dref} style={{ width: "max-content", display: "unset" }} key={this.props.document[Id]}>
- <DocumentView Document={this.props.document}
- ContainingCollectionView={undefined}
- ScreenToLocalTransform={this.docTransform}
- isTopMost={false}
- useActualDimensions={true}
- ContentScaling={returnOne}
- PanelWidth={this.props.document[WidthSym]}
- PanelHeight={this.props.document[HeightSym]}
- focus={emptyFunction}
- selectOnLoad={false}
- parentActive={returnFalse}
- whenActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- addDocTab={this.props.addDocTab}
- /></div>);
- } else
- contentElement.push(<ul key={key + "more"}>
- <div style={{ display: "block" }}>
- {TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, key, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.panelHeight)}
- </div>
- </ul >);
- } else {
- bulletType = BulletType.Collapsed;
- }
+ let contentElement: (JSX.Element | null) = null;
+ let docList = Cast(this.props.document[this._chosenKey], listSpec(Doc));
+ let remDoc = (doc: Doc) => this.remove(doc, this._chosenKey);
+ let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.document, this._chosenKey, doc, addBefore, before);
+ let doc = Cast(this.props.document[this._chosenKey], Doc);
+ let docWidth = () => NumCast(this.props.document.nativeWidth) ? Math.min(this.props.document[WidthSym](), this.props.panelWidth() - 5) : this.props.panelWidth() - 5;
+ if (!this._collapsed) {
+ if (!this.props.document.embed && (docList && (DocListCast(docList).length > 0 || this._chosenKey === "data"))) {
+ contentElement = <ul key={this._chosenKey + "more"}>
+ {TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, this._chosenKey, addDoc, remDoc, this.move,
+ this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth)}
+ </ul >;
+ } else {
+ contentElement = <div ref={this._dref} style={{ display: "inline-block", height: this.props.panelHeight() }} key={this.props.document[Id]}>
+ <CollectionSchemaPreview
+ Document={this.props.document}
+ width={docWidth}
+ height={this.props.panelHeight}
+ getTransform={this.docTransform}
+ CollectionView={undefined}
+ addDocument={emptyFunction as any}
+ moveDocument={this.props.moveDocument}
+ removeDocument={emptyFunction as any}
+ active={this.props.active}
+ whenActiveChanged={emptyFunction as any}
+ addDocTab={this.props.addDocTab}
+ setPreviewScript={emptyFunction}>
+ </CollectionSchemaPreview>
+ </div>
}
- });
- this._bulletType = bulletType;
- return <div className="treeViewItem-container"
- ref={this.createTreeDropTarget}
- onContextMenu={this.onWorkspaceContextMenu}>
+ }
+ return <div className="treeViewItem-container" ref={this.createTreeDropTarget} onContextMenu={this.onWorkspaceContextMenu}>
<li className="collection-child">
<div className="treeViewItem-header" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
- {this.renderBullet(bulletType)}
+ {this.renderBullet()}
{this.renderTitle()}
</div>
<div className="treeViewItem-border">
@@ -348,17 +305,17 @@ class TreeView extends React.Component<TreeViewProps> {
treeViewId: string,
key: string,
add: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean,
- remove: ((doc: Doc) => void),
+ remove: ((doc: Doc) => boolean),
move: DragManager.MoveFunction,
dropAction: dropActionType,
addDocTab: (doc: Doc, where: string) => void,
screenToLocalXf: () => Transform,
- outerXf: () => number[],
+ outerXf: () => { translateX: number, translateY: number },
active: () => boolean,
panelWidth: () => number,
- panelHeight: () => number
) {
let docList = docs.filter(child => !child.excludeFromLibrary && (key !== "data" || !child.isMinimized));
+ let rowWidth = () => panelWidth() - 20;
return docList.map((child, i) => {
let indent = i === 0 ? undefined : () => {
if (StrCast(docList[i - 1].layout).indexOf("CollectionView") !== -1) {
@@ -368,15 +325,22 @@ class TreeView extends React.Component<TreeViewProps> {
remove(child);
}
}
+ let addDocument = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
+ return add(doc, relativeTo ? relativeTo : docList[i], before !== undefined ? before : false);
+ }
+ let rowHeight = () => {
+ let aspect = NumCast(child.nativeWidth, 0) / NumCast(child.nativeHeight, 0);
+ return aspect ? Math.min(child[WidthSym](), rowWidth()) / aspect : child[HeightSym]();
+ }
return <TreeView
document={child}
treeViewId={treeViewId}
key={child[Id]}
indentDocument={indent}
deleteDoc={remove}
- addDocument={add}
- panelWidth={panelWidth}
- panelHeight={panelHeight}
+ addDocument={addDocument}
+ panelWidth={rowWidth}
+ panelHeight={rowHeight}
moveDocument={move}
dropAction={dropAction}
addDocTab={addDocTab}
@@ -392,20 +356,26 @@ class TreeView extends React.Component<TreeViewProps> {
export class CollectionTreeView extends CollectionSubView(Document) {
private treedropDisposer?: DragManager.DragDropDisposer;
private _mainEle?: HTMLDivElement;
+
protected createTreeDropTarget = (ele: HTMLDivElement) => {
- if (this.treedropDisposer) {
- this.treedropDisposer();
- }
- if (ele) {
+ this.treedropDisposer && this.treedropDisposer();
+ if (this._mainEle = ele) {
this.treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
}
- this._mainEle = ele;
+ }
+
+ componentWillUnmount() {
+ this.treedropDisposer && this.treedropDisposer();
}
@action
- remove = (document: Document) => {
+ remove = (document: Document): boolean => {
let children = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []);
- children.indexOf(document) !== -1 && children.splice(children.indexOf(document), 1);
+ if (children.indexOf(document) !== -1) {
+ children.splice(children.indexOf(document), 1);
+ return true;
+ }
+ return false;
}
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
@@ -415,26 +385,16 @@ export class CollectionTreeView extends CollectionSubView(Document) {
}
}
- outerXf = () => {
- let outerXf = Utils.GetScreenTransform(this._mainEle!);
- return [outerXf.translateX, outerXf.translateY];
- }
- onTreeDrop = (e: React.DragEvent) => {
- this.onDrop(e, {});
- }
+ outerXf = () => Utils.GetScreenTransform(this._mainEle!);
+ onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {});
+
render() {
let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
- if (!this.childDocs) {
- return (null);
- }
let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
- let childElements = TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.fieldKey, addDoc, this.remove,
- moveDoc, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.outerXf, this.props.active, this.props.PanelWidth, () => 25);
- return (
+ return !this.childDocs ? (null) : (
<div id="body" className="collectionTreeView-dropTarget"
- style={{ borderRadius: "inherit" }}
onContextMenu={this.onContextMenu}
onWheel={(e: React.WheelEvent) => this.props.isSelected() && e.stopPropagation()}
onDrop={this.onTreeDrop}
@@ -445,22 +405,19 @@ export class CollectionTreeView extends CollectionSubView(Document) {
display={"inline"}
height={72}
GetValue={() => StrCast(this.props.Document.title)}
+ SetValue={(value: string) => (Doc.GetProto(this.props.Document).title = value) ? true : true}
OnFillDown={(value: string) => {
- let target = this.props.Document.proto ? this.props.Document.proto : this.props.Document;
- target.title = value;
- let doc = Docs.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25 });
+ Doc.GetProto(this.props.Document).title = value;
+ let doc = Docs.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
TreeView.loadId = doc[Id];
- doc.templates = new List<string>([Templates.Title.Layout]);
- this.props.addDocument(doc);
- }}
- SetValue={(value: string) => {
- let target = this.props.Document.proto ? this.props.Document.proto : this.props.Document;
- target.title = value;
- return true;
+ TreeView.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true);
}} />
</div>
<ul className="no-indent">
- {childElements}
+ {
+ TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.fieldKey, addDoc, this.remove,
+ moveDoc, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.outerXf, this.props.active, this.props.PanelWidth)
+ }
</ul>
</div >
);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f7836d947..4992669df 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -72,7 +72,6 @@ export interface DocumentViewProps {
ScreenToLocalTransform: () => Transform;
isTopMost: boolean;
ContentScaling: () => number;
- useActualDimensions?: boolean;
PanelWidth: () => number;
PanelHeight: () => number;
focus: (doc: Doc) => void;
@@ -539,8 +538,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
render() {
var scaling = this.props.ContentScaling();
- var nativeWidth = this.props.useActualDimensions ? NumCast(this.props.Document.width) : this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%";
- var nativeHeight = this.props.useActualDimensions ? NumCast(this.props.Document.height) : BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%";
+ var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%";
+ var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%";
return (
<div className={`documentView-node${this.props.isTopMost ? "-topmost" : ""}`}
ref={this._mainCont}