|
@@ -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
|