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.
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.