aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts1
-rw-r--r--src/client/views/GestureOverlay.scss13
-rw-r--r--src/client/views/GestureOverlay.tsx127
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx29
6 files changed, 78 insertions, 101 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 64583ae55..1c13eb079 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -138,6 +138,7 @@ export interface DocumentOptions {
textTransform?: string; // is linear view expanded
letterSpacing?: string; // is linear view expanded
flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse";
+ selectedIndex?: number;
}
class EmptyBox {
diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss
index f425c438e..2fad87ee0 100644
--- a/src/client/views/GestureOverlay.scss
+++ b/src/client/views/GestureOverlay.scss
@@ -17,19 +17,18 @@
position: absolute;
width: 300px;
overflow: hidden;
+ pointer-events: none;
.inkToTextDoc-scroller {
overflow: visible;
position: absolute;
width: 100%;
- left: -24px;
- .collectionView {
- overflow: visible;
-
- .collectionLinearView-outer {
- overflow: visible;
- }
+ .menuItem-cont {
+ width: 100%;
+ height: 20px;
+ padding: 2.5px;
+ border-bottom: .5px solid black;
}
}
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 0fd6f3dba..e8262af1b 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -26,7 +26,7 @@ import { ScriptField } from "../../new_fields/ScriptField";
import { listSpec } from "../../new_fields/Schema";
import { List } from "../../new_fields/List";
import { CollectionViewType } from "./collections/CollectionView";
-import InkCanvas from "./InkCanvas";
+import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
@observer
export default class GestureOverlay extends Touchable {
@@ -40,12 +40,15 @@ export default class GestureOverlay extends Touchable {
@observable private _thumbX?: number;
@observable private _thumbY?: number;
+ @observable private _selectedIndex: number = -1;
+ @observable private _menuX: number = -300;
+ @observable private _menuY: number = -300;
@observable private _pointerY?: number;
@observable private _points: { X: number, Y: number }[] = [];
@observable private _strokes: InkData[] = [];
@observable private _palette?: JSX.Element;
@observable private _clipboardDoc?: JSX.Element;
- @observable private _possibilities: Doc[] = [];
+ @observable private _possibilities: JSX.Element[] = [];
@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; }
@@ -254,6 +257,8 @@ export default class GestureOverlay extends Touchable {
this._thumbDoc = thumbDoc;
this._thumbX = thumb.clientX;
this._thumbY = thumb.clientY;
+ this._menuX = thumb.clientX + 50;
+ this._menuY = thumb.clientY;
this._palette = <HorizontalPalette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
});
}
@@ -294,15 +299,14 @@ export default class GestureOverlay extends Touchable {
const pt = e.changedTouches.item(i);
if (pt && pt.identifier === this.thumbIdentifier && this._thumbY) {
if (this._thumbX && this._thumbDoc) {
- if (Math.abs(pt.clientX - this._thumbX) > 20) {
+ if (Math.abs(pt.clientX - this._thumbX) > 30) {
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;
+ this._selectedIndex = Math.max(0, -Math.floor((pt.clientY - this._thumbY) / 20));
}
}
}
@@ -324,11 +328,10 @@ export default class GestureOverlay extends Touchable {
let scriptWorked = false;
if (NumCast(this._inkToTextDoc?.selectedIndex) > -1) {
const selectedButton = this._possibilities[NumCast(this._inkToTextDoc?.selectedIndex)];
- if (Cast(selectedButton?.proto?.onClick, ScriptField)?.script.run({ this: selectedButton }, console.log).success) {
+ if (selectedButton) {
+ selectedButton.props.onClick();
scriptWorked = true;
- console.log("success");
- };
- console.log(Cast(selectedButton?.proto?.onClick, ScriptField)?.script);
+ }
}
if (!scriptWorked) {
@@ -337,6 +340,7 @@ export default class GestureOverlay extends Touchable {
});
}
this._strokes = [];
+ this._points = [];
this._possibilities = [];
document.removeEventListener("touchend", this.handleHandUp);
}
@@ -398,12 +402,12 @@ export default class GestureOverlay extends Touchable {
}
@action
- onPointerUp = async (e: PointerEvent) => {
+ onPointerUp = (e: PointerEvent) => {
if (this._points.length > 1) {
const B = this.svgBounds;
const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
- const initialPoint = this._points[0];
+ const initialPoint = this._points[0.];
const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + this.height;
const yInGlass = initialPoint.Y > (this._thumbY ?? Number.MAX_SAFE_INTEGER) - this.height && initialPoint.Y < (this._thumbY ?? Number.MAX_SAFE_INTEGER);
@@ -414,28 +418,21 @@ export default class GestureOverlay extends Touchable {
document.removeEventListener("pointerup", this.onPointerUp);
this._strokes.push(new Array(...this._points));
this._points = [];
- const results = await CognitiveServices.Inking.Appliers.InterpretStrokes(this._strokes);
- const wordResults = results.filter((r: any) => r.category === "inkWord");
- const possibilities: string[] = [];
- if (wordResults[0]?.recognizedText) {
- possibilities.push(wordResults[0]?.recognizedText)
- }
- possibilities.push(...wordResults[0]?.alternates?.map((a: any) => a.recognizedString));
- 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(() => {
- const buttons = possibilities.map(p => Docs.Create.ButtonDocument({
- _height: 25, _width: r - l, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", x: l, y: t, _viewType: CollectionViewType.Linear,
- isExpanded: true,
- title: p, fontSize: 10, letterSpacing: "0px", textTransform: "unset", boxShadow: ".5px .5px 0px rgb(34, 34, 34)",
- onClick: ScriptField.MakeScript('createText(this.proto.title, this.x, this.y)')
- }));
- if (this._inkToTextDoc && this._thumbDoc) {
- this._inkToTextDoc = this._thumbDoc.inkToTextDoc = Docs.Create.LinearDocument(buttons, { _width: 300, _height: 25, _autoHeight: true, _chromeStatus: "disabled", isExpanded: true, flexDirection: "column" });
- this._inkToTextDoc.selectedIndex = 0;
+ CognitiveServices.Inking.Appliers.InterpretStrokes(this._strokes).then((results) => {
+ const wordResults = results.filter((r: any) => r.category === "inkWord" || r.category === "paragraph");
+ const possibilities: string[] = [];
+ if (wordResults[0]?.recognizedText) {
+ possibilities.push(wordResults[0]?.recognizedText)
}
- this._possibilities = buttons;
+ 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(() => {
+ this._possibilities = possibilities.map(p =>
+ <TouchScrollableMenuItem text={p} onClick={() => GestureOverlay.Instance.dispatchGesture(GestureUtils.Gestures.Text, [{ X: l, Y: t }], p)} />);
+ });
});
break;
case ToolglassTools.IgnoreGesture:
@@ -511,10 +508,9 @@ export default class GestureOverlay extends Touchable {
return [
this.props.children,
this._palette,
-
[this._strokes.map(l => {
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 }}>
+ return <svg key={b.left} 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, GestureOverlay.Instance.Color, GestureOverlay.Instance.Width)}
</svg>;
}),
@@ -558,58 +554,6 @@ export default class GestureOverlay extends Touchable {
this._clipboardDoc = undefined;
}
- @computed
- private get suggestionContent() {
- 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: this._possibilities.length * 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 className="shadow" style={{ height: `calc(100% - 25px - ${NumCast(this._inkToTextDoc!.selectedIndex) * 25}px)` }}>
- </div>
- </div>)
- }
-
- private get inkToTextSuggestions() {
- if (this._inkToTextDoc && this._possibilities.length) {
- return (
- this.suggestionContent
- );
- }
- return null;
- }
-
render() {
trace();
return (
@@ -618,8 +562,8 @@ export default class GestureOverlay extends Touchable {
<div className="clipboardDoc-cont" style={{
transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - this.height}px)`,
- height: this.height,
- width: this.height,
+ height: this.height * 2,
+ width: this.height * 2,
pointerEvents: this._clipboardDoc ? "unset" : "none",
touchAction: this._clipboardDoc ? "unset" : "none",
}}>
@@ -627,14 +571,14 @@ export default class GestureOverlay extends Touchable {
</div>
<div className="filter-cont" style={{
transform: `translate(${this._thumbX}px, ${(this._thumbY ?? 0) - this.height}px)`,
- height: this.height,
- width: this.height,
+ height: this.height * 2,
+ width: this.height * 2,
pointerEvents: "none",
touchAction: "none",
display: this.showBounds ? "unset" : "none",
}}>
</div>
- {this.inkToTextSuggestions}
+ <TouchScrollableMenu options={this._possibilities} bounds={this.svgBounds} selectedIndex={this._selectedIndex} x={this._menuX} y={this._menuY} />
</div>);
}
}
@@ -666,6 +610,5 @@ Scripting.addGlobal(function resetPen() {
});
});
Scripting.addGlobal(function createText(text: any, x: any, y: any) {
- console.log("creating");
GestureOverlay.Instance.dispatchGesture("text", [{ X: x, Y: y }], text);
}); \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 17139d9d9..2b160f2ff 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -984,6 +984,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
</CollectionFreeFormViewPannableContents>
</MarqueeView>;
}
+
@computed get contentScaling() {
if (this.props.annotationsKey) return 0;
const hscale = this.nativeHeight ? this.props.PanelHeight() / this.nativeHeight : 1;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index 71f265484..db4b674b5 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -11,6 +11,7 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
public createCollection: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction;
public delete: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction;
public summarize: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction;
+ public inkToText: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction;
public showMarquee: () => void = unimplementedFunction;
public hideMarquee: () => void = unimplementedFunction;
@@ -43,6 +44,13 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
onPointerDown={this.delete}>
<FontAwesomeIcon icon="trash-alt" size="lg" />
</button>,
+ <button
+ className="antimodeMenu-button"
+ title="Change to Text"
+ key="inkToText"
+ onPointerDown={this.inkToText}>
+ <FontAwesomeIcon icon="font" size="lg" />
+ </button>,
];
return this.getElement(buttons);
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index ef2fc2ad1..112df8f05 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,12 +1,12 @@
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../../new_fields/Doc";
+import { Doc, DocListCast, DataSym, WidthSym, HeightSym } from "../../../../new_fields/Doc";
import { InkField } from "../../../../new_fields/InkField";
import { List } from "../../../../new_fields/List";
import { listSpec } from "../../../../new_fields/Schema";
import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
import { ComputedField } from "../../../../new_fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Cast, NumCast, StrCast, FieldValue } from "../../../../new_fields/Types";
import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
import { Utils } from "../../../../Utils";
import { Docs } from "../../../documents/Documents";
@@ -19,6 +19,7 @@ import "./MarqueeView.scss";
import React = require("react");
import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
import { SubCollectionViewProps } from "../CollectionSubView";
+import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
interface MarqueeViewProps {
getContainerTransform: () => Transform;
@@ -204,6 +205,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
MarqueeOptionsMenu.Instance.createCollection = this.collection;
MarqueeOptionsMenu.Instance.delete = this.delete;
MarqueeOptionsMenu.Instance.summarize = this.summary;
+ MarqueeOptionsMenu.Instance.inkToText = this.syntaxHighlight;
MarqueeOptionsMenu.Instance.showMarquee = this.showMarquee;
MarqueeOptionsMenu.Instance.hideMarquee = this.hideMarquee;
MarqueeOptionsMenu.Instance.jumpTo(e.clientX, e.clientY);
@@ -362,6 +364,29 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
@action
+ syntaxHighlight = (e: KeyboardEvent | React.PointerEvent | undefined) => {
+ const selected = this.marqueeSelect(false);
+ if (e instanceof KeyboardEvent ? e.key === "i" : true) {
+ const inks = selected.filter(s => s.proto?.type === "ink");
+ const sets = selected.filter(s => s.proto?.type === "text")
+ const inkFields = inks.map(i => FieldValue(Cast(i.data, InkField)));
+ CognitiveServices.Inking.Appliers.InterpretStrokes(inkFields.filter(i => i instanceof InkField).map(i => i!.inkData)).then((results) => {
+ const wordResults = results.filter((r: any) => r.category === "inkWord");
+ console.log(wordResults);
+ for (const word of wordResults) {
+ const indices: number[] = word.strokeIds;
+ const r = Math.floor(Math.random() * 256);
+ const g = Math.floor(Math.random() * 256);
+ const b = Math.floor(Math.random() * 256);
+ indices.forEach(i => {
+ inks[i].color = `rgb(${r}, ${g}, ${b})`;
+ })
+ }
+ });
+ }
+ }
+
+ @action
summary = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const bounds = this.Bounds;
const selected = this.marqueeSelect(false);