From a61dfaab422886733a727eebe80b619230d59684 Mon Sep 17 00:00:00 2001
From: Stanley Yip <stanley_yip@brown.edu>
Date: Mon, 20 Jan 2020 13:40:57 -0500
Subject: working palette

---
 .../views/collections/CollectionLinearView.tsx     | 24 +++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

(limited to 'src/client/views/collections/CollectionLinearView.tsx')

diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index e91c2a01d..8b0638aa1 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -31,6 +31,9 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
         this._dropDisposer && this._dropDisposer();
         this._widthDisposer && this._widthDisposer();
         this._selectedDisposer && this._selectedDisposer();
+        this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => {
+            Cast(pair.layout.proto?.onPointerUp, ScriptField)?.script.run({ this: pair.layout.proto }, console.log);
+        });
     }
 
     componentDidMount() {
@@ -42,7 +45,22 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
         this._selectedDisposer = reaction(
             () => NumCast(this.props.Document.selectedIndex),
-            (i) => runInAction(() => this._selectedIndex = i),
+            (i) => runInAction(() => {
+                this._selectedIndex = i;
+                let selected: any = undefined;
+                this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => {
+                    const isSelected = this._selectedIndex === ind;
+                    if (isSelected) {
+                        selected = pair;
+                    }
+                    else {
+                        Cast(pair.layout.proto?.onPointerUp, ScriptField)?.script.run({ this: pair.layout.proto }, console.log);
+                    }
+                });
+                if (selected && selected.layout) {
+                    Cast(selected.layout.proto?.onPointerDown, ScriptField)?.script.run({ this: selected.layout.proto }, console.log);
+                }
+            }),
             { fireImmediately: true }
         );
     }
@@ -76,10 +94,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                         const dref = React.createRef<HTMLDivElement>();
                         const nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension());
                         const deltaSize = nativeWidth * .15 / 2;
-                        const isSelected = this._selectedIndex === ind;
-                        if (isSelected) {
-                            Cast(pair.layout.proto?.onPointerDown, ScriptField)?.script.run({ this: pair.layout.proto }, console.log);
-                        }
                         return <div className={`collectionLinearView-docBtn` + (pair.layout.onClick || pair.layout.onDragStart ? "-scalable" : "")} key={pair.layout[Id]} ref={dref}
                             style={{
                                 width: nested ? pair.layout[WidthSym]() : this.dimension() - deltaSize,
-- 
cgit v1.2.3-70-g09d2


From dabb4a9c66083b88eba7bfb07a2614634e124b10 Mon Sep 17 00:00:00 2001
From: Stanley Yip <stanley_yip@brown.edu>
Date: Mon, 20 Jan 2020 16:33:49 -0500
Subject: resizable palette

---
 src/client/documents/Documents.ts                  |  4 +-
 src/client/views/GestureOverlay.scss               |  6 ++
 src/client/views/GestureOverlay.tsx                | 68 +++++++++++++++-------
 src/client/views/MainView.tsx                      |  2 +-
 .../views/collections/CollectionLinearView.tsx     |  2 +-
 src/client/views/nodes/ButtonBox.tsx               |  5 +-
 src/new_fields/documentSchemas.ts                  |  2 +
 .../authentication/models/current_user_utils.ts    | 16 +++--
 8 files changed, 75 insertions(+), 30 deletions(-)

(limited to 'src/client/views/collections/CollectionLinearView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 7e7b10ae8..821185518 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -80,7 +80,7 @@ export interface DocumentOptions {
     isTemplateDoc?: boolean;
     templates?: List<string>;
     viewType?: number;
-    backgroundColor?: string;
+    backgroundColor?: string | ScriptField;
     ignoreClick?: boolean;
     lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged
     lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed
@@ -127,6 +127,8 @@ export interface DocumentOptions {
     // [key: string]: Opt<Field>;
     pointerHack?: boolean; // for buttons, allows onClick handler to fire onPointerDown
     isExpanded?: boolean; // is linear view expanded
+    textTransform?: string; // is linear view expanded
+    letterSpacing?: string; // is linear view expanded
 }
 
 class EmptyBox {
diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss
index f9a52d976..d980b0a91 100644
--- a/src/client/views/GestureOverlay.scss
+++ b/src/client/views/GestureOverlay.scss
@@ -11,4 +11,10 @@
     position: absolute;
     width: 300px;
     height: 300px;
+}
+
+.filter-cont {
+    position: absolute;
+    background-color: transparent;
+    border: 1px solid black;
 }
\ No newline at end of file
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 7fb8e7797..e44db4463 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -24,19 +24,25 @@ import { DocumentContentsView } from "./nodes/DocumentContentsView";
 export default class GestureOverlay extends Touchable {
     static Instance: GestureOverlay;
 
-    @observable private _points: { X: number, Y: number }[] = [];
-    @observable private _palette?: JSX.Element;
-    @observable private _clipboardDoc?: JSX.Element;
     @observable public Color: string = "rgb(244, 67, 54)";
     @observable public Width: number = 5;
     @observable public SavedColor?: string;
     @observable public SavedWidth?: number;
 
-    private _d1: Doc | undefined;
-    private _thumbDoc: Doc | undefined;
     @observable private _thumbX?: number;
     @observable private _thumbY?: number;
+    @observable private _pointerY?: number;
+    @observable private _points: { X: number, Y: number }[] = [];
+    @observable private _palette?: JSX.Element;
+    @observable private _clipboardDoc?: JSX.Element;
+    @observable private _showBounds: boolean = false;
+
+    @computed private get height(): number { return Math.max(this._pointerY && this._thumbY ? this._thumbY - this._pointerY : 300, 300); }
+
+    private _d1: Doc | undefined;
+    private _thumbDoc: Doc | undefined;
     private thumbIdentifier?: number;
+    private pointerIdentifier?: number;
     private _hands: Map<number, React.Touch[]> = new Map<number, React.Touch[]>();
 
     protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
@@ -178,7 +184,7 @@ export default class GestureOverlay extends Touchable {
         e.stopPropagation();
     }
 
-    handleHandDown = (e: React.TouchEvent) => {
+    handleHandDown = async (e: React.TouchEvent) => {
         const fingers = new Array<React.Touch>();
         for (let i = 0; i < e.touches.length; i++) {
             const pt: any = e.touches.item(i);
@@ -194,6 +200,22 @@ export default class GestureOverlay extends Touchable {
             }
         }
         const thumb = fingers.reduce((a, v) => a.clientY > v.clientY ? a : v, fingers[0]);
+        const rightMost = Math.max(...fingers.map(f => f.clientX));
+        const leftMost = Math.min(...fingers.map(f => f.clientX));
+        let pointer: React.Touch | undefined;
+        // left hand
+        if (thumb.clientX === rightMost) {
+            pointer = fingers.reduce((a, v) => a.clientX > v.clientX || v.identifier === thumb.identifier ? a : v);
+        }
+        // right hand
+        else if (thumb.clientX === leftMost) {
+            pointer = fingers.reduce((a, v) => a.clientX < v.clientX || v.identifier === thumb.identifier ? a : v);
+        }
+        else {
+            console.log("not hand");
+        }
+        this.pointerIdentifier = pointer?.identifier;
+        runInAction(() => this._pointerY = pointer?.clientY);
         if (thumb.identifier === this.thumbIdentifier) {
             this._thumbX = thumb.clientX;
             this._thumbY = thumb.clientY;
@@ -201,15 +223,12 @@ export default class GestureOverlay extends Touchable {
             return;
         }
         this.thumbIdentifier = thumb?.identifier;
-        // fingers.forEach((f) => this.prevPoints.delete(f.identifier));
         this._hands.set(thumb.identifier, fingers);
         const others = fingers.filter(f => f !== thumb);
         const minX = Math.min(...others.map(f => f.clientX));
         const minY = Math.min(...others.map(f => f.clientY));
-        // const t = this.getTransform().transformPoint(minX, minY);
-        // const th = this.getTransform().transformPoint(thumb.clientX, thumb.clientY);
 
-        const thumbDoc = FieldValue(Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc));
+        const thumbDoc = await Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc);
         if (thumbDoc) {
             runInAction(() => {
                 this._thumbDoc = thumbDoc;
@@ -247,7 +266,7 @@ export default class GestureOverlay extends Touchable {
             }
         }
         const thumb = fingers.reduce((a, v) => a.clientY > v.clientY ? a : v, fingers[0]);
-        if (thumb?.identifier === this.thumbIdentifier) {
+        if (thumb?.identifier && thumb?.identifier === this.thumbIdentifier) {
             this._hands.set(thumb.identifier, fingers);
         }
 
@@ -259,6 +278,9 @@ export default class GestureOverlay extends Touchable {
                     this._thumbX = pt.clientX;
                 }
             }
+            if (pt && pt.identifier === this.pointerIdentifier) {
+                this._pointerY = pt.clientY;
+            }
         }
     }
 
@@ -329,8 +351,6 @@ export default class GestureOverlay extends Touchable {
         return actionPerformed;
     }
 
-
-
     @action
     onPointerUp = (e: PointerEvent) => {
         if (this._points.length > 1) {
@@ -414,7 +434,6 @@ export default class GestureOverlay extends Touchable {
     @computed get elements() {
         return [
             this.props.children,
-            // this._clipboardDoc,
             this._palette,
             this.currentStroke
         ];
@@ -422,8 +441,6 @@ export default class GestureOverlay extends Touchable {
 
     @action
     public openFloatingDoc = (doc: Doc) => {
-        // const t = new Transform(-(this._clipboardDoc ? (this._thumbX ?? 0) : -350), -(this._thumbY ?? 0) + 350, 1);
-        // let t =
         this._clipboardDoc =
             <DocumentView
                 Document={doc}
@@ -435,7 +452,7 @@ export default class GestureOverlay extends Touchable {
                 onClick={undefined}
                 ruleProvider={undefined}
                 removeDocument={undefined}
-                ScreenToLocalTransform={() => new Transform(-(this._thumbX ?? 0), -(this._thumbY ?? 0) + 350, 1)}
+                ScreenToLocalTransform={() => new Transform(-(this._thumbX ?? 0), -(this._thumbY ?? 0) + this.height, 1)}
                 ContentScaling={returnOne}
                 PanelWidth={() => 300}
                 PanelHeight={() => 300}
@@ -462,13 +479,24 @@ export default class GestureOverlay extends Touchable {
             <div className="gestureOverlay-cont" onPointerDown={this.onPointerDown} onTouchStart={this.onReactTouchStart}>
                 {this.elements}
                 <div className="clipboardDoc-cont" style={{
-                    transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - 350}px)`,
+                    transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - this.height}px)`,
+                    height: this.height,
+                    width: this.height,
                     pointerEvents: this._clipboardDoc ? "unset" : "none",
-                    touchAction: this._clipboardDoc ? "unset" : "none"
+                    touchAction: this._clipboardDoc ? "unset" : "none",
                 }}>
                     {this._clipboardDoc}
                 </div>
-            </div>);
+                <div className="filter-cont" style={{
+                    transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - this.height}px)`,
+                    height: this.height,
+                    width: this.height,
+                    pointerEvents: this._showBounds ? "unset" : "none",
+                    touchAction: this._showBounds ? "unset" : "none",
+                    display: this._showBounds ? "unset" : "none",
+                }}>
+                </div>
+            </div >);
     }
 }
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 168d2ea18..14ee0dc53 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -46,7 +46,7 @@ import RichTextMenu from '../util/RichTextMenu';
 @observer
 export class MainView extends React.Component {
     public static Instance: MainView;
-    private _buttonBarHeight = 75;
+    private _buttonBarHeight = 35;
     private _flyoutSizeOnDown = 0;
     private _urlState: HistoryUtil.DocUrl;
     private _docBtnRef = React.createRef<HTMLDivElement>();
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 8b0638aa1..77af2dc0e 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -48,7 +48,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
             (i) => runInAction(() => {
                 this._selectedIndex = i;
                 let selected: any = undefined;
-                this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => {
+                this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map(async (pair, ind) => {
                     const isSelected = this._selectedIndex === ind;
                     if (isSelected) {
                         selected = pair;
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index d1272c266..d29fe1711 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -80,7 +80,10 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
         return (
             <div className="buttonBox-outerDiv" ref={this.createDropTarget} onContextMenu={this.specificContextMenu}
                 style={{ boxShadow: this.Document.opacity === 0 ? undefined : StrCast(this.Document.boxShadow, "") }}>
-                <div className="buttonBox-mainButton" style={{ background: this.Document.backgroundColor || "", color: this.Document.color || "black", fontSize: this.Document.fontSize }} >
+                <div className="buttonBox-mainButton" style={{
+                    background: this.Document.backgroundColor, color: this.Document.color || "black",
+                    fontSize: this.Document.fontSize, letterSpacing: this.Document.letterSpacing || "", textTransform: this.Document.textTransform || ""
+                }} >
                     <div className="buttonBox-mainButtonCenter">
                         {(this.Document.text || this.Document.title)}
                     </div>
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
index 24f6224eb..d5c34e128 100644
--- a/src/new_fields/documentSchemas.ts
+++ b/src/new_fields/documentSchemas.ts
@@ -57,6 +57,8 @@ export const documentSchema = createSchema({
     yPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
     LODarea: "number",          // area (width*height) where CollectionFreeFormViews switch from a label to rendering contents
     LODdisable: "boolean",      // whether to disbale LOD switching for CollectionFreeFormViews
+    letterSpacing: "string",
+    textTransform: "string"
 });
 
 export const positionSchema = createSchema({
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index adeee452c..3e6399d82 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -129,7 +129,7 @@ export class CurrentUserUtils {
     static setupThumbDoc(userDoc: Doc) {
         if (!userDoc.thumbDoc) {
             userDoc.thumbDoc = Docs.Create.LinearDocument(CurrentUserUtils.setupThumbButtons(userDoc), {
-                width: 100, height: 50, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons", autoHeight: true, yMargin: 5, isExpanded: true
+                width: 100, height: 50, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons", autoHeight: true, yMargin: 5, isExpanded: true, backgroundColor: "white"
             });
         }
         return userDoc.thumbDoc;
@@ -154,7 +154,8 @@ export class CurrentUserUtils {
         });
 
         return Docs.Create.ButtonDocument({
-            width: 35, height: 35, backgroundColor: "#222222", color: "lightgrey", title: "Tools", fontSize: 10, targetContainer: sidebarContainer,
+            width: 35, height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Tools", fontSize: 10, targetContainer: sidebarContainer,
+            letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.StackingDocument([dragCreators, color], {
                 width: 500, height: 800, lockedPosition: true, chromeStatus: "disabled", title: "tools stack"
             }),
@@ -179,9 +180,10 @@ export class CurrentUserUtils {
         });
 
         return Docs.Create.ButtonDocument({
-            width: 50, height: 35, backgroundColor: "#222222", color: "lightgrey", title: "Library", fontSize: 10,
+            width: 50, height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Library", fontSize: 10,
+            letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.TreeDocument([doc.workspaces as Doc, doc.documents as Doc, doc.recentlyClosed as Doc], {
-                title: "Library", xMargin: 5, yMargin: 5, gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true
+                title: "Library", xMargin: 5, yMargin: 5, gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0",
             }),
             targetContainer: sidebarContainer,
             onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel;")
@@ -191,7 +193,8 @@ export class CurrentUserUtils {
     // setup the Search button which will display the search panel.  
     static setupSearchPanel(sidebarContainer: Doc) {
         return Docs.Create.ButtonDocument({
-            width: 50, height: 35, backgroundColor: "#222222", color: "lightgrey", title: "Search", fontSize: 10,
+            width: 50, height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Search", fontSize: 10,
+            letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.QueryDocument({
                 title: "search stack", ignoreClick: true
             }),
@@ -214,7 +217,8 @@ export class CurrentUserUtils {
         // Finally, setup the list of buttons to display in the sidebar
         doc.sidebarButtons = Docs.Create.StackingDocument([doc.SearchBtn as Doc, doc.LibraryBtn as Doc, doc.ToolsBtn as Doc], {
             width: 500, height: 80, boxShadow: "0 0", sectionFilter: "title", hideHeadings: true, ignoreClick: true,
-            backgroundColor: "lightgrey", chromeStatus: "disabled", title: "library stack"
+            backgroundColor: "rgb(100, 100, 100)", chromeStatus: "disabled", title: "library stack",
+            yMargin: 10,
         });
     }
 
-- 
cgit v1.2.3-70-g09d2

