Ghost to show the location of new element

Hello.

I'm trying to build my own diagramming tool, which has some custom behavior compared to the default GoDigram behavior. The most important policy is that none of the elements should overlap.

I have a modal custom tool (called NewEntityTool), which creates an element on each click on the GoView surface. It denies clicks, which would create elements that overlap others. It shows a deny cursor.

What I would like to do is, to have a ghost element, when I’m working with this modal tool, so the user can actually see that the new element would overlap with the existing ones. Like when I’m moving an element, a ghost of the moving element is shown by default although the element isn’t yet moved. Here is an example (the Second element is being moved):

How could I achieve that the ghost element would move with the mouse when my custom modal tool is on? I hope I’ve explained the problem well enough.

Thanks you for any suggestions.

That’s easy enough to implement in a few lines of code:
// A modal tool that inserts a copy of a prototype GoObject at the
// point the user clicks, as long as it does not overlap any other nodes.
//
// Example usage:
// ClickCreateTool ctool = new ClickCreateTool(goView1);
// GoTextNode proto = new GoTextNode();
// proto.Label.Alignment = GoObject.Middle;
// proto.AutoResizes = false;
// proto.Background.Size = new SizeF(150, 80);
// proto.Text = “a text node”;
// ctool.Prototype = proto;
// goView1.Tool = ctool;
[Serializable]
public class ClickCreateTool : GoTool {
public ClickCreateTool(GoView view) : base(view) { }
public override bool CanStart() {
return false; // cannot be run as a modeless tool – must assign GoView.Tool
}
public override void Start() {
this.View.CursorName = “crosshair”;
this.View.Layers.Default.Add(this.Prototype);
}
public override void Stop() {
this.Prototype.Remove(); // from view layer
this.View.CursorName = “default”;
}
public override void DoMouseMove() {
this.Prototype.Location = this.LastInput.DocPoint;
bool ok = this.View.Document.IsUnoccupied(this.Prototype.Bounds, null);
if (ok)
this.View.CursorName = “crosshair”;
else
this.View.CursorName = “not-allowed”;
}
public override void DoMouseUp() {
if (!IsBeyondDragSize() && this.View.Document.IsUnoccupied(this.Prototype.Bounds, null)) {
StartTransaction();
this.View.Document.AddCopy(this.Prototype, this.Prototype.Location);
this.TransactionResult = “inserted object”;
StopTransaction();
}
}
public GoObject Prototype {
get { return myPrototype; }
set { myPrototype = value; }
}
private GoObject myPrototype;
}
You’ll note that since this didn’t override DoKeyDown not to call DoCancelMouse, when the user types ESCAPE the tool will stop.

This class is now included in Demo1 in version 2.6.