aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanley Yip <stanley_yip@brown.edu>2020-02-02 19:18:23 -0500
committerStanley Yip <stanley_yip@brown.edu>2020-02-02 19:18:23 -0500
commitdab8f5893ffb8fab05a46695b9d1a690d1171bca (patch)
tree83de29075a0d95191f2e82042ad49f33e70acaaa
parent8775ff05e1cfd8f158fb6f0a973d3ee5b9284005 (diff)
some more stuff
-rw-r--r--src/client/documents/Documents.ts1
-rw-r--r--src/client/views/GestureOverlay.scss19
-rw-r--r--src/client/views/GestureOverlay.tsx111
-rw-r--r--src/client/views/Touchable.tsx2
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx3
-rw-r--r--src/server/authentication/models/current_user_utils.ts4
6 files changed, 122 insertions, 18 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fa5707288..64583ae55 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -137,6 +137,7 @@ export interface DocumentOptions {
isExpanded?: boolean; // is linear view expanded
textTransform?: string; // is linear view expanded
letterSpacing?: string; // is linear view expanded
+ flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse";
}
class EmptyBox {
diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss
index d980b0a91..60b53c528 100644
--- a/src/client/views/GestureOverlay.scss
+++ b/src/client/views/GestureOverlay.scss
@@ -13,6 +13,25 @@
height: 300px;
}
+.inkToTextDoc-cont {
+ position: absolute;
+ width: 300px;
+ height: 300px;
+ overflow: hidden;
+
+ .inkToTextDoc-scroller {
+ overflow: visible;
+
+ .collectionView {
+ overflow: visible;
+
+ .collectionLinearView-outer {
+ overflow: visible;
+ }
+ }
+ }
+}
+
.filter-cont {
position: absolute;
background-color: transparent;
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 284224fb2..0c2e9e1bc 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -2,19 +2,19 @@ import React = require("react");
import { Touchable } from "./Touchable";
import { observer } from "mobx-react";
import "./GestureOverlay.scss";
-import { computed, observable, action, runInAction, IReactionDisposer, reaction } from "mobx";
+import { computed, observable, action, runInAction, IReactionDisposer, reaction, flow } from "mobx";
import { GestureUtils } from "../../pen-gestures/GestureUtils";
import { InteractionUtils } from "../util/InteractionUtils";
import { InkingControl } from "./InkingControl";
import { InkTool, InkData } from "../../new_fields/InkField";
import { Doc } from "../../new_fields/Doc";
import { LinkManager } from "../util/LinkManager";
-import { DocUtils } from "../documents/Documents";
+import { DocUtils, Docs } from "../documents/Documents";
import { undoBatch } from "../util/UndoManager";
import { Scripting } from "../util/Scripting";
import { FieldValue, Cast, NumCast, BoolCast } from "../../new_fields/Types";
import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
-import Palette from "./Palette";
+import HorizontalPalette from "./Palette";
import { Utils, emptyPath, emptyFunction, returnFalse, returnOne, returnEmptyString, returnTrue, numberRange } from "../../Utils";
import { DocumentView } from "./nodes/DocumentView";
import { Transform } from "../util/Transform";
@@ -22,6 +22,9 @@ import { DocumentContentsView } from "./nodes/DocumentContentsView";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
import { DocServer } from "../DocServer";
import htmlToImage from "html-to-image";
+import { ScriptField } from "../../new_fields/ScriptField";
+import { listSpec } from "../../new_fields/Schema";
+import { List } from "../../new_fields/List";
@observer
export default class GestureOverlay extends Touchable {
@@ -40,11 +43,13 @@ export default class GestureOverlay extends Touchable {
@observable private _strokes: InkData[] = [];
@observable private _palette?: JSX.Element;
@observable private _clipboardDoc?: JSX.Element;
+ @observable private _possibilities: Doc[] = [];
@computed private get height(): number { return Math.max(this._pointerY && this._thumbY ? this._thumbY - this._pointerY : 300, 300); }
@computed private get showBounds() { return this.Tool !== ToolglassTools.None; }
private _d1: Doc | undefined;
+ private _inkToTextDoc: Doc | undefined;
private _thumbDoc: Doc | undefined;
private thumbIdentifier?: number;
private pointerIdentifier?: number;
@@ -111,7 +116,6 @@ export default class GestureOverlay extends Touchable {
ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
const nts = this.getNewTouches(te);
- console.log(nts.nt.length);
if (nts.nt.length < 5) {
const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY);
@@ -239,10 +243,11 @@ export default class GestureOverlay extends Touchable {
const thumbDoc = await Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc);
if (thumbDoc) {
runInAction(() => {
+ this._inkToTextDoc = FieldValue(Cast(thumbDoc.inkToTextDoc, Doc));
this._thumbDoc = thumbDoc;
this._thumbX = thumb.clientX;
this._thumbY = thumb.clientY;
- this._palette = <Palette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
+ this._palette = <HorizontalPalette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
});
}
@@ -280,10 +285,18 @@ export default class GestureOverlay extends Touchable {
for (let i = 0; i < e.changedTouches.length; i++) {
const pt = e.changedTouches.item(i);
- if (pt && pt.identifier === this.thumbIdentifier && this._thumbX && this._thumbDoc) {
- if (Math.abs(pt.clientX - this._thumbX) > 20) {
- this._thumbDoc.selectedIndex = Math.max(0, NumCast(this._thumbDoc.selectedIndex) - Math.sign(pt.clientX - this._thumbX));
- this._thumbX = pt.clientX;
+ if (pt && pt.identifier === this.thumbIdentifier && this._thumbY) {
+ if (this._thumbX && this._thumbDoc) {
+ if (Math.abs(pt.clientX - this._thumbX) > 20) {
+ this._thumbDoc.selectedIndex = Math.max(0, NumCast(this._thumbDoc.selectedIndex) - Math.sign(pt.clientX - this._thumbX));
+ this._thumbX = pt.clientX;
+ }
+ }
+ if (this._thumbY && this._inkToTextDoc) {
+ if (Math.abs(pt.clientY - this._thumbY) > 20) {
+ this._inkToTextDoc.selectedIndex = Math.max(0, NumCast(this._inkToTextDoc.selectedIndex) - Math.sign(pt.clientY - this._thumbY));
+ this._thumbY = pt.clientY;
+ }
}
}
if (pt && pt.identifier === this.pointerIdentifier) {
@@ -304,6 +317,11 @@ export default class GestureOverlay extends Touchable {
this.dispatchGesture(GestureUtils.Gestures.Stroke, s);
});
this._strokes = [];
+ if (NumCast(this._inkToTextDoc?.selectedIndex) > 0) {
+ const selectedButton = this._possibilities[NumCast(this._inkToTextDoc?.selectedIndex) - 1];
+ Cast(selectedButton?.proto?.onClick, ScriptField)?.script.run({ this: selectedButton.proto }, console.log);
+ }
+ this._possibilities = [];
document.removeEventListener("touchend", this.handleHandUp);
}
}
@@ -382,9 +400,27 @@ export default class GestureOverlay extends Touchable {
this._points = [];
const results = await CognitiveServices.Inking.Appliers.InterpretStrokes(this._strokes);
const wordResults = results.filter((r: any) => r.category === "inkWord");
- const possibilities = [wordResults[0]?.recognizedText];
+ const possibilities: string[] = [];
+ if (wordResults[0]?.recognizedText) {
+ possibilities.push(wordResults[0]?.recognizedText)
+ }
possibilities.push(...wordResults[0]?.alternates?.map((a: any) => a.recognizedString));
- console.log(possibilities);
+ const r = Math.max(this.svgBounds.right, ...this._strokes.map(s => this.getBounds(s).right));
+ const l = Math.min(this.svgBounds.left, ...this._strokes.map(s => this.getBounds(s).left));
+ const t = Math.min(this.svgBounds.top, ...this._strokes.map(s => this.getBounds(s).top));
+ runInAction(() => {
+ console.log(possibilities);
+ const buttons = possibilities.map(p => Docs.Create.ButtonDocument({
+ _height: r - l, _width: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", x: l, y: t,
+ title: p, fontSize: 10, letterSpacing: "0px", textTransform: "unset", boxShadow: ".5px .5px 0px rgb(34, 34, 34)",
+ onClick: ScriptField.MakeScript('Docs.Create.TextDocument(this.title, {_width: 200, _height: 35, x: this.x, y: this.y})')
+ }));
+ if (this._inkToTextDoc) {
+ this._inkToTextDoc.data = new List<Doc>(buttons);
+ this._inkToTextDoc.selectedIndex = 0;
+ }
+ this._possibilities = buttons;
+ });
break;
case ToolglassTools.IgnoreGesture:
this.dispatchGesture(GestureUtils.Gestures.Stroke);
@@ -458,8 +494,7 @@ export default class GestureOverlay extends Touchable {
return (
[this._strokes.map(l => {
- let b = this.getBounds(l);
- console.log(b);
+ const b = this.getBounds(l);
return <svg width={b.width} height={b.height} style={{ transform: `translate(${b.left}px, ${b.top}px)`, pointerEvents: "none", position: "absolute", zIndex: 30000 }}>
{InteractionUtils.CreatePolyline(l, b.left, b.top, this.Color, this.Width)}
</svg>;
@@ -512,6 +547,53 @@ export default class GestureOverlay extends Touchable {
this._clipboardDoc = undefined;
}
+ @computed
+ private get inkToTextSuggestions() {
+ console.log(this._possibilities.length);
+ if (this._inkToTextDoc && this._possibilities.length) {
+ const b = Math.max(this.svgBounds.bottom, ...this._strokes.map(s => this.getBounds(s).bottom));
+ const r = Math.max(this.svgBounds.right, ...this._strokes.map(s => this.getBounds(s).right));
+ const l = Math.min(this.svgBounds.left, ...this._strokes.map(s => this.getBounds(s).left));
+ const t = Math.min(this.svgBounds.top, ...this._strokes.map(s => this.getBounds(s).top));
+
+ return (
+ <div className="inkToTextDoc-cont" style={{
+ transform: `translate(${l}px, ${b}px)`,
+ width: r - l,
+ height: 25,
+ }}>
+ <div className="inkToTextDoc-scroller" style={{ transform: `translate(0, ${-NumCast(this._inkToTextDoc.selectedIndex) * 25}px)` }}>
+ <DocumentView
+ Document={this._inkToTextDoc}
+ DataDoc={undefined}
+ LibraryPath={emptyPath}
+ addDocument={undefined}
+ addDocTab={returnFalse}
+ pinToPres={emptyFunction}
+ onClick={undefined}
+ removeDocument={undefined}
+ ScreenToLocalTransform={() => new Transform(-l, -(b + NumCast(this._inkToTextDoc?.selectedIndex, 0) * 25), 1)}
+ ContentScaling={returnOne}
+ PanelWidth={() => 300}
+ PanelHeight={() => 300}
+ renderDepth={0}
+ backgroundColor={returnEmptyString}
+ focus={emptyFunction}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ zoomToScale={emptyFunction}
+ getScale={returnOne}
+ />;
+ </div>
+ </div>
+ );
+ }
+ return null;
+ }
+
render() {
return (
<div className="gestureOverlay-cont" onPointerDown={this.onPointerDown} onTouchStart={this.onReactTouchStart}>
@@ -535,7 +617,8 @@ export default class GestureOverlay extends Touchable {
display: this.showBounds ? "unset" : "none",
}}>
</div>
- </div >);
+ {this.inkToTextSuggestions}
+ </div>);
}
}
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 7800c4019..ead6e2a00 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -92,7 +92,6 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
if (!InteractionUtils.IsDragging(this.prevPoints, myTouches, 5) && !this._touchDrag) return;
this._touchDrag = true;
if (this.holdTimer) {
- console.log("CLEAR");
clearTimeout(this.holdTimer);
// this.holdTimer = undefined;
}
@@ -129,7 +128,6 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
}
if (this.holdTimer) {
clearTimeout(this.holdTimer);
- console.log("clear");
}
this._touchDrag = false;
te.stopPropagation();
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 67062ae41..e613bf411 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -82,13 +82,14 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
render() {
const guid = Utils.GenerateGuid();
+ const flexDir: any = StrCast(this.Document.flexDirection);
return <div className="collectionLinearView-outer">
<div className="collectionLinearView" ref={this.createDashEventsTarget} >
<input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.isExpanded)} ref={this.addMenuToggle}
onChange={action((e: any) => this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} />
<label htmlFor={`${guid}`} style={{ marginTop: "auto", marginBottom: "auto", background: StrCast(this.props.Document.backgroundColor, "black") === StrCast(this.props.Document.color, "white") ? "black" : StrCast(this.props.Document.backgroundColor, "black") }} title="Close Menu"><p>+</p></label>
- <div className="collectionLinearView-content" style={{ height: this.dimension(), width: NumCast(this.props.Document._width, 25) }}>
+ <div className="collectionLinearView-content" style={{ height: this.dimension(), width: NumCast(this.props.Document._width, 25), flexDirection: flexDir }}>
{this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => {
const nested = pair.layout._viewType === CollectionViewType.Linear;
const dref = React.createRef<HTMLDivElement>();
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index dbde351b3..6c37380f3 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -131,9 +131,11 @@ export class CurrentUserUtils {
static setupThumbDoc(userDoc: Doc) {
if (!userDoc.thumbDoc) {
- userDoc.thumbDoc = Docs.Create.LinearDocument(CurrentUserUtils.setupThumbButtons(userDoc), {
+ const 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, backgroundColor: "white"
});
+ thumbDoc.inkToTextDoc = Docs.Create.LinearDocument([], { _width: 300, _height: 25, _autoHeight: true, _chromeStatus: "disabled", isExpanded: true, flexDirection: "column" });
+ userDoc.thumbDoc = thumbDoc;
}
return userDoc.thumbDoc;
}