Item array hover buttons when text block is in edit mode

I have this sample

which on hover it popup an action adornment to have some actions

in the example I did a long time wait just to show the problem

 this.dia.toolManager.hoverDelay = 1000;

so when I am in a view mode everything is ok.
the adornment appears after a second.

the problem is when I edit one of the values
then try to hover over one of the other values the adornment does not appear
image

the expected behavior should be that when I am in edit mode then continue to see the adornment(on hover) and when I click somewhere the we can get out of the edit mode.
how can I achieve that?

Yes, while editing some text, focus has moved out of the diagram and into the textarea. The text editor is running, not the ToolManger which is what normally handles hover events. By default the text editor does not have the regular behaviors which would occur if the text editor weren’t running, since most people do not want to be distracted with stuff unrelated to editing text. The default text editor implementation is provided in https://gojs.net/latest/extensions/TextEditor.js or https://gojs.net/latest/extensionsJSM/TextEditor.ts.

You could extend the text editor so that it detects mouse movement in that textarea and decide to show an Adornment. You would also need to handle a click to an Adornment button and mouse leaving of the Adornment to cause the Adornment to disappear. So the implementation of this new functionality will be rather involved.

I will give it a try, but it will take some time (because it is complicated maybe the priority of this will be lower then other features)

thanks

I thought about it and tried to do something,
first I need to listen to events for all the system (not just the textArea) since I need to know on which element the mouse is over.
basically I will need todo everything that the tool manager is doing.
it look too complicated.
where am I wrong?

When editing starts on a click, could you always show the Adornment, as if a hover had happened?

yes, but I do not want the hover to be on the edited text,
I want the user to keep hovering over all items and for each item it should show its adornment

So you do want to have the diagram handle pointer events while the text editor handles keyboard and pointer events. Perhaps that could be achieved by customizing the TextEditingTool to delegate such events that are outside of the textarea on to the ToolManager.

that was my thought also, but I could not do it
because the events I have on editing tool are [doMouseUp,doMouseDown]
and I do not know to which method of the toolManger should I call

The same methods. When I get more free time later today I can do the experiment.

This is a start. You may find you’ll have to do some additional adaptation in order to get it to work the way that your app needs.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
class CustomTextEditingTool extends go.TextEditingTool {
  doMouseDown() { if (this.isActive) { super.doMouseDown(); this.diagram.toolManager.doMouseDown(); } }
  doMouseMove() { if (this.isActive) this.diagram.toolManager.doMouseMove(); }
  doMouseUp() { if (this.isActive) this.diagram.toolManager.doMouseUp(); }
}

const $ = go.GraphObject.make;

const myDiagram =
  new go.Diagram("myDiagramDiv",
    {
      textEditingTool: new CustomTextEditingTool(),
      "undoManager.isEnabled": true,
      "ModelChanged": e => {     // just for demonstration purposes,
        if (e.isTransactionFinished) {  // show the model data in the page's TextArea
          document.getElementById("mySavedModel").textContent = e.model.toJson();
        }
      }
    });

const AD =
  $(go.Adornment, "Spot",
    { mouseLeave: (e, ad) => ad.adornedPart.removeAdornment("AD") },
    $(go.Placeholder),
    $(go.Panel,
      { background: "transparent", alignment: go.Spot.Right, alignmentFocus: go.Spot.Left },
      $("Button", { margin: new go.Margin(2, 2, 2, 6) },
        $(go.Shape, "Diamond", { width: 12, height: 12, fill: "red", stroke: "darkred" }),
        { click: (e, shp) => alert(shp.part.adornedObject.data) }
      )
    )
  );

myDiagram.nodeTemplate =
  $(go.Node, "Auto",
    $(go.Shape, { fill: "lightyellow" }),
    $(go.Panel, "Vertical",
      new go.Binding("itemArray", "items"),
      {
        itemTemplate:
          $(go.Panel, "Horizontal",
            $(go.Shape, { width: 10, height: 10, margin: 2 }),
            $(go.TextBlock, { editable: true },
              new go.Binding("text", "").makeTwoWay()),
            {
              mouseEnter: (e, panel) => { AD.adornedObject = panel; panel.part.addAdornment("AD", AD); },
              mouseLeave: (e, panel, next) => { if (!next || !next.isContainedBy(AD)) panel.part.removeAdornment("AD"); }
            }
          ),
        defaultAlignment: go.Spot.Left,
        margin: 6
      }
    )
  );

myDiagram.model = new go.GraphLinksModel(
[
  { key: 1, text: "Alpha",
    items: ["one", "two", "three", "four", "five"] },
]);
  </script>
</body>
</html>

it works on the my test app

it still does not work on my app,
I will check
thanks

it works for me in my app also.
I only needed to override the do doMouseMove
thanks