Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions src/components/EditorCanvas/Canvas.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ export default function Canvas() {
ctrlKey: false,
metaKey: false,
});
// this is used to store the element that is clicked on
// at the moment, and shouldn't be a part of the state

let elementPointerDown = null;

const isSameElement = (el1, el2) => {
Expand All @@ -112,9 +111,7 @@ export default function Canvas() {
const rect = getRectFromEndpoints(bulkSelectRect);
const elements = [];
const shouldAddElement = (elementRect, element) => {
// if ctrl key is pressed, only add the elements that are not already selected
// can theoretically be optimized later if the selected elements is
// a map from id to element (after the ids are made unique)

return (
isInsideRect(elementRect, rect) &&
((!bulkSelectRect.ctrlKey && !bulkSelectRect.metaKey) ||
Expand Down Expand Up @@ -215,8 +212,7 @@ export default function Canvas() {
show: false,
}));

// this is the object that will be added to the bulk selected elements
// if necessary

const elementInBulk = {
id: element.id,
type,
Expand Down Expand Up @@ -273,9 +269,7 @@ export default function Canvas() {
return { x, y };
};

/**
* @param {PointerEvent} e
*/

const handlePointerMove = (e) => {
if (selectedElement.open && !layout.sidebar) return;

Expand All @@ -296,6 +290,11 @@ export default function Canvas() {
return;
}

const isDragMode = settings.canvasMode === "drag";
if (isDragMode) {
return;
}

if (layout.readOnly) return;

if (linking) {
Expand Down Expand Up @@ -406,13 +405,9 @@ export default function Canvas() {
}
};

/**
* @param {PointerEvent} e
*/
const handlePointerDown = (e) => {
if (!e.isPrimary) return;

// don't pan if the sidesheet for editing a table is open
if (
selectedElement.element === ObjectType.TABLE &&
selectedElement.open &&
Expand All @@ -422,8 +417,20 @@ export default function Canvas() {

const isMouseLeftButton = e.button === 0;
const isMouseMiddleButton = e.button === 1;
const isDragMode = settings.canvasMode === "drag";

if (isMouseLeftButton) {
if (isMouseLeftButton && isDragMode) {
setPanning({
isPanning: true,
panStart: transform.pan,

cursorStart: pointer.spaces.screen,
});
pointer.setStyle("grabbing");
return;
}

if (isMouseLeftButton && !isDragMode) {
setBulkSelectRect({
x1: pointer.spaces.diagram.x,
y1: pointer.spaces.diagram.y,
Expand All @@ -441,8 +448,6 @@ export default function Canvas() {
setPanning({
isPanning: true,
panStart: transform.pan,
// Diagram space depends on the current panning.
// Use screen space to avoid circular dependencies and undefined behavior.
cursorStart: pointer.spaces.screen,
});
pointer.setStyle("grabbing");
Expand All @@ -455,7 +460,6 @@ export default function Canvas() {

const didDrag = () => {
if (!isDragging()) return false;
// checking any element is sufficient
const { currentCoords, initialCoords } = bulkSelectedElements[0];
return (
currentCoords.x !== initialCoords.x || currentCoords.y !== initialCoords.y
Expand All @@ -476,10 +480,6 @@ export default function Canvas() {
transform.pan.x === panning.panStart.x &&
transform.pan.y === panning.panStart.y
);

/**
* @param {PointerEvent} e
*/
const handlePointerUp = (e) => {
if (selectedElement.open && !layout.sidebar) return;

Expand Down Expand Up @@ -526,7 +526,7 @@ export default function Canvas() {
setSaveState(State.SAVING);
}
setPanning((old) => ({ ...old, isPanning: false }));
pointer.setStyle("default");
pointer.setStyle(settings.canvasMode === "drag" ? "grab" : "default");

if (linking) handleLinking();
setLinking(false);
Expand Down Expand Up @@ -638,8 +638,7 @@ export default function Canvas() {
e.preventDefault();

if (e.ctrlKey || e.metaKey) {
// How "eager" the viewport is to
// center the cursor's coordinates

const eagernessFactor = 0.05;
setTransform((prev) => ({
pan: {
Expand Down Expand Up @@ -683,7 +682,12 @@ export default function Canvas() {
<div
className="w-full h-full"
style={{
cursor: pointer.style,
cursor:
panning.isPanning
? "grabbing"
: settings.canvasMode === "drag"
? "grab"
: pointer.style,
backgroundColor: settings.mode === "dark" ? darkBgTheme : "white",
}}
>
Expand Down
32 changes: 29 additions & 3 deletions src/components/EditorHeader/ControlPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,6 @@ export default function ControlPanel({

const scaleX = canvas.width / width;
const scaleY = canvas.height / height;
// Making sure the scale is a multiple of 0.05
const scale = Math.floor(Math.min(scaleX, scaleY) * 20) / 20;

const centerX = (minMaxXY.minX + minMaxXY.maxX) / 2;
Expand Down Expand Up @@ -1742,6 +1741,34 @@ export default function ControlPanel({
</button>
</Tooltip>
<Divider layout="vertical" margin="8px" />
<Tooltip
content={settings.canvasMode === "drag" ? "Drag Mode" : "Select Mode"}
position="bottom"
>
<button
className={`py-1 px-2 hover-2 rounded-sm flex items-center ${
settings.canvasMode === "drag" ? "bg-blue-500/20" : ""
}`}
onClick={() =>
setSettings((prev) => ({
...prev,
canvasMode: prev.canvasMode === "drag" ? "select" : "drag",
}))
}
title={
settings.canvasMode === "drag"
? "Switch to Select Mode"
: "Switch to Drag Mode"
}
>
{settings.canvasMode === "drag" ? (
<i className="fa-solid fa-hand" style={{ color: "#3b82f6" }} />
) : (
<i className="fa-solid fa-mouse-pointer" />
)}
</button>
</Tooltip>
<Divider layout="vertical" margin="8px" />
<Tooltip content={t("undo")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded-sm flex items-center disabled:opacity-50"
Expand Down Expand Up @@ -1896,8 +1923,7 @@ export default function ControlPanel({
onPointerEnter={(e) => e.isPrimary && setShowEditName(true)}
onPointerLeave={(e) => e.isPrimary && setShowEditName(false)}
onPointerDown={(e) => {
// Required for onPointerLeave to trigger when a touch pointer leaves
// https://stackoverflow.com/a/70976017/1137077

e.target.releasePointerCapture(e.pointerId);
}}
onClick={!layout.readOnly && (() => setModal(MODAL.RENAME))}
Expand Down
1 change: 1 addition & 0 deletions src/context/SettingsContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const defaultSettings = {
showRelationshipLabels: true,
tableWidth: tableWidth,
showDebugCoordinates: false,
canvasMode: "select",
};

export const SettingsContext = createContext(defaultSettings);
Expand Down