Skip to content

Commit 9eca500

Browse files
authored
fix: Cursor disappearing when multiple tools active (#2493)
* fix: Cursor disappearing * fix: Tool cursor disappearing * Fix npe on dynamic threshold * Use non-calibrated image for starting point * Change to isPrimary * docs: Cursor drawing
1 parent 8fe7f5e commit 9eca500

4 files changed

Lines changed: 43 additions & 8 deletions

File tree

packages/tools/examples/labelmapSegmentationTools/index.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
addDropdownToToolbar,
1515
addSliderToToolbar,
1616
setCtTransferFunctionForVolumeActor,
17-
getLocalUrl,
1817
} from '../../../../utils/demo/helpers';
1918
import * as cornerstoneTools from '@cornerstonejs/tools';
2019

@@ -307,17 +306,17 @@ async function run() {
307306
}
308307
);
309308
toolGroup.addToolInstance(
310-
brushInstanceNames.CircularEraser,
309+
brushInstanceNames.SphereBrush,
311310
BrushTool.toolName,
312311
{
313-
activeStrategy: brushStrategies.CircularEraser,
312+
activeStrategy: brushStrategies.SphereBrush,
314313
}
315314
);
316315
toolGroup.addToolInstance(
317-
brushInstanceNames.SphereBrush,
316+
brushInstanceNames.CircularEraser,
318317
BrushTool.toolName,
319318
{
320-
activeStrategy: brushStrategies.SphereBrush,
319+
activeStrategy: brushStrategies.CircularEraser,
321320
}
322321
);
323322
toolGroup.addToolInstance(
@@ -352,10 +351,19 @@ async function run() {
352351
bindings: [{ mouseButton: MouseBindings.Primary }],
353352
});
354353

354+
toolGroup.setToolActive(brushInstanceNames.CircularEraser, {
355+
bindings: [
356+
{
357+
mouseButton: MouseBindings.Primary,
358+
modifierKey: KeyboardBindings.Shift,
359+
},
360+
],
361+
});
362+
355363
toolGroup.setToolActive(ZoomTool.toolName, {
356364
bindings: [
357365
{
358-
mouseButton: MouseBindings.Primary, // Shift Left Click
366+
mouseButton: MouseBindings.Auxiliary, // Shift Middle
359367
modifierKey: KeyboardBindings.Shift,
360368
},
361369
],

packages/tools/src/store/ToolGroupManager/ToolGroup.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,11 @@ export default class ToolGroup {
404404
const cursor = MouseCursor.getDefinedCursor('default');
405405
this._setCursorForViewports(cursor);
406406
}
407+
toolInstance.isPrimary = false;
407408
} else {
408409
// reset the mouse cursor if tool has left click binding
409410
this.setViewportsCursorByToolName(toolName);
411+
toolInstance.isPrimary = true;
410412
}
411413

412414
// if it is a primary tool binding, we should store it as the previous primary tool
@@ -496,6 +498,7 @@ export default class ToolGroup {
496498

497499
this.toolOptions[toolName] = toolOptions;
498500
toolInstance.mode = mode;
501+
toolInstance.isPrimary = false;
499502

500503
if (typeof toolInstance.onSetToolPassive === 'function') {
501504
toolInstance.onSetToolPassive();

packages/tools/src/tools/base/BaseTool.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ const { DefaultHistoryMemo } = csUtils.HistoryMemo;
1313
*/
1414
abstract class BaseTool {
1515
static toolName;
16+
17+
/**
18+
* Set to the tool that is currently drawing the active cursor. This
19+
* will be either primary mouse button tool if no tool is currently
20+
* being directly interacted with, OR the tool that is directly interacted
21+
* with. This logic ensures that there is only a single tool at a time
22+
* drawing, which prevents tools not getting mouse updates from over-writing
23+
* the cursor.
24+
*
25+
* - If the tool bound to the primary button is a cursor drawing tool,
26+
* use that tool and there is NOT a tool currently drawing directly
27+
* - If there is a tool currently drawing directly, then that tool should
28+
* display a cursor EVEN if it normally doesn't have a custom cursor
29+
* - When a tool finishes drawing direct, it should stop being the active
30+
* cursor tool unless it is also the primary tool
31+
*/
32+
public static activeCursorTool;
33+
1634
/** Supported Interaction Types - currently only Mouse */
1735
public supportedInteractionTypes: InteractionTypes[];
1836
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -21,6 +39,9 @@ abstract class BaseTool {
2139
public toolGroupId: string;
2240
/** Tool Mode - Active/Passive/Enabled/Disabled/ */
2341
public mode: ToolModes;
42+
/** Primary tool - this is set to true when this tool is primary */
43+
public isPrimary = false;
44+
2445
/**
2546
* A memo recording the starting state of a tool. This will be updated
2647
* as changes are made, and reflects the fact that a memo has been created.

packages/tools/src/tools/segmentation/BrushTool.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
fillInsideCircle,
2323
} from './strategies/fillCircle';
2424
import { eraseInsideCircle } from './strategies/eraseCircle';
25-
import { drawCircle as drawCircleSvg } from '../../drawingSvg';
2625
import {
2726
resetElementCursor,
2827
hideElementCursor,
@@ -249,6 +248,9 @@ class BrushTool extends LabelmapBaseTool {
249248
* The preview also needs to be cancelled on changing tools.
250249
*/
251250
mouseMoveCallback = (evt: EventTypes.InteractionEventType): void => {
251+
if (!this.isPrimary) {
252+
return;
253+
}
252254
if (this.mode === ToolModes.Active) {
253255
this.updateCursor(evt);
254256
if (!this.configuration.preview.enabled) {
@@ -355,6 +357,7 @@ class BrushTool extends LabelmapBaseTool {
355357
return;
356358
}
357359

360+
BrushTool.activeCursorTool = this;
358361
triggerAnnotationRenderForViewportUIDs(this._hoverData.viewportIdsToRender);
359362
}
360363

@@ -619,7 +622,7 @@ class BrushTool extends LabelmapBaseTool {
619622
enabledElement: Types.IEnabledElement,
620623
svgDrawingHelper: SVGDrawingHelper
621624
): void {
622-
if (!this._hoverData) {
625+
if (!this._hoverData || BrushTool.activeCursorTool !== this) {
623626
return;
624627
}
625628

0 commit comments

Comments
 (0)