diff --git a/editor/src/components/canvas/canvas-strategies/strategies/grid-draw-to-insert-strategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/grid-draw-to-insert-strategy.tsx index a4fdd42e61e6..7e4fac06a0b5 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/grid-draw-to-insert-strategy.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/grid-draw-to-insert-strategy.tsx @@ -1,31 +1,27 @@ import type { ElementPath } from 'utopia-shared/src/types' import { MetadataUtils } from '../../../../core/model/element-metadata-utils' +import { stripNulls } from '../../../../core/shared/array-utils' import * as EP from '../../../../core/shared/element-path' -import type { - CanvasPoint, - CanvasRectangle, - Size, - WindowRectangle, -} from '../../../../core/shared/math-utils' +import type { CanvasPoint, CanvasRectangle, Size } from '../../../../core/shared/math-utils' import { canvasPoint, canvasRectangle, - canvasVector, - offsetPoint, + pointDifference, roundRectangleToNearestWhole, - scaleVector, size, - windowPoint, } from '../../../../core/shared/math-utils' +import * as PP from '../../../../core/shared/property-path' import { assertNever } from '../../../../core/shared/utils' import { EditorModes, type InsertionSubject } from '../../../editor/editor-modes' import { childInsertionPath } from '../../../editor/store/insertion-path' +import { deleteProperties } from '../../commands/delete-properties-command' import type { InsertElementInsertionSubject } from '../../commands/insert-element-insertion-subject' import { insertElementInsertionSubject } from '../../commands/insert-element-insertion-subject' +import { showGridControls } from '../../commands/show-grid-controls-command' import { updateHighlightedViews } from '../../commands/update-highlighted-views-command' import { wildcardPatch } from '../../commands/wildcard-patch-command' import { controlsForGridPlaceholders } from '../../controls/grid-controls' -import { canvasPointToWindowPoint } from '../../dom-lookup' +import { canvasPointToWindowPoint, windowToCanvasCoordinates } from '../../dom-lookup' import { getWrapperWithGeneratedUid, getWrappingCommands, @@ -50,11 +46,6 @@ import { import { getTargetCell, setGridPropsCommands } from './grid-helpers' import { newReparentSubjects } from './reparent-helpers/reparent-strategy-helpers' import { getReparentTargetUnified } from './reparent-helpers/reparent-strategy-parent-lookup' -import { stripNulls } from '../../../../core/shared/array-utils' -import { showGridControls } from '../../commands/show-grid-controls-command' -import * as PP from '../../../../core/shared/property-path' -import { propertyToDelete, updateBulkProperties } from '../../commands/set-property-command' -import { deleteProperties } from '../../commands/delete-properties-command' export const gridDrawToInsertText: CanvasStrategyFactory = ( canvasState: InteractionCanvasState, @@ -193,7 +184,11 @@ const gridDrawToInsertStrategyInner = const { gridCellCoordinates, cellWindowRectangle } = newTargetCell - const offset = getOffsetFromGridCell(interactionData, canvasState, cellWindowRectangle) + const cellCanvasOrigin = windowToCanvasCoordinates( + canvasState.scale, + canvasState.canvasOffset, + cellWindowRectangle, + ).canvasPositionRounded const defaultSize = interactionData.type === 'DRAG' && @@ -205,7 +200,7 @@ const gridDrawToInsertStrategyInner = const insertionCommand = getInsertionCommand( targetParent, insertionSubject, - getFrameForInsertion(interactionData, defaultSize, offset), + getFrameForInsertion(interactionData, defaultSize, cellCanvasOrigin), ) const gridTemplate = parent.specialSizeMeasurements.containerGridProperties @@ -245,6 +240,9 @@ const gridDrawToInsertStrategyInner = gridColumnStart: { numericalPosition: gridCellCoordinates.column }, gridRowEnd: { numericalPosition: gridCellCoordinates.row + 1 }, gridColumnEnd: { numericalPosition: gridCellCoordinates.column + 1 }, + // TODO! this is currently going to assign the element to the cell the interaction started in, + // however it would be good to instead assign the element to _all_ cells overlapping with the final + // inserted frame. }), ...wrappingCommands, ...stripNulls([ @@ -279,17 +277,22 @@ const gridDrawToInsertStrategyInner = function getFrameForInsertion( interactionData: DragInteractionData | HoverInteractionData, defaultSize: Size, - offset: CanvasPoint, + cellOrigin: CanvasPoint, ): CanvasRectangle { if (interactionData.type === 'DRAG') { - const origin = interactionData.drag ?? { x: defaultSize.width / 2, y: defaultSize.height / 2 } - - const { x, y } = { x: offset.x - origin.x, y: offset.y - origin.y } + const dragStart = interactionData.dragStart + const mouseAt = { + x: interactionData.dragStart.x + (interactionData.drag?.x ?? 0), + y: interactionData.dragStart.y + (interactionData.drag?.y ?? 0), + } + const width = Math.abs(interactionData.drag?.x ?? defaultSize.width) + const height = Math.abs(interactionData.drag?.y ?? defaultSize.height) - const { width, height } = - interactionData.drag == null - ? defaultSize - : { width: interactionData.drag.x, height: interactionData.drag.y } + const origin = canvasPoint({ + x: Math.min(dragStart.x, mouseAt.x), + y: Math.min(dragStart.y, mouseAt.y), + }) + const { x, y } = pointDifference(cellOrigin, origin) return roundRectangleToNearestWhole(canvasRectangle({ x, y, width, height })) } @@ -347,30 +350,3 @@ function getGridCellUnderCursor( mouseWindowPoint, ) } - -function getOffsetFromGridCell( - interactionData: DragInteractionData | HoverInteractionData, - canvasState: InteractionCanvasState, - cellWindowRectangle: WindowRectangle, -) { - const windowPointToUse = - interactionData.type === 'DRAG' - ? offsetPoint(interactionData.dragStart, interactionData.drag ?? canvasVector({ x: 0, y: 0 })) - : interactionData.point - - const mouseWindowPoint = canvasPointToWindowPoint( - windowPointToUse, - canvasState.scale, - canvasState.canvasOffset, - ) - - const { x, y } = scaleVector( - windowPoint({ - x: mouseWindowPoint.x - cellWindowRectangle.x, - y: mouseWindowPoint.y - cellWindowRectangle.y, - }), - 1 / canvasState.scale, - ) - - return canvasPoint({ x, y }) -}