diff options
Diffstat (limited to 'src/client/views')
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> ); |
