aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/MainView.tsx4
-rw-r--r--src/client/views/MarqueeAnnotator.tsx5
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx26
-rw-r--r--src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx95
4 files changed, 57 insertions, 73 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a1cb44106..44e00396e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -55,7 +55,6 @@ import { TabDocView } from './collections/TabDocView';
import './collections/TreeView.scss';
import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { ImageLabelHandler } from './collections/collectionFreeForm/ImageLabelHandler';
-import { SmartDrawHandler } from './collections/collectionFreeForm/SmartDrawHandler';
import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu';
import { CollectionLinearView } from './collections/collectionLinear';
import { LinkMenu } from './linking/LinkMenu';
@@ -318,6 +317,7 @@ export class MainView extends ObservableReactComponent<{}> {
fa.faCompass,
fa.faSnowflake,
fa.faStar,
+ fa.faSplotch,
fa.faMicrophone,
fa.faCircleHalfStroke,
fa.faKeyboard,
@@ -402,7 +402,6 @@ export class MainView extends ObservableReactComponent<{}> {
fa.faPortrait,
fa.faRedoAlt,
fa.faStamp,
- fa.faTape,
fa.faStickyNote,
fa.faArrowsAltV,
fa.faTimesCircle,
@@ -1092,7 +1091,6 @@ export class MainView extends ObservableReactComponent<{}> {
<TaskCompletionBox />
<ContextMenu />
<ImageLabelHandler />
- <SmartDrawHandler />
<AnchorMenu />
<MapAnchorMenu />
<DirectionsAnchorMenu />
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index db48e095d..f06f3efe0 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -74,7 +74,8 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
onClick: isLinkButton ? FollowLinkScript() : undefined,
backgroundColor: color,
annotationOn: this.props.Document,
- title: 'Annotation on ' + this.props.Document.title,a
+ title: 'Annotation on ' + this.props.Document.title,
+ a,
});
marqueeAnno.x = NumCast(doc.freeform_panX_min) + (parseInt(anno.style.left || '0') - containerOffset[0]) / scale;
marqueeAnno.y = NumCast(doc.freeform_panY_min) + (parseInt(anno.style.top || '0') - containerOffset[1]) / scale;
@@ -215,7 +216,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
marqueeAnno.y = NumCast(doc.freeform_panY_min) / scale;
marqueeAnno._height = parseInt('100') / scale;
marqueeAnno._width = parseInt('100') / scale;
- return marqueeAnno;
+ return marqueeAnno;
// }
// const textRegionAnno = Docs.Create.ConfigDocument({
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e66dbd796..a27ac2a0c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,12 +1,13 @@
/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
-import { Bezier } from 'bezier-js';
+import { Bezier, Point } from 'bezier-js';
import { Colors } from 'browndash-components';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
+import { TbAlpha } from 'react-icons/tb';
import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
import { ActiveEraserWidth, ActiveInkWidth, Doc, DocListCast, Field, FieldType, Opt, SetActiveInkColor, SetActiveInkWidth } from '../../../../fields/Doc';
@@ -26,6 +27,7 @@ import { aggregateBounds, clamp, emptyFunction, intersectRect, Utils } from '../
import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
import { DocUtils } from '../../../documents/DocUtils';
+import { FitCurve, GenerateControlPoints } from '../../../util/bezierFit';
import { DragManager } from '../../../util/DragManager';
import { dropActionType } from '../../../util/DropActionTypes';
import { CompileScript } from '../../../util/Scripting';
@@ -55,7 +57,6 @@ import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCurso
import './CollectionFreeFormView.scss';
import { MarqueeView } from './MarqueeView';
import { SmartDrawHandler } from './SmartDrawHandler';
-import { ImageLabelHandler } from './ImageLabelHandler';
@observer
class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> {
@@ -144,10 +145,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
: this._props.childPointerEvents?.() ??
(this._props.viewDefDivClick || //
(this.layoutEngine === computePassLayout.name && !this._props.isSelected()) ||
- this.isContentActive() === false ||
- Doc.ActiveTool === InkTool.RadiusEraser ||
- Doc.ActiveTool === InkTool.SegmentEraser ||
- Doc.ActiveTool === InkTool.StrokeEraser
+ this.isContentActive() === false
? 'none'
: this._props.pointerEvents?.());
}
@@ -685,6 +683,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@action
onEraserClick = (e: PointerEvent, doubleTap?: boolean) => {
this.erase(e, [0, 0]);
+ e.stopPropagation();
return false;
};
@@ -1265,19 +1264,20 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@action
createDrawing = (e: PointerEvent, doubleTap?: boolean) => {
- SmartDrawHandler.Instance.displaySmartDrawHandler(e.pageX, e.pageY, this.createInkStroke);
+ SmartDrawHandler.Instance.displaySmartDrawHandler(e.pageX, e.pageY, this.createInkStrokes);
};
@action
- createInkStroke = (strokeList: InkData[]) => {
- strokeList.forEach(coords => {
- // const stroke = new InkField(coords);
- // const points = coords.map(p => intersect.inkView.ComponentView?.ptToScreen?.({ X: p.X, Y: p.Y }) ?? { X: 0, Y: 0 }), [] as PointData[]);
- const bounds = InkField.getBounds(coords);
+ createInkStrokes = (strokeList: InkData[], alpha?: number) => {
+ console.log(strokeList.length);
+ strokeList.forEach(inkData => {
+ // const points: InkData = FitCurve(inkData, 20) as InkData;
+ const allPts = GenerateControlPoints(inkData, alpha);
+ const bounds = InkField.getBounds(allPts);
const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height);
const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
const inkDoc = Docs.Create.InkDocument(
- coords,
+ allPts,
{ title: 'stroke',
x: B.x - inkWidth / 2,
y: B.y - inkWidth / 2,
diff --git a/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx b/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx
index fc8f7a429..4c2e78e31 100644
--- a/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx
+++ b/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx
@@ -11,6 +11,7 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu';
import './ImageLabelHandler.scss';
import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
import { InkData } from '../../../../fields/InkField';
+import { ButtonType } from '../../nodes/FontIconBox/FontIconBox';
@observer
export class SmartDrawHandler extends ObservableReactComponent<{}> {
@@ -22,8 +23,11 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
@observable private _yRelativeToTop: boolean = true;
@observable private _isLoading: boolean = false;
@observable private _userInput: string = '';
+ @observable private _drawingTypeToolTip = 'Create Geometric Drawing';
+ @observable private _drawingTypeIcon: 'star' | 'splotch' = 'star';
+ @observable private _alpha: number | undefined = undefined; // number between 0 and 1 that determines how rounded a drawing will be
// @observable public strokes: InkData[] = [];
- private _addToDocFunc: (strokeList: InkData[]) => void = () => {};
+ private _addToDocFunc: (strokeList: InkData[], alpha?: number) => void = () => {};
constructor(props: any) {
super(props);
@@ -42,7 +46,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
};
@action
- displaySmartDrawHandler = (x: number, y: number, addToDoc: (strokeList: InkData[]) => void) => {
+ displaySmartDrawHandler = (x: number, y: number, addToDoc: (strokeList: InkData[], alpha?: number) => void) => {
this._pageX = x;
this._pageY = y;
this._display = true;
@@ -50,14 +54,11 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
};
@action
- hideLabelhandler = () => {
+ hideSmartDrawHandler = () => {
this._display = false;
};
@action
- waitForCoords = async () => {};
-
- @action
drawWithGPT = async (startPoint: { X: number; Y: number }, input: string) => {
console.log('start point is', startPoint);
this.setIsLoading(true);
@@ -68,25 +69,18 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
return;
}
console.log('GPT response:', res);
- // const controlPts: [number, number][][] = JSON.parse(res) as [number, number][][];
- // console.log("Control Points", controlPts);
- // const transformedPts: { X: number; Y: number }[][] = [];
- // controlPts.forEach(stroke => {
- // stroke.map(pt => {
- // pt.X += startPoint.X, pt.Y += startPoint.Y;
- // });
- // transformedPts.push(stroke);
- // });
const simplifiedRes: string = res.replace(/[^\d\[\],]/g, '');
- console.log(simplifiedRes)
try {
- const controlPts: { X: number; Y: number }[][] = JSON.parse(simplifiedRes).map((stroke: [number, number][]) => stroke.map(([X, Y]) => ({ X: X + startPoint.X, Y: Y + startPoint.Y })));
- console.log('transformed points', controlPts);
-
- // this.strokes = controlPts;
- this._addToDocFunc(controlPts);
+ const parsedPts = JSON.parse(simplifiedRes);
+ if (parsedPts[0][0][0]) {
+ const controlPts = (parsedPts as [number, number][][]).map((stroke: [number, number][]) => stroke.map(([X, Y]) => ({ X: X + startPoint.X - 100, Y: Y + startPoint.Y - 100 })));
+ this._addToDocFunc(controlPts, this._alpha);
+ } else {
+ const controlPts = (parsedPts as [number, number][]).map(([X, Y]) => ({ X: X + startPoint.X - 100, Y: Y + startPoint.Y - 100 }));
+ this._addToDocFunc([controlPts], this._alpha);
+ }
} catch (err) {
- console.error('Incompatible GPT output type');
+ console.error('Error likely from bad GPT output type');
}
} catch (err) {
console.error('GPT call failed', err);
@@ -94,6 +88,19 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
this.setIsLoading(false);
this.setUserInput('');
+ this.hideSmartDrawHandler();
+ };
+
+ changeDrawingType = () => {
+ if (this._drawingTypeIcon === 'star') {
+ this._drawingTypeIcon = 'splotch';
+ this._drawingTypeToolTip = 'Create Rounded Drawing';
+ this._alpha = 0.2;
+ } else {
+ this._drawingTypeIcon = 'star';
+ this._drawingTypeToolTip = 'Create Geometric Drawing';
+ this._alpha = 0;
+ }
};
render() {
@@ -110,7 +117,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
color: SettingsManager.userColor,
}}>
<div>
- <IconButton tooltip={'Cancel'} onPointerDown={this.hideLabelhandler} icon={<FontAwesomeIcon icon="xmark" />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} />
+ <IconButton tooltip={'Cancel'} onClick={this.hideSmartDrawHandler} icon={<FontAwesomeIcon icon="xmark" />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} />
<input
aria-label="label-input"
id="new-label"
@@ -122,6 +129,16 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
}}
placeholder="Enter item to draw"
/>
+ <IconButton tooltip={this._drawingTypeToolTip} icon={<FontAwesomeIcon icon={this._drawingTypeIcon} />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '14px' }} onClick={this.changeDrawingType} />
+ {/* <IconButton
+ tooltip="Create Geometric Drawing"
+ icon={<FontAwesomeIcon icon="star" />}
+ color={MarqueeOptionsMenu.Instance.userColor}
+ style={{ width: '14px' }}
+ onClick={() => {
+ this._alpha = 0;
+ }}
+ /> */}
<Button
style={{ alignSelf: 'flex-end' }}
text="Send"
@@ -132,38 +149,6 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
this.drawWithGPT({ X: e.clientX, Y: e.clientY }, this._userInput);
}}
/>
- {/* <IconButton
- tooltip={'Generate Drawing'}
- onPointerDown={() => {
- const input = document.getElementById('new-label') as HTMLInputElement;
- const newLabel = input.value;
- // this.addLabel(newLabel);
- // this._currentLabel = '';
- input.value = '';
- }}
- icon={<FontAwesomeIcon icon="plus" />}
- color={MarqueeOptionsMenu.Instance.userColor}
- style={{ width: '19px' }}
- />
- <IconButton tooltip={'Group Images'} icon={<FontAwesomeIcon icon="object-group" />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> */}
- </div>
- <div>
- {/* {this._labelGroups.map(group => {
- return (
- <div>
- <p>{group}</p>
- <IconButton
- tooltip={'Remove Label'}
- onPointerDown={() => {
- this.removeLabel(group);
- }}
- icon={'x'}
- color={MarqueeOptionsMenu.Instance.userColor}
- style={{ width: '19px' }}
- />
- </div>
- );
- })} */}
</div>
</div>
);