diff options
| author | eleanor-park <eleanor_park@brown.edu> | 2024-07-11 11:50:01 -0400 |
|---|---|---|
| committer | eleanor-park <eleanor_park@brown.edu> | 2024-07-11 11:50:01 -0400 |
| commit | 49b3c7cbe01f830a2b1d2c02452901fe360348d3 (patch) | |
| tree | ad4efc73fac5e2dfa20b1911399821614f42fa8c /src/client/views/smartdraw/AnnotationPalette.tsx | |
| parent | f33e6c9e191092e6050f980892b4404ff0d0a1f2 (diff) | |
updates
Diffstat (limited to 'src/client/views/smartdraw/AnnotationPalette.tsx')
| -rw-r--r-- | src/client/views/smartdraw/AnnotationPalette.tsx | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/src/client/views/smartdraw/AnnotationPalette.tsx b/src/client/views/smartdraw/AnnotationPalette.tsx new file mode 100644 index 000000000..10e88e91e --- /dev/null +++ b/src/client/views/smartdraw/AnnotationPalette.tsx @@ -0,0 +1,337 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { flexibleCompare } from '@fullcalendar/core/internal'; +import { Slider, Switch } from '@mui/material'; +import { Button, IconButton } from 'browndash-components'; +import { data } from 'jquery'; +import { action, computed, makeObservable, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { AiOutlineSend } from 'react-icons/ai'; +import ReactLoading from 'react-loading'; +import { returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero } from '../../../ClientUtils'; +import { ActiveInkWidth, Doc, StrListCast } from '../../../fields/Doc'; +import { DocData } from '../../../fields/DocSymbols'; +import { InkData, InkField } from '../../../fields/InkField'; +import { BoolCast, DocCast } from '../../../fields/Types'; +import { emptyFunction } from '../../../Utils'; +import { Docs } from '../../documents/Documents'; +import { CollectionViewType } from '../../documents/DocumentTypes'; +import { DragManager } from '../../util/DragManager'; +import { convertDropDataToButtons, makeUserTemplateButton } from '../../util/DropConverter'; +import { SettingsManager } from '../../util/SettingsManager'; +import { Transform } from '../../util/Transform'; +import { MarqueeOptionsMenu, MarqueeView } from '../collections/collectionFreeForm'; +import { CollectionGridView } from '../collections/collectionGrid'; +import { CollectionStackingView } from '../collections/CollectionStackingView'; +import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView'; +import { FieldViewProps } from '../nodes/FieldView'; +import { ObservableReactComponent } from '../ObservableReactComponent'; +import { DefaultStyleProvider } from '../StyleProvider'; +import './AnnotationPalette.scss'; +import { SmartDrawHandler } from './SmartDrawHandler'; + +@observer +export class AnnotationPalette extends ObservableReactComponent<{}> { + static Instance: AnnotationPalette; + @observable private _savedDrawings: Doc[] = []; + // @observable private _marqueeViewRef = React.createRef<MarqueeView>(); + @observable private _display: boolean = false; + @observable private _paletteMode: 'create' | 'view' = 'view'; + @observable private _userInput: string = ''; + @observable private _showDrawing: boolean = false; + @observable private _drawing: Doc | undefined = undefined; + @observable private _isLoading: boolean = false; + @observable private _detail: number = 5; + @observable private _size: number = 350; + @observable private _canInteract: boolean = true; + + constructor(props: any) { + super(props); + makeObservable(this); + AnnotationPalette.Instance = this; + } + + return170 = () => 170; + + @action + setPaletteMode = (mode: 'create' | 'view') => { + this._paletteMode = mode; + }; + + @action + setUserInput = (input: string) => { + this._userInput = input; + }; + + @action + setDetail = (detail: number) => { + this._detail = detail; + }; + + @action + setSize = (size: number) => { + this._size = size; + }; + + saveAnno = async (docView: DocumentView | undefined, doc: Doc) => { + const dragData = new DragManager.DocumentDragData([doc]); + // convertDropDataToButtons(dragData); + const clone = await Doc.MakeClone(doc); + clone.clone.title = doc.title; + const templateBtn = makeUserTemplateButton(clone.clone); + + // const cloneData: Doc = DocCast(clone.clone[DocData]); + // cloneData.dragFactory = doc; + Doc.AddDocToList(Doc.MyAnnos, 'data', templateBtn); + // const collection = this._marqueeViewRef.current?.collection(undefined, false, this._savedDrawings); + // if (docView) docView.ComponentView?.removeDocument?.(doc); + }; + + @action + displayPalette = (display: boolean) => { + this._display = display; + }; + + @action + generateDrawing = async () => { + this._isLoading = true; + try { + const drawingRes = await SmartDrawHandler.Instance.drawWithGPT({ X: 0, Y: 0 }, this._userInput); + const opts = drawingRes?.lastInput; + const drawing: Doc[] = []; + drawingRes?.data.forEach((stroke: [InkData, string, string]) => { + const bounds = InkField.getBounds(stroke[0]); + // const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height); + const inkWidth = ActiveInkWidth(); + const inkDoc = Docs.Create.InkDocument( + stroke[0], + { title: 'stroke', + // x: B.x - inkWidth / 2, + // y: B.y - inkWidth / 2, + // _width: B.width + inkWidth, + // _height: B.height + inkWidth, + stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore + inkWidth, + stroke[1], + undefined, + stroke[2] === 'none' ? undefined : stroke[2] + ); + drawing.push(inkDoc); + }); + const collection = MarqueeOptionsMenu.Instance.createCollection(undefined, true, drawing); + if (collection) { + const docData = collection[DocData]; + docData.title = opts?.text; + docData.drawingInput = opts?.text; + docData.drawingComplexity = opts?.complexity; + docData.drawingColored = opts?.autoColor; + docData.drawingSize = opts?.size; + docData.drawingData = drawingRes?.lastRes; + this._drawing = collection; + } + this._showDrawing = true; + } catch (e) { + console.log('Error generating drawing'); + } + this._isLoading = false; + }; + + // @computed get drawingCreator() { + // return ( + // MarqueeOptionsMenu.Instance.createCollection(undefined, true, this._drawing); + // ); + // } + // return Docs.Create.FreeformDocument([], {}); + // Docs.Create. + // return ( + // <DocumentView + // Document={doc} + // addDocument={undefined} + // addDocTab={DocumentViewInternal.addDocTabFunc} + // pinToPres={DocumentView.PinDoc} + // containerViewPath={returnEmptyDoclist} + // styleProvider={DefaultStyleProvider} + // removeDocument={returnFalse} + // ScreenToLocalTransform={Transform.Identity} + // PanelWidth={this.return170} + // PanelHeight={this.return170} + // renderDepth={0} + // isContentActive={returnTrue} + // focus={emptyFunction} + // whenChildContentsActiveChanged={emptyFunction} + // childFilters={returnEmptyFilter} + // childFiltersByRanges={returnEmptyFilter} + // searchFilterDocs={returnEmptyDoclist} + // /> + // ); + + render() { + return !this._display ? null : ( + <div className="annotation-palette" style={{ zIndex: 1000 }}> + {this._paletteMode === 'view' && ( + <> + <DocumentView + Document={Doc.MyAnnos} + addDocument={undefined} + addDocTab={DocumentViewInternal.addDocTabFunc} + pinToPres={DocumentView.PinDoc} + containerViewPath={returnEmptyDoclist} + styleProvider={DefaultStyleProvider} + removeDocument={returnFalse} + ScreenToLocalTransform={Transform.Identity} + PanelWidth={this.return170} + PanelHeight={this.return170} + renderDepth={0} + isContentActive={returnTrue} + focus={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} + childFilters={returnEmptyFilter} + childFiltersByRanges={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} + /> + <Button + // style={{ alignSelf: 'center' }} + text="Add" + icon={<FontAwesomeIcon icon="square-plus" />} + // iconPlacement="" + color={SettingsManager.userColor} + onClick={() => this.setPaletteMode('create')} + /> + </> + )} + {this._paletteMode === 'create' && ( + <> + <div style={{ display: 'flex', flexDirection: 'row', width: '170px' }}> + {/* <IconButton + tooltip="Advanced Options" + icon={<FontAwesomeIcon icon="caret-right" />} + color={SettingsManager.userColor} + style={{ width: '14px' }} + // onClick={() => { + // this._showOptions = !this._showOptions; + // }} + /> */} + <input + aria-label="label-input" + id="new-label" + type="text" + style={{ color: 'black', width: '170px' }} + value={this._userInput} + onChange={e => { + this.setUserInput(e.target.value); + }} + placeholder="Enter item to draw" + // onKeyDown={this.handleKeyPress} + /> + <Button + style={{ alignSelf: 'flex-end' }} + // text="Send" + icon={this._isLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />} + iconPlacement="right" + color={SettingsManager.userColor} + onClick={this.generateDrawing} + /> + </div> + <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: '170px', marginTop: '5px' }}> + <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '40px' }}> + Color + <Switch + sx={{ + '& .MuiSwitch-switchBase.Mui-checked': { + color: SettingsManager.userColor, + }, + '& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': { + backgroundColor: SettingsManager.userVariantColor, + }, + }} + defaultChecked={true} + size="small" + // onChange={this.setAutoColor} + /> + </div> + <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '60px' }}> + Detail + <Slider + sx={{ + '& .MuiSlider-thumb': { + color: SettingsManager.userColor, + '&.Mui-focusVisible, &:hover, &.Mui-active': { + boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}10`, + }, + }, + '& .MuiSlider-track': { + color: SettingsManager.userVariantColor, + }, + '& .MuiSlider-rail': { + color: SettingsManager.userColor, + }, + }} + style={{ width: '80%' }} + min={1} + max={10} + step={1} + size="small" + value={this._detail} + onChange={(e, val) => { + this.setDetail(val as number); + }} + valueLabelDisplay="auto" + /> + </div> + <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '60px' }}> + Size + <Slider + sx={{ + '& .MuiSlider-thumb': { + color: SettingsManager.userColor, + '&.Mui-focusVisible, &:hover, &.Mui-active': { + boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}20`, + }, + }, + '& .MuiSlider-track': { + color: SettingsManager.userVariantColor, + }, + '& .MuiSlider-rail': { + color: SettingsManager.userColor, + }, + }} + style={{ width: '80%' }} + min={50} + max={700} + step={10} + size="small" + value={this._size} + onChange={(e, val) => { + this.setSize(val as number); + }} + valueLabelDisplay="auto" + /> + </div> + </div> + {this._drawing !== undefined && ( + <DocumentView + Document={this._drawing} + addDocument={undefined} + addDocTab={DocumentViewInternal.addDocTabFunc} + pinToPres={DocumentView.PinDoc} + containerViewPath={returnEmptyDoclist} + styleProvider={DefaultStyleProvider} + removeDocument={returnFalse} + ScreenToLocalTransform={Transform.Identity} + PanelWidth={this.return170} + PanelHeight={this.return170} + renderDepth={0} + isContentActive={returnTrue} + focus={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} + childFilters={returnEmptyFilter} + childFiltersByRanges={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} + /> + )} + </> + )} + </div> + ); + } +} |
