Changing the cursor for ToolManagers

I am trying to get the cursor to change depending on whether panning or DragSelection is active. However, I can’t get the cursor to change until the action is complete and mouseup. This can be seen as the default behaviour with panning, when the four direction cursor appears after the canvas has already been panned for a few seconds. I’ve tried achieving the same thing with the DragSelection. The cursor argument in box.go.Shape seems to be ignored completely. I’ve tried overriding both doActivate() and canStart(), but in both cases the cursor does the same as panning, and only appears after the DragSelection is complete.

    this.goDiagram.toolManager.dragSelectingTool.canStart = function() {
        console.log("HERE");
        const result = go.DragSelectingTool.prototype.canStart.call(this);
        if (result) {this.diagram.currentCursor = "crosshair";}
        return result
    }

or

    this.goDiagram.toolManager.dragSelectingTool.doActivate = function() {
        console.log("HERE");
        this.diagram.currentCursor = "crosshair";
        go.DragSelectingTool.prototype.doActivate.call(this);
    }

The canStart() behaviour is closest to what I want as HERE is logged on mousedown and the appropriate delay, showing that selection is available, whilst with doActivate() the HERE is only logged once I start dragging the selection. However, in both cases the cursor doesn’t change until mouseup.

How can I get the cursor to change before the action occurs?

Chrome, GoJS v.1.8.13, Windows 10

I just tried this:

    myDiagram.toolManager.dragSelectingTool.doActivate = function() {
      go.DragSelectingTool.prototype.doActivate.call(this);
      this.diagram.currentCursor = "crosshair";
    }

    myDiagram.toolManager.dragSelectingTool.doDeactivate = function() {
      go.DragSelectingTool.prototype.doDeactivate.call(this);
      this.diagram.currentCursor = "";
    }

Then when I use the DragSelectingTool the cursor does change to be a “crosshair” throughout the operation of that tool, in all browsers that I tried on Windows 10 (Firefox, Edge, IE11) except for Chrome. So that seems to be a bug in Chrome.

Thanks. Yes, it works much better on Firefox. However, the cursor still isn’t changing on mousedown, only when the mouse is moved, whether that be the default behaviour for panning or the altered behaviour for DragSelection (canStart or doActivate).
I’m finding that the doDeactivate() isn’t necessary as the cursor seems to be automatically reverted.

At the time of the mouse-down event, the DragSelectingTool cannot start, so it would be too soon to change the cursor.

That’s because the DragSelectingTool.canStart method can only return true after DragSelectingTool.delay milliseconds of the mouse/finger being stationary. That’s to distinguish it from a panning gesture, i.e. starting the PanningTool.

I know. What I’m after is for the panning cursor to come up on mousedown and then the crosshair cursor to appear after the time delay. Although the HERE log message appears once the delay has expired from within canStart() (see the code above), the cursor doesn’t change until I actually start moving the mouse (in Firefox). Similarly, the default panning tool only changed the cursor, in Firefox, once the panning operation is started, not on mouse down.

I am attempting to give the user feedback on which tool will be active when they start moving across the canvas, before they actually do the move, so that they can see visually when the ToolManager has switched from panning to drag selection and take the guesswork out of judging the whether the delay has passed.

Oh, now I understand what you are trying to do. Maybe later I’ll have some time to come up with a solution.

And maybe we can figure out if there’s a work-around for dealing with Chrome and cursors.

Note that I tried @walter’s code in the second post in Chrome Dev, and it seems to work OK. There may be a bug in the stable version of Chrome.

Try this:

    var tool = new go.Tool();
    tool.canStart = function() {
      // if both PanningTool and DragSelectingTool might be able to run,
      // change the cursor right away
      var diag = this.diagram;
      if (diag && diag.lastInput.left && !diag.lastInput.control && 
          diag.allowSelect && (diag.allowHorizontalScroll || diag.allowVerticalScroll) &&
          diag.findPartAt(diag.lastInput.documentPoint, true) === null) {
        diag.currentCursor = "move";  // assuming PanningTool
        setTimeout(function() {
          if (diag.currentTool === diag.defaultTool) {
            diag.currentCursor = "crosshair";  // assuming DragSelectingTool
          }
        }, diag.toolManager.dragSelectingTool.delay);
      }
      return false;
    }
    myDiagram.toolManager.mouseDownTools.add(tool);

Thanks. I had to change the creation to ActionTool as Tool is abstract and couldn’t be created directly, but otherwise it works perfectly on Firefox. On Chrome, if I just hold the mouse button down, I see the cursor change to move, but then back to the default after a short while, then at the right time shift to crosshair and then change back to the default again. On Firefox, the cursor stays as set. I’ve updated the delay for the DragSelectingTool to 750ms, so the first switch back to the default cursor may not happen on Chrome with the default delay.