Paste to current cursor position

I realize the paste behavior adding the copied node on its old location, which means overlapped. For example, Minimal GoJS Sample

How can I paste the node to the position where my mouse clicked?

EDIT: I made some progress by overriding pasteSelection method as follow. But this only works for pasting to the same layer. If I paste to other layer, it seems not using the pos I set.

    // paste to current cursor point
    let commandHandler = newDiagram.commandHandler;
    commandHandler.pasteSelection = (pos? : go.Point) => {
        if (!pos) {
            pos = commandHandler.diagram.lastInput.documentPoint;
        }
        go.CommandHandler.prototype.pasteSelection.call(commandHandler, pos);
    }

Thanks,
Chuan

Yes, that’s the right idea. Note for example how the “Paste” command is implemented in the Basic samples’ context menu:

function(e, obj) { e.diagram.commandHandler.pasteSelection(e.diagram.lastInput.documentPoint); }

Layers are completely independent of position/location. So what you are saying doesn’t make sense to me.

Thanks for quick reply, just as usual.

What I mean is I do copy on one layer, then I move to another layer, then I do paste. The position seems not impacted but always use wherever my copied data is. For example, my copied data is in layer A at (50, 50), then I paste it to layer B at (100, 100) by setting pos as my last input position. however, in layer B, it is still go to (50, 50) but not (100, 100).

BTW, I am not using context menu to call pasteSelection but via ctrl+v. So I think I should override default API.

Ok, I give up overriding pasteSelection since it only works for copy/paste in same layer. I listen to ClipBoardPasted and I can see the position of subject was set correctly if pasting to same layer. However, when paste to another layer, the position is correct in overrided pastedSelection but will be reset to the copied node location as observed in ClipBoardPasted event.

This gives me an “inspiration” though. I do setDataProperty in ClipBoardPasted event to modify the loc since this is the last place where I know the location might be reset. And then it works! I still don’t know why pasting to another layer will cause reset on my position even if I pass lastInput.documentPoint to pasteSelection function. Any idea?

    newDiagram.addDiagramListener("ClipboardPasted", (e: any) => {
        let openedLayer: go.Layer = this.getOpenedLayer(e.diagram);

        e.subject.each((part: go.Part) => {
            if (part instanceof go.Node) {
                e.diagram.model.startTransaction("Modify part position");
                e.diagram.model.setDataProperty(part.data, "loc", go.Point.stringify(e.diagram.lastInput.documentPoint));
                e.diagram.model.commitTransaction("Modify part position");

                this.sharedDataService.broadcastChanged(Events.MOVE_DIALOG_FLOW_NODE, [part.data]);
            }

            if (openedLayer) {
                part.layerName = openedLayer.name;
            }
        });

        this.requestUpdateAll();
    });

I see two problems with your code:

  1. As is well documented ( GoJS Transactions -- Northwoods Software and Transaction | GoJS API ), you should not start and end a transaction within a loop. I’m guessing that holds true for the call to broadcastChange, whatever that does.
  2. You are setting the location of each node to the same point. Are you sure that is what you want?

You are right. Instead of doing that, I think I should add offset instead of setting the input position directly, in case of copy/paste multiple parts. But again, I still don’t understand why copy/paste between layers not work as expected.