@ -259,6 +259,7 @@ export type PointerDownState = Readonly<{
hasBeenDuplicated : boolean ;
hasHitCommonBoundingBoxOfSelectedElements : boolean ;
} ;
withCmdOrCtrl : boolean ;
drag : {
// Might change during the pointer interation
hasOccurred : boolean ;
@ -2260,11 +2261,13 @@ class App extends React.Component<AppProps, AppState> {
} else if ( isOverScrollBar ) {
setCursor ( this . canvas , CURSOR_TYPE . AUTO ) ;
} else if (
hitElement ||
this . isHittingCommonBoundingBoxOfSelectedElements (
scenePointer ,
selectedElements ,
)
// if using cmd/ctrl, we're not dragging
! event [ KEYS . CTRL_OR_CMD ] &&
( hitElement ||
this . isHittingCommonBoundingBoxOfSelectedElements (
scenePointer ,
selectedElements ,
) )
) {
setCursor ( this . canvas , CURSOR_TYPE . MOVE ) ;
} else {
@ -2542,6 +2545,7 @@ class App extends React.Component<AppProps, AppState> {
return {
origin ,
withCmdOrCtrl : event [ KEYS . CTRL_OR_CMD ] ,
originInGrid : tupleToCoors (
getGridPoint ( origin . x , origin . y , this . state . gridSize ) ,
) ,
@ -2746,6 +2750,9 @@ class App extends React.Component<AppProps, AppState> {
if ( hitElement != null ) {
// on CMD/CTRL, drill down to hit element regardless of groups etc.
if ( event [ KEYS . CTRL_OR_CMD ] ) {
if ( ! this . state . selectedElementIds [ hitElement . id ] ) {
pointerDownState . hit . wasAddedToSelection = true ;
}
this . setState ( ( prevState ) = > ( {
. . . editGroupForSelectedElement ( prevState , hitElement ) ,
previousSelectedElementIds : this.state.selectedElementIds ,
@ -3184,7 +3191,9 @@ class App extends React.Component<AppProps, AppState> {
this . scene . getElements ( ) ,
this . state ,
) ;
if ( selectedElements . length > 0 ) {
// prevent dragging even if we're no longer holding cmd/ctrl otherwise
// it would have weird results (stuff jumping all over the screen)
if ( selectedElements . length > 0 && ! pointerDownState . withCmdOrCtrl ) {
const [ dragX , dragY ] = getGridPoint (
pointerCoords . x - pointerDownState . drag . offset . x ,
pointerCoords . y - pointerDownState . drag . offset . y ,
@ -3326,11 +3335,25 @@ class App extends React.Component<AppProps, AppState> {
if ( this . state . elementType === "selection" ) {
const elements = this . scene . getElements ( ) ;
if ( ! event . shiftKey && isSomeElementSelected ( elements , this . state ) ) {
this . setState ( {
selectedElementIds : { } ,
selectedGroupIds : { } ,
editingGroupId : null ,
} ) ;
if ( pointerDownState . withCmdOrCtrl && pointerDownState . hit . element ) {
this . setState ( ( prevState ) = >
selectGroupsForSelectedElements (
{
. . . prevState ,
selectedElementIds : {
[ pointerDownState . hit . element ! . id ] : true ,
} ,
} ,
this . scene . getElements ( ) ,
) ,
) ;
} else {
this . setState ( {
selectedElementIds : { } ,
selectedGroupIds : { } ,
editingGroupId : null ,
} ) ;
}
}
const elementsWithinSelection = getElementsWithinSelection (
elements ,
@ -3346,6 +3369,14 @@ class App extends React.Component<AppProps, AppState> {
map [ element . id ] = true ;
return map ;
} , { } as any ) ,
. . . ( pointerDownState . hit . element
? {
// if using ctrl/cmd, select the hitElement only if we
// haven't box-selected anything else
[ pointerDownState . hit . element
. id ] : ! elementsWithinSelection . length ,
}
: null ) ,
} ,
} ,
this . scene . getElements ( ) ,
@ -3610,12 +3641,18 @@ class App extends React.Component<AppProps, AppState> {
} else {
// remove element from selection while
// keeping prev elements selected
this . setState ( ( prevState ) = > ( {
selectedElementIds : {
. . . prevState . selectedElementIds ,
[ hitElement ! . id ] : false ,
} ,
} ) ) ;
this . setState ( ( prevState ) = >
selectGroupsForSelectedElements (
{
. . . prevState ,
selectedElementIds : {
. . . prevState . selectedElementIds ,
[ hitElement ! . id ] : false ,
} ,
} ,
this . scene . getElements ( ) ,
) ,
) ;
}
} else {
// add element to selection while