Disable selection adornment and resize adornment while node is being rotated and reposition rotate handle on top

How can I disable Adornment while I’m rotating a node?
Also,

Currently i’m positioning the rotate handle on top by

diagram.toolManager.rotatingTool.handleAngle = 270;

But it moves along with the shape, I want it to get back to angle 270 once I’ve rotated the shape.

Are you saying that you do not want the rotation handle to indicate the current angle of the object that was rotated? So that after every rotation operation by RotatingTool the Resizing Adornment is reset to be above the node?

And you also do not want the Selection Adornment to follow along with the rotated object?

Have you set either Part.selectionObjectName or Part.rotateObjectName?

Could you please share with us a screenshot of the current behavior and a sketch of what you want instead? It would be good if you considered a case where the rotation was of some non-multiple of 90 degrees, unless your app will only do rotations that are a multiple of 90 degrees.

right when drawn a shape it appears like this, this has rotation adornment, resize adornment and selection adornment.
I’ve set { rotateObjectName = “SHAPE” }

step 1

the nodeTemplate is using drag creating tool,

diagram.nodeTemplateMap.add(

  "DragRectangle",

  $(

    go.Node,

    "Auto",

    {

      //click: printKey,

      locationSpot: go.Spot.Center,

      reshapable: true,

      zOrder: 1,

    },

    {

      selectionAdorned: true,

      // selectionObjectName: "SHAPE",

      // custom selection adornment: a blue rectangle

      selectionAdornmentTemplate: $(

        go.Adornment,

        "Spot", //configuration panel

        $(

          go.Panel,

          "Auto",

          $(go.Shape, {

            stroke: "Transparent",

            strokeWidth: 2,

            fill: null,

          }),

          $(go.Placeholder, { margin: 25 })

        ),

        $(go.Shape, {

          alignmentFocus: go.Spot.Top,

          // alignment: new go.Spot(0.5, 1.2),

          alignment: go.Spot.Bottom,

          // margin: 15,

          geometryString:

            "M123 0H8C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16H123C127.418 16 131 12.4183 131 8C131 3.58172 127.418 0 123 0Z",

          fill: "#00D1FF",

          stroke: "#00D1FF",

          strokeWidth: 40,

        }),

        $(

          go.Panel,

          "Horizontal",

          {

            // alignment: new go.Spot(0.5, 1.2),

            alignmentFocus: go.Spot.Top,

            alignment: go.Spot.Bottom,

          },

          $(

            "Button",

            {

              margin: 15,

              height: 26,

              width: 26,

              "ButtonBorder.stroke": null,

              "ButtonBorder.fill": "#00D1FF",

              click: function (e, obj) {

                _sendSelectionDetailsToNative(

                  _CURRENT_SELECTION_KEY,

                  _CURRENT_SELECTION,

                  _CURRENT_SELECTION_CATEGORY,

                  _PREVIOUS_SELECTION_KEY,

                  "SETTINGS"

                );

              },

            }, // defined below, to support editing the text of the node

            $(go.Picture, "./Assets/img/settings.svg", {})

          ),

          $(

            "Button",

            {

              margin: 15,

              height: 26,

              width: 26,

              "ButtonBorder.fill": "#00D1FF",

              "ButtonBorder.stroke": null,

              click: function (e, button) {

                // this is different from CommandHandler.deleteSelection because this

                // only deletes the one node, not all selected parts

                e.diagram.commit(function (d) {

                  e.diagram.commandHandler.copySelection();

                  e.diagram.commandHandler.pasteSelection(

                    e.diagram.toolManager.contextMenuTool.mouseDownPoint

                  );

                }, "copy node");

                _sendSelectionDetailsToNative(

                  _CURRENT_SELECTION_KEY,

                  _CURRENT_SELECTION,

                  _CURRENT_SELECTION_CATEGORY,

                  _PREVIOUS_SELECTION_KEY,

                  "COPY"

                );

              },

            }, // defined below, to support editing the text of the node

            $(go.Picture, "./Assets/img/copy.svg", {})

          ),

          $(

            "Button",

            {

              margin: 15,

              height: 26,

              width: 26,

              "ButtonBorder.fill": "#00D1FF",

              "ButtonBorder.stroke": null,

              click: function (e, button) {

                // this is different from CommandHandler.deleteSelection because this

                // only deletes the one node, not all selected parts

                e.diagram.commit(function (d) {

                  d.remove(button.part.adornedPart);

                }, "deleted node");

   

                _sendSelectionDetailsToNative(

                  _CURRENT_SELECTION_KEY,

                  _CURRENT_SELECTION,

                  _CURRENT_SELECTION_CATEGORY,

                  _PREVIOUS_SELECTION_KEY,

                  "DELETE"

                );

              },

            }, // defined below, to support editing the text of the node

            $(go.Picture, "./Assets/img/trash.svg", {})

          )

   

        

        )

      ),

    },

    new go.Binding("selectionAdorned", "selectionAdorned"),

    {

      minSize: new go.Size(60, 20),

      resizable: true,

      // movable: receiveValue,

      resizeObjectName: "SHAPE",

     // resizeAdornmentTemplate: _getResizeAdornmentTemplate(),

    },

    new go.Binding("resizable", "resizable"),

    {

      rotatable: true,

      rotateObjectName: "SHAPE",

      rotateAdornmentTemplate: _getRotateAdornmentTemplate(),

    },

    new go.Binding("position", "pos", go.Point.parse).makeTwoWay(

      go.Point.stringify

    ),

    $(

      go.Shape,

      OBJ_RECTANGLE,

      {

        fill: "Transparent",

        strokeWidth: 2,

        name: "SHAPE",

      },

      new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(

        go.Size.stringify

      ),

      new go.Binding("angle").makeTwoWay()

    ),

    $(

      go.Panel,

      "Grid",

      {

        name: "GRID",

        desiredSize: new go.Size(100, 100),

        gridCellSize: new go.Size(20, 20),

        visible: false,

      },

      new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(

        go.Size.stringify

      ),

      new go.Binding("gridCellSize", "cell", go.Size.parse).makeTwoWay(

        go.Size.stringify

      ),

      new go.Binding("visible", "gridVisible").makeTwoWay(),

      $(go.Shape, "LineV", new go.Binding("stroke", "gridStroke")),

      $(go.Shape, "LineH", new go.Binding("stroke", "gridStroke"))

    )

  )

);

var _getRotateAdornmentTemplate = function () {

return $(

  go.Adornment,

  { locationSpot: go.Spot.Center },

  $(go.Shape, {

    width: 24,

    height: 24,

    cursor: "pointer",

    background: "transparent",

    stroke: null,

    fill: "Trasparent",

  }),

  $(go.Picture, "./Assets/img/rotate.svg")

);

};


tool.archetypeNodeData = {

  fill: "transparent",

  stroke: "black",

  strokeWidth: 2,

  figure: OBJ_RECTANGLE,

  opacity: 1,

  category: "DragRectangle",

  key: uuidv4(),

  cell: "20 20",

  gridStroke: "green",

  gridVisible: false,

  //isGroup: true

};

Temporarily removing the selection adornment is easy:

      "rotatingTool.doActivate": function() {
        go.RotatingTool.prototype.doActivate.call(this);
        this._savedSelAd = this.adornedObject.part.selectionAdorned;
        this.adornedObject.part.selectionAdorned = false;
      },
      "rotatingTool.doDeactivate": function() {
        this.adornedObject.part.selectionAdorned = this._savedSelAd;
        go.RotatingTool.prototype.doDeactivate.call(this);
      },

Pretending that the angle is something that it is not might be tricky. I’ll have to look into it.

Thanks a lot Walter, Appreciate it much!

If you use this class, replacing the standard ToolManager.rotatingTool, you won’t need to override “rotatingTool.doActivate” or “rotatingTool.doDeactivate” any more.

myDiagram = $(go.Diagram, . . .,
  {
    rotatingTool: new ResettingRotatingTool(),
    . . .
  })
class ResettingRotatingTool extends go.RotatingTool {
  constructor() {
    super();
    this.relativeAngle = 0;
    this.initialAngle = 0;
  }
  // The rotation handle always starts at zero, where zero is above the rotationPoint.
  // Its position is always at relativeAngle, relative to the rotationPoint.
  updateAdornments(part) {
    super.updateAdornments(part);
    let adornment = part.findAdornment(this.name);
    if (adornment) adornment.angle = this.relativeAngle;
  }
  computeAdornmentLocation(obj) {  // don't call super method, which depends on adornedObject.angle
    let p = this.rotationPoint;
    if (!p.isReal()) p = this.computeRotationPoint(obj);
    // don't use handleAngle but assume it's -90
    const q = new go.Point(0, - (obj.naturalBounds.width + obj.naturalBounds.height)/2 - this.handleDistance);
    return q.rotate(this.relativeAngle).offset(p.x, p.y);
  }
  // The angle of the adornedObject shouldn't be set to the relativeAngle,
  // but to the initialAngle plus the relativeAngle.
  doActivate() {
    this.handleAngle = 0;  // don't depend on this property
    super.doActivate();
    this.initialAngle = this.adornedObject.angle;
    // hide any selection Adornment
    this._savedSelAd = this.adornedObject.part.selectionAdorned;
    this.adornedObject.part.selectionAdorned = false;
  }
  doDeactivate() {
    const part = this.adornedObject.part;
    // maybe re-show any selection Adornment
    part.selectionAdorned = this._savedSelAd;
    super.doDeactivate();
    this.relativeAngle = 0;
    this.updateAdornments(part);
  }
  computeRotate(newPoint) {
    // this doesn't use handleAngle, but assumes it's -90 both here and in computeAdornmentLocation
    let a = super.computeRotate(newPoint) + 90;
    if (a >= 360) a -= 360; else if (a < 0) a += 360;
    this.relativeAngle = a;
    a += this.initialAngle;  // real angle will be initialAngle + relativeAngle
    if (a >= 360) a -= 360; else if (a < 0) a += 360;
    return a;
  }
}  // end of ResettingRotatingTool

This works great, Thanks again Walter!