diff options
Diffstat (limited to 'src')
3 files changed, 91 insertions, 32 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index f1d98d22a..bdc0e1599 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -21,6 +21,8 @@ export interface CollectionFreeFormLinkViewProps { LinkDocs: Doc[]; } +// props.screentolocatransform + @observer export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFormLinkViewProps> { @observable _opacity: number = 0; @@ -235,8 +237,12 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo bActive, textX, textY, - pt1: [pt1[0] + pt1normalized[0] * 13, pt1[1] + pt1normalized[1] * 13], - pt2: [pt2[0] + pt2normalized[0] * 13, pt2[1] + pt2normalized[1] * 13], + // fully connected + pt1: pt1, + pt2: pt2, + // gaps between + // pt1: [pt1[0] + pt1normalized[0] * 13, pt1[1] + pt1normalized[1] * 13], + // pt2: [pt2[0] + pt2normalized[0] * 13, pt2[1] + pt2normalized[1] * 13], }; } @@ -294,6 +300,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo className="collectionfreeformlinkview-linkLine" style={{ pointerEvents: 'visibleStroke', opacity: this._opacity, stroke, strokeWidth }} onClick={this.onClickLine} + // d={`M ${pt1[0]} ${pt1[1]} L ${pt2[0]} ${pt2[1]}`} d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} markerEnd={link.link_displayArrow ? `url(#${link[Id] + 'arrowhead'})` : ''} /> diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx index ab7e3dfef..5e7b4fdca 100644 --- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx +++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx @@ -1,23 +1,25 @@ +import './GenerativeFill.scss'; +import React = require('react'); import { useEffect, useRef, useState } from 'react'; import { APISuccess, ImageUtility } from './generativeFillUtils/ImageHandler'; import { BrushHandler } from './generativeFillUtils/BrushHandler'; import { IconButton, TextField } from '@mui/material'; import { CursorData, Point } from './generativeFillUtils/generativeFillInterfaces'; -import { activeColor, canvasSize, eraserColor, freeformRenderSize } from './generativeFillUtils/generativeFillConstants'; +import { activeColor, canvasSize, eraserColor, freeformRenderSize, offsetDistanceY, offsetX } from './generativeFillUtils/generativeFillConstants'; import { PointerHandler } from './generativeFillUtils/PointerHandler'; import { BsBrush, BsEraser, BsX } from 'react-icons/bs'; import { AiOutlineUpload } from 'react-icons/ai'; import { CiUndo, CiRedo } from 'react-icons/ci'; import Buttons from './GenerativeFillButtons'; -import React = require('react'); -import './GenerativeFill.scss'; import { EditableText } from 'browndash-components'; import { MainView } from '../../MainView'; import { Doc } from '../../../../fields/Doc'; import { Networking } from '../../../Network'; import { Utils } from '../../../../Utils'; import { DocUtils, Docs } from '../../../documents/Documents'; -import { NumCast } from '../../../../fields/Types'; +import { DocCast, NumCast } from '../../../../fields/Types'; +import { CollectionDockingView } from '../../collections/CollectionDockingView'; +import { OpenWhere, OpenWhereMod } from '../DocumentView'; /** * For images not 1024x1024 fill in the rest in solid black, or a @@ -63,16 +65,23 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const [brushStyle, setBrushStyle] = useState<BrushStyle>(BrushStyle.ADD); const [input, setInput] = useState(''); const [loading, setLoading] = useState(false); - // used to store the current image loaded to the main canvas + // the current image in the main canvas const currImg = useRef<HTMLImageElement | null>(null); + // the unedited version of each generation (parent) const originalImg = useRef<HTMLImageElement | null>(null); // stores history of data urls const undoStack = useRef<string[]>([]); // stores redo stack const redoStack = useRef<string[]>([]); - // will change later, for now, stores an array [<col (generation)>, <row (edit in generation)>] + + // early stage properly, likely will get rid of const freeformPosition = useRef<number[]>([0, 0]); + // references to keep track of tree structure + const newCollectionRef = useRef<Doc | null>(null); + const parentDoc = useRef<Doc | null>(null); + const childrenDocs = useRef<Doc[]>([]); + // Undo and Redo const handleUndo = () => { const ctx = ImageUtility.getCanvasContext(canvasRef); @@ -165,6 +174,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD ImageUtility.drawImgToCanvas(img, canvasRef); currImg.current = img; originalImg.current = img; + freeformPosition.current = [0, 0]; }, [canvasRef, imageEditorSource]); // handles brush sizing @@ -237,9 +247,8 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const maskBlob = await ImageUtility.canvasToBlob(canvas); const imgBlob = await ImageUtility.canvasToBlob(ImageUtility.getCanvasImg(img)); - // const res = await ImageUtility.getEdit(imgBlob, maskBlob, input !== '' ? input + ' in the same style' : 'Fill in the image in the same style', 2); - - const res = await ImageUtility.mockGetEdit(img.src); + const res = await ImageUtility.getEdit(imgBlob, maskBlob, input !== '' ? input + ' in the same style' : 'Fill in the image in the same style', 2); + // const res = await ImageUtility.mockGetEdit(img.src); const { urls } = res as APISuccess; const image = new Image(); image.src = urls[0]; @@ -247,32 +256,73 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD setEdits(urls); ImageUtility.drawImgToCanvas(image, canvasRef); currImg.current = image; + freeformPosition.current[0] += 1; + freeformPosition.current[1] = 0; } catch (err) { console.log(err); } }; + // adjusts all the img positions to be aligned + const adjustImgPositions = () => { + if (!parentDoc.current) return; + const startY = NumCast(parentDoc.current.y); + const len = childrenDocs.current.length; + let initialYPositions: number[] = []; + for (let i = 0; i < len; i++) { + initialYPositions.push(startY + i * offsetDistanceY); + } + childrenDocs.current.forEach((doc, i) => { + if (len % 2 === 1) { + doc.y = initialYPositions[i] - Math.floor(len / 2) * offsetDistanceY; + } else { + doc.y = initialYPositions[i] - (len / 2 - 1 / 2) * offsetDistanceY; + } + }); + }; + + // creates a new image document and returns its reference + const createNewImgDoc = async (img: HTMLImageElement, firstDoc: boolean): Promise<Doc | undefined> => { + if (!newCollectionRef.current || !imageRootDoc || !parentDoc.current) return; + const src = img.src; + const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [src] }); + const source = Utils.prepend(result.accessPaths.agnostic.client); + // the y position is dummy + const x = firstDoc ? 0 : NumCast(parentDoc.current.x) + freeformRenderSize + offsetX; + const initialY = firstDoc ? 500 : 0; + + const newImg = Docs.Create.ImageDocument(source, { + x: x, + y: initialY, + _height: freeformRenderSize, + _width: freeformRenderSize, + data_nativeWidth: result.nativeWidth, + data_nativeHeight: result.nativeHeight, + }); + + childrenDocs.current.push(newImg); + adjustImgPositions(); + Doc.AddDocToList(newCollectionRef.current, undefined, newImg); + DocUtils.MakeLink(parentDoc.current, newImg, { link_relationship: 'Image Edit' }); + return newImg; + }; + const onSave = async () => { - if (!currImg.current || !imageRootDoc) return; + if (!currImg.current || !originalImg.current || !imageRootDoc) return; try { - const src = currImg.current.src; - console.log(src); - const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [src] }); - const source = Utils.prepend(result.accessPaths.agnostic.client); - console.log(source); - const newImg = Docs.Create.ImageDocument(source, { - x: NumCast(imageRootDoc.x) + NumCast(imageRootDoc._width) + 20, - y: NumCast(imageRootDoc.y), - _height: freeformRenderSize, - _width: freeformRenderSize, - data_nativeWidth: result.nativeWidth, - data_nativeHeight: result.nativeHeight, - }); - - addDoc?.(newImg); + if (!newCollectionRef.current) { + // create new collection and add it to the view + newCollectionRef.current = Docs.Create.FreeformDocument([], { x: NumCast(imageRootDoc.x) + NumCast(imageRootDoc._width) + 20, y: NumCast(imageRootDoc.y), _width: 1000, _height: 1000 }); + addDoc?.(newCollectionRef.current); + const originalSrc = originalImg.current.src; + await createNewImgDoc(originalImg.current, true); + } + CollectionDockingView.AddSplit(Doc.MakeCopy(DocCast(Doc.UserDoc().emptyPane)), OpenWhereMod.right); + // CollectionDockingView.AddSplit(newCollection,OpenWhere.inParent) + // mindmapping + // this.props.addDocTab(); + // Create link between prompt and image - DocUtils.MakeLink(imageRootDoc, newImg, { link_relationship: 'Image Edit' }); - console.log('done'); } catch (err) { console.log(err); } @@ -361,9 +411,9 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD </div> {/* Edits box */} <div className="editsBox"> - {edits.map(edit => ( + {edits.map((edit, i) => ( <img - key={edit} + key={i} width={100} height={100} src={edit} diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/generativeFillConstants.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/generativeFillConstants.ts index fe668ef6f..5fd0e9419 100644 --- a/src/client/views/nodes/generativeFill/generativeFillUtils/generativeFillConstants.ts +++ b/src/client/views/nodes/generativeFill/generativeFillUtils/generativeFillConstants.ts @@ -1,6 +1,8 @@ // constants export const canvasSize = 1024; -export const freeformRenderSize = 200; +export const freeformRenderSize = 300; +export const offsetDistanceY = freeformRenderSize + 100; +export const offsetX = 100; export const activeColor = '#1976d2'; export const eraserColor = '#e1e9ec'; |