From 3b880d7b15b7107049ae27601b9f759b17f7fde9 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 18 Jun 2019 22:51:46 -0400
Subject: added initial keyboard shortcuts for adding and moving docs in
 TreeView.  fixed image drag bug.

---
 src/client/views/EditableView.tsx | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

(limited to 'src/client/views/EditableView.tsx')

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index c946d68e1..a96fca464 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -18,13 +18,17 @@ export interface EditableProps {
 
     OnFillDown?(value: string): void;
 
+    OnTab?(): void;
+
     /**
      * The contents to render when not editing
      */
     contents: any;
+    fontStyle?: string;
     height?: number;
     display?: string;
     oneLine?: boolean;
+    editing?: boolean
 }
 
 /**
@@ -34,40 +38,48 @@ export interface EditableProps {
  */
 @observer
 export class EditableView extends React.Component<EditableProps> {
-    @observable
-    editing: boolean = false;
+    @observable _editing: boolean = false;
+
+    constructor(props: EditableProps) {
+        super(props);
+        this._editing = this.props.editing ? true : false;
+    }
 
     @action
     onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
-        if (e.key === "Enter") {
+        if (e.key === "Tab") {
+            this.props.OnTab && this.props.OnTab();
+        } else if (e.key === "Enter") {
             if (!e.ctrlKey) {
                 if (this.props.SetValue(e.currentTarget.value)) {
-                    this.editing = false;
+                    this._editing = false;
                 }
             } else if (this.props.OnFillDown) {
                 this.props.OnFillDown(e.currentTarget.value);
-                this.editing = false;
+                this._editing = false;
             }
         } else if (e.key === "Escape") {
-            this.editing = false;
+            this._editing = false;
         }
     }
 
     @action
     onClick = (e: React.MouseEvent) => {
-        this.editing = true;
+        this._editing = true;
         e.stopPropagation();
     }
 
     render() {
-        if (this.editing) {
-            return <input className="editableView-input" defaultValue={this.props.GetValue()} onKeyDown={this.onKeyDown} autoFocus onBlur={action(() => this.editing = false)}
+        if (this._editing) {
+            return <input className="editableView-input" defaultValue={this.props.GetValue()} onKeyDown={this.onKeyDown} autoFocus
+                onBlur={action(() => this._editing = false)}
                 style={{ display: this.props.display }} />;
         } else {
             return (
-                <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`} style={{ display: this.props.display, height: "auto", maxHeight: `${this.props.height}` }}
+                <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`}
+                    style={{ display: this.props.display, height: "auto", maxHeight: `${this.props.height}` }}
                     onClick={this.onClick} >
-                    <span>{this.props.contents}</span>
+                    <span style={{ fontStyle: this.props.fontStyle }}>{this.props.contents}</span>
                 </div>
             );
         }
-- 
cgit v1.2.3-70-g09d2


From 1472d2b56aa64896f0a93f172322121d19cd1592 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 19 Jun 2019 09:11:35 -0400
Subject: fixed lint errors.

---
 src/client/views/EditableView.tsx                   |  2 +-
 src/client/views/collections/CollectionTreeView.tsx | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'src/client/views/EditableView.tsx')

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index a96fca464..70d6c22bf 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -28,7 +28,7 @@ export interface EditableProps {
     height?: number;
     display?: string;
     oneLine?: boolean;
-    editing?: boolean
+    editing?: boolean;
 }
 
 /**
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6a2ab9d7d..f6c9ba86b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -154,7 +154,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 Doc.GetProto(this.props.document)[key] = value;
                 return true;
             }}
-        />);
+        />)
 
     /**
      * Renders the EditableView title element for placement into the tree.
@@ -241,7 +241,7 @@ class TreeView extends React.Component<TreeViewProps> {
         return true;
     }
 
-    @observable _chosenKey: string = "data"
+    @observable _chosenKey: string = "data";
     _bulletType: BulletType = BulletType.List;
     render() {
         let bulletType = BulletType.List;
@@ -268,7 +268,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 style={{ display: "inline", marginRight: "3px", marginTop: "7px", background: key === this._chosenKey ? "lightgray" : undefined }}>
                 {key}
             </span>)}
-        </div>
+        </div>;
         [this._chosenKey].map(key => {
             let docList = Cast(this.props.document[key], listSpec(Doc));
             let remDoc = (doc: Doc) => this.remove(doc, key);
@@ -318,7 +318,7 @@ class TreeView extends React.Component<TreeViewProps> {
     ) {
         let docList = docs.filter(child => !child.excludeFromLibrary && (key !== "data" || !child.isMinimized));
         return docList.map((child, i) => {
-            let indent = i == 0 ? undefined : () => {
+            let indent = i === 0 ? undefined : () => {
                 if (StrCast(docList[i - 1].layout).indexOf("CollectionView") !== -1) {
                     let fieldKeysub = StrCast(docList[i - 1].layout).split("fieldKey")[1];
                     let fieldKey = fieldKeysub.split("\"")[1];
@@ -338,7 +338,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 addDocTab={addDocTab}
                 ScreenToLocalTransform={screenToLocalXf}
                 parentKey={key}
-                active={active} />
+                active={active} />;
         });
     }
 }
-- 
cgit v1.2.3-70-g09d2


From 38de022621175bda7410df4444fcd2bbee0919cb Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 19 Jun 2019 23:43:47 -0400
Subject: slight tweaks.

---
 src/client/views/EditableView.tsx                  |  5 +++-
 .../views/collections/CollectionTreeView.tsx       | 35 +++++++++++++++-------
 2 files changed, 28 insertions(+), 12 deletions(-)

(limited to 'src/client/views/EditableView.tsx')

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 70d6c22bf..0f6281b5c 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -29,6 +29,7 @@ export interface EditableProps {
     display?: string;
     oneLine?: boolean;
     editing?: boolean;
+    onClick?: (e: React.MouseEvent) => boolean;
 }
 
 /**
@@ -65,7 +66,9 @@ export class EditableView extends React.Component<EditableProps> {
 
     @action
     onClick = (e: React.MouseEvent) => {
-        this._editing = true;
+        if (!this.props.onClick || !this.props.onClick(e)) {
+            this._editing = true;
+        }
         e.stopPropagation();
     }
 
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 856430036..c51c16883 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
 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 } from "mobx";
+import { action, observable, computed } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, HeightSym, WidthSym } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
@@ -125,12 +125,20 @@ class TreeView extends React.Component<TreeViewProps> {
         </div>;
     }
 
+    titleClicked = (e: React.MouseEvent) => {
+        if (this._collapsed) return false;
+        else {
+            this.props.document.embed = !BoolCast(this.props.document.embed);
+            return 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])}
+        onClick={this.titleClicked}
         height={36}
         fontStyle={style}
         GetValue={() => StrCast(this.props.document[key])}
@@ -144,24 +152,24 @@ class TreeView extends React.Component<TreeViewProps> {
         OnTab={() => this.props.indentDocument && this.props.indentDocument()}
     />)
 
-    get keyList() {
-        let keyList: string[] = [];
+    @computed get keyList() {
         let keys = Array.from(Object.keys(this.props.document));
         if (this.props.document.proto instanceof Doc) {
             keys.push(...Array.from(Object.keys(this.props.document.proto)));
             while (keys.indexOf("proto") !== -1) keys.splice(keys.indexOf("proto"), 1);
         }
-        if (keys.indexOf("data") !== -1) {
-            keys.splice(keys.indexOf("data"), 1);
-            keys.splice(0, 0, "data");
-        }
+        let keyList: string[] = [];
         keys.map(key => {
             let docList = Cast(this.props.document[key], listSpec(Doc));
             let doc = Cast(this.props.document[key], Doc);
-            if (doc instanceof Doc || (docList && (DocListCast(docList).length > 0 || key === "data"))) {
+            if (doc instanceof Doc || docList) {
                 keyList.push(key);
             }
         });
+        if (keyList.indexOf("data") !== -1) {
+            keyList.splice(keyList.indexOf("data"), 1);
+        }
+        keyList.splice(0, 0, "data");
         return keyList;
     }
     /**
@@ -172,7 +180,12 @@ class TreeView extends React.Component<TreeViewProps> {
         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))} >
+            <span className="collectionTreeView-keyHeader" key={this._chosenKey}
+                onPointerDown={action(() => {
+                    let ind = this.keyList.indexOf(this._chosenKey);
+                    ind = (ind + 1) % this.keyList.length;
+                    this._chosenKey = this.keyList[ind];
+                })} >
                 {this._chosenKey}
             </span>);
         let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document.data, listSpec(Doc), []) : [];
@@ -209,7 +222,7 @@ class TreeView extends React.Component<TreeViewProps> {
             } else {
                 ContextMenu.Instance.addItem({ description: "Delete Workspace", event: undoBatch(() => this.props.deleteDoc(this.props.document)) });
             }
-            ContextMenu.Instance.displayMenu(e.pageX - 156, e.pageY - 15);
+            ContextMenu.Instance.displayMenu(e.pageX > 156 ? e.pageX - 156 : 0, e.pageY - 15);
             e.stopPropagation();
         }
     }
@@ -264,7 +277,7 @@ class TreeView extends React.Component<TreeViewProps> {
         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"))) {
+            if (!this.props.document.embed) {
                 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)}
-- 
cgit v1.2.3-70-g09d2

