fix: returns only first item after a click on a tile (for efficiency)

This commit is contained in:
Mark Mankarious
2023-08-17 19:31:46 +01:00
parent 7275dd3a23
commit b220c25fe0
9 changed files with 89 additions and 92 deletions

View File

@@ -87,7 +87,7 @@ export const ToolMenu = () => {
uiStateStoreActions.setMode({
type: 'CURSOR',
showCursor: true,
mousedown: null
mousedownItem: null
});
}}
size={theme.customVars.toolMenu.height}

View File

@@ -58,7 +58,7 @@ export const AreaTool: ModeActions = {
uiState.actions.setMode({
type: 'CURSOR',
showCursor: true,
mousedown: null
mousedownItem: null
});
}
};

View File

@@ -1,7 +1,7 @@
import { produce } from 'immer';
import {
generateId,
filterNodesByTile,
getItemAtTile,
connectorInputToConnector,
connectorToConnectorInput,
getConnectorPath,
@@ -28,20 +28,18 @@ export const Connector: ModeActions = {
// TODO: Items at tile should take the entire scene in and return just the first item of interest
// for efficiency
const itemsAtTile = filterNodesByTile({
const itemAtTile = getItemAtTile({
tile: uiState.mouse.position.tile,
nodes: scene.nodes
scene
});
if (itemsAtTile.length > 0) {
const node = itemsAtTile[0];
if (itemAtTile && itemAtTile.type === 'NODE') {
const newMode = produce(uiState.mode, (draftState) => {
if (!draftState.connector) return;
draftState.connector.anchors[1] = {
type: 'NODE',
id: node.id
id: itemAtTile.id
};
draftState.connector.path = getConnectorPath({
@@ -72,19 +70,17 @@ export const Connector: ModeActions = {
mousedown: ({ uiState, scene }) => {
if (uiState.mode.type !== 'CONNECTOR') return;
const itemsAtTile = filterNodesByTile({
const itemAtTile = getItemAtTile({
tile: uiState.mouse.position.tile,
nodes: scene.nodes
scene
});
if (itemsAtTile.length > 0) {
const node = itemsAtTile[0];
if (itemAtTile && itemAtTile.type === 'NODE') {
const newMode = produce(uiState.mode, (draftState) => {
draftState.connector = connectorInputToConnector(
{
id: generateId(),
anchors: [{ nodeId: node.id }, { nodeId: node.id }]
anchors: [{ nodeId: itemAtTile.id }, { nodeId: itemAtTile.id }]
},
scene.nodes
);
@@ -120,7 +116,7 @@ export const Connector: ModeActions = {
uiState.actions.setMode({
type: 'CURSOR',
showCursor: true,
mousedown: null
mousedownItem: null
});
}
};

View File

@@ -1,22 +1,19 @@
import { produce } from 'immer';
import { ItemControlsTypeEnum, ModeActions } from 'src/types';
import { filterNodesByTile, getItemById, hasMovedTile } from 'src/utils';
import { getItemAtTile, getItemById, hasMovedTile } from 'src/utils';
export const Cursor: ModeActions = {
type: 'CURSOR',
mousemove: ({ uiState }) => {
if (uiState.mode.type !== 'CURSOR' || !hasMovedTile(uiState.mouse)) return;
if (uiState.mode.mousedown) {
// User is in mousedown mode
if (uiState.mode.mousedown.items.length > 0) {
// User's last mousedown action was on a node
uiState.actions.setMode({
type: 'DRAG_ITEMS',
showCursor: true,
items: uiState.mode.mousedown.items
});
}
if (uiState.mode.mousedownItem) {
// User is in dragging mode
uiState.actions.setMode({
type: 'DRAG_ITEMS',
showCursor: true,
items: [uiState.mode.mousedownItem]
});
// draftState.mode = {
// type: 'LASSO',
@@ -33,16 +30,13 @@ export const Cursor: ModeActions = {
mousedown: ({ uiState, scene, isRendererInteraction }) => {
if (uiState.mode.type !== 'CURSOR' || !isRendererInteraction) return;
const itemsAtTile = filterNodesByTile({
const itemAtTile = getItemAtTile({
tile: uiState.mouse.position.tile,
nodes: scene.nodes
scene
});
const newMode = produce(uiState.mode, (draftState) => {
draftState.mousedown = {
items: itemsAtTile,
tile: uiState.mouse.position.tile
};
draftState.mousedownItem = itemAtTile;
});
uiState.actions.setMode(newMode);
@@ -50,40 +44,34 @@ export const Cursor: ModeActions = {
mouseup: ({ uiState, scene }) => {
if (uiState.mode.type !== 'CURSOR') return;
scene.nodes.forEach((node) => {
if (node.isSelected)
scene.actions.updateNode(node.id, { isSelected: false });
});
if (
uiState.mode.mousedownItem &&
uiState.mode.mousedownItem.type === 'NODE'
) {
const { item: node } = getItemById(
scene.nodes,
uiState.mode.mousedownItem.id
);
if (uiState.mode.mousedown !== null) {
// User's last mousedown action was on a scene item
const mousedownNode = uiState.mode.mousedown.items[0];
if (mousedownNode) {
// The user's last mousedown action was on a node
const { item: node } = getItemById(scene.nodes, mousedownNode.id);
uiState.actions.setContextMenu(node);
// state.sceneActions.updateNode(node.id, { isSelected: true });
uiState.actions.setItemControls({
type: ItemControlsTypeEnum.SINGLE_NODE,
nodeId: node.id
});
} else {
// Empty tile selected
uiState.actions.setContextMenu({
type: 'EMPTY_TILE',
position: uiState.mouse.position.tile
});
uiState.actions.setItemControls(null);
}
const newMode = produce(uiState.mode, (draftState) => {
draftState.mousedown = null;
uiState.actions.setContextMenu(node);
uiState.actions.setItemControls({
type: ItemControlsTypeEnum.SINGLE_NODE,
nodeId: node.id
});
} else {
// Empty tile selected
uiState.actions.setContextMenu({
type: 'EMPTY_TILE',
position: uiState.mouse.position.tile
});
uiState.actions.setMode(newMode);
uiState.actions.setItemControls(null);
}
const newMode = produce(uiState.mode, (draftState) => {
draftState.mousedownItem = null;
});
uiState.actions.setMode(newMode);
}
};

View File

@@ -9,10 +9,12 @@ export const DragItems: ModeActions = {
renderer.style.userSelect = 'none';
uiState.mode.items.forEach((node) => {
scene.actions.updateNode(node.id, {
position: uiState.mouse.position.tile
});
uiState.mode.items.forEach((item) => {
if (item.type === 'NODE') {
scene.actions.updateNode(item.id, {
position: uiState.mouse.position.tile
});
}
});
},
exit: ({ rendererRef }) => {
@@ -28,10 +30,12 @@ export const DragItems: ModeActions = {
return;
// User is dragging
uiState.mode.items.forEach((node) => {
scene.actions.updateNode(node.id, {
position: uiState.mouse.position.tile
});
uiState.mode.items.forEach((item) => {
if (item.type === 'NODE') {
scene.actions.updateNode(item.id, {
position: uiState.mouse.position.tile
});
}
});
uiState.actions.setContextMenu(null);
@@ -40,7 +44,7 @@ export const DragItems: ModeActions = {
uiState.actions.setMode({
type: 'CURSOR',
showCursor: true,
mousedown: null
mousedownItem: null
});
}
};

View File

@@ -1,6 +1,6 @@
import { produce } from 'immer';
import { ModeActions } from 'src/types';
import { filterNodesByTile, generateId } from 'src/utils';
import { getItemAtTile, generateId } from 'src/utils';
export const PlaceElement: ModeActions = {
type: 'PLACE_ELEMENT',
@@ -9,17 +9,14 @@ export const PlaceElement: ModeActions = {
if (uiState.mode.type !== 'PLACE_ELEMENT') return;
if (!uiState.mode.icon) {
const itemsAtTile = filterNodesByTile({
const itemAtTile = getItemAtTile({
tile: uiState.mouse.position.tile,
nodes: scene.nodes
scene
});
uiState.actions.setMode({
type: 'CURSOR',
mousedown: {
items: itemsAtTile,
tile: uiState.mouse.position.tile
},
mousedownItem: itemAtTile,
showCursor: true
});

View File

@@ -10,7 +10,7 @@ const initialState = () => {
mode: {
type: 'CURSOR',
showCursor: true,
mousedown: null
mousedownItem: null
},
mouse: {
position: { screen: CoordsUtils.zero(), tile: CoordsUtils.zero() },
@@ -64,7 +64,7 @@ const initialState = () => {
set({ mode: { type: 'INTERACTIONS_DISABLED', showCursor: false } });
} else {
set({
mode: { type: 'CURSOR', showCursor: true, mousedown: null }
mode: { type: 'CURSOR', showCursor: true, mousedownItem: null }
});
}
},

View File

@@ -45,10 +45,7 @@ export interface InteractionsDisabled {
export interface CursorMode {
type: 'CURSOR';
showCursor: boolean;
mousedown: {
items: SceneItem[];
tile: Coords;
} | null;
mousedownItem: SceneItem | null;
}
export interface PanMode {

View File

@@ -13,7 +13,9 @@ import {
Size,
Scroll,
Mouse,
ConnectorAnchor
ConnectorAnchor,
SceneItem,
Scene
} from 'src/types';
import {
CoordsUtils,
@@ -203,15 +205,28 @@ export const getTranslateCSS = (translate: Coords = { x: 0, y: 0 }) => {
return `translate(${translate.x}px, ${translate.y}px)`;
};
interface GetNodesByTile {
interface GetItemAtTile {
tile: Coords;
nodes: Node[];
scene: Scene;
}
export const filterNodesByTile = ({ tile, nodes }: GetNodesByTile): Node[] => {
return nodes.filter((node) => {
return CoordsUtils.isEqual(node.position, tile);
export const getItemAtTile = ({
tile,
scene
}: GetItemAtTile): SceneItem | null => {
const node = scene.nodes.find(({ position }) => {
return CoordsUtils.isEqual(position, tile);
});
if (node) return node;
const group = scene.groups.find(({ from, to }) => {
return isWithinBounds(tile, [from, to]);
});
if (group) return group;
return null;
};
export const incrementZoom = (zoom: number) => {