Simulate DND

Hello!

How can I simulate a Drag and drop in Go? By simulate, I mean, invoke all the methods programmatically that would be called during a normal user operation with mouse. For instance, if I needed to simulate the drawing of a link, I can do -

GoToolLinkingNew drawer = new GoToolLinkingNew(aView);
drawer.DoNewLink(fromPort, toPort);

Here, after DoNewLink, all the methods/validations that are performed after creating a link would be called.

Can I achieve this for DND?

TIA,

Pradip

Sure – that’s the reason GoDiagram has a canonical/unified input event mechanism, using GoInputEventArgs.
Basically you just set up GoView.FirstInput and GoView.LastInput the way you want, and then call GoView.DoMouseDown followed by calls to DoMouseMove and finally a call to DoMouseUp. Before each of those DoMouse… calls you make sure that GoView.LastInput has the values you want.
In fact, this is how GoDiagram Web is implemented, so that all the same tools and events can happen on the server as simulated from the client. (Well, maybe not all events, such as mouse-over or hover, since those would be impractical.)
Of course this is how GoDiagram Win is implemented, since the overrides for Control.OnMouseDown, OnMouseMove, OnMouseUp, OnDoubleClick, OnKeyDown all set up GoInputEventArgs and call those methods.
And you can use this mechanism for implementing your own regression tests.

Can you please give an example?

This is what I have so far -

public partial class Form1 : Form
{
private GoView view;
private PointF startingPosition = new PointF(50, 50);

    public Form1()
    {
          InitializeComponent();
          InitGoObjects();
          Controls.Add(view);
          TryMoving();              
    }

    private void InitGoObjects()
    {
          view = new GoView();
          view.Dock = DockStyle.Fill;

          GoText t1 = new GoText();
          t1.Text = "Blandings";
          t1.Position = startingPosition;
          view.Document.Add(t1);
    }

    private void TryMoving()
    {
          view.FirstInput.DocPoint = startingPosition;
          // I would expect this to select t1 by clicking on it.
          view.DoMouseDown();                     
          view.LastInput.DocPoint = new PointF(450, 100);
          view.DoMouseMove();
          view.DoMouseUp();
    }        
}

Also, is it possible to simulate the clicking of buttons? I tried the following -

[continuing with the previous example]

private void TryClicking()
{
GoToolAction action = new GoToolAction(view);
GoInputEventArgs inputEventArgs = new GoInputEventArgs();
inputEventArgs.DocPoint = new PointF(startingPosition.X + 5, startingPosition.Y);
//inputEventArgs.IsContextButton = true;
action.DoClick(inputEventArgs);
}

Can we use GoToolAction to simulate the clicking of objects/buttons? How?

You need to set all of the GoInputEventArgs properties. In particular, you didn’t specify which button was used. But you really need to set all of the properties, except maybe for the Mouse/Drag/KeyEventArgs.

There is no button that is used. It is a drag and drop operation, i.e. in the code above, I am trying to select t1 and move it to a new location. This is the code I have, for moving t1.

[startingPosition is defined in my earlier message.]

private void TryMoving()
{
view.FirstInput.Buttons = MouseButtons.Left;
view.FirstInput.Delta = 0;
view.FirstInput.DocPoint = startingPosition;
view.FirstInput.DoubleClick = false;
view.FirstInput.InputState = GoInputState.Start;
view.FirstInput.Key = Keys.None;
view.FirstInput.Modifiers = Keys.None;
view.FirstInput.MouseEventArgs = null;
view.FirstInput.ViewPoint = new Point((int)startingPosition.X, (int) startingPosition.Y);

          view.LastInput.Buttons = MouseButtons.Left;
          view.LastInput.Delta = 0;
          view.LastInput.DocPoint = startingPosition;
          view.LastInput.DoubleClick = false;
          view.LastInput.InputState = GoInputState.Start;
          view.LastInput.Key = Keys.None;
          view.LastInput.Modifiers = Keys.None;
          view.LastInput.MouseEventArgs = null;
          view.LastInput.ViewPoint = new Point(x, y);

          // I would expect this to select t1 by clicking on it.
          view.DoMouseDown();
          view.DoMouseMove();

          view.LastInput.Buttons = MouseButtons.Left;
          view.LastInput.Delta = 0;
          view.LastInput.DocPoint = new PointF(450, 100);
          view.LastInput.DoubleClick = false;
          view.LastInput.InputState = GoInputState.Start;
          view.LastInput.Key = Keys.None;
          view.LastInput.Modifiers = Keys.None;
          view.LastInput.MouseEventArgs = null;
          view.LastInput.ViewPoint = new Point(452, 102);
          view.DoMouseUp();
    }

So my question is -

  1. Since my view.LastInput (before view.DoMouseDown();) points to t1, does view.DoMouseDown(); select the t1 object or not? I believe that t1 is selected after DoMouseDown since t1 appears selected. In that case, why is the move of t1 not working?

Are you sure that the values of the ViewPoint properties correctly correspond to the values of the DocPoint properties? You should be using GoView.ConvertDocToView.
Whether the selectable object at the mouse point is selected depends on the tool that is chosen to run. GoToolDragging, used for moving or copying, does select.
If you are intending to simulate a drag-and-drop, please be aware that starting a GoToolDragging will call Control.DoDragDrop in Windows Forms if GoView.AllowDragOut is true. To continue that simulation you will need to call all of the standard drag-and-drop methods that Control defines.
Alternatively, you could set GoView.AllowDragOut to false, to avoid the dragging tool calling Control.DoDragDrop. If you don’t want to drag out to a different window, but just want to pretend to do a drag-and-drop internally within the GoView, this would be OK for making use of the dragging tool.

I am a little confused at the moment. Can you answer these questions?

  1. What are the default tools present in a goview? When I do view = new GoView(); I can only see a GoToolManager in view.DefaultTool.

  2. What does mode-less tool mean?

Going back to the original question - I tried what you mentioned and this is what I have now. I seem to be moving a copy of t1 instead of t1. Moreover, the DoMouseUp doesn’t seem to end the DND.

private void TryMoving()
{
view.AllowDragOut = false;

          GoToolDragging dragger = view.FindMouseTool(typeof(GoToolDragging)) as GoToolDragging;
          if (dragger == null)
          {
              dragger = new GoToolDragging(view);
          }

          view.DefaultTool = dragger;

          view.FirstInput.Buttons = MouseButtons.Left;
          view.FirstInput.Delta = 0;
          view.FirstInput.DocPoint = startingPosition;
          view.FirstInput.DoubleClick = false;
          view.FirstInput.InputState = GoInputState.Start;
          view.FirstInput.Key = Keys.None;
          view.FirstInput.Modifiers = Keys.None;
          view.FirstInput.MouseEventArgs = null;
          view.FirstInput.ViewPoint = view.ConvertDocToView(startingPosition);

          view.LastInput.Buttons = MouseButtons.Left;
          view.LastInput.Delta = 0;
          view.LastInput.DocPoint = startingPosition;
          view.LastInput.DoubleClick = false;
          view.LastInput.InputState = GoInputState.Start;
          view.LastInput.Key = Keys.None;
          view.LastInput.Modifiers = Keys.None;
          view.LastInput.MouseEventArgs = null;
          view.LastInput.ViewPoint = view.ConvertDocToView(startingPosition);

          // I would expect this to select t1 by clicking on it.
          view.DoMouseDown();
          view.DoMouseMove();              

          view.LastInput.Buttons = MouseButtons.Left;
          view.LastInput.Delta = 0;
          view.LastInput.DocPoint = new PointF(450, 100);
          view.LastInput.DoubleClick = false;
          view.LastInput.InputState = GoInputState.Finish;
          view.LastInput.Key = Keys.None;
          view.LastInput.Modifiers = Keys.None;
          view.LastInput.MouseEventArgs = null;
          view.LastInput.ViewPoint = view.ConvertDocToView(new Point(450, 100));

          // view.DoDragDrop(view.Selection, DragDropEffects.Move);
          view.DoMouseUp();
    }

Pages 88-89 of the User Guide talk about the standard modeless tools that GoView has. A tool is modeless if it is added to one of the three GoView.Mouse…Tools lists, so that the tool’s CanStart predicate can be called by GoToolManager to decide whether or not to make that tool the current one.
If you explicitly set GoView.Tool to an instance of a tool, that is effectively using the tool in a modal fashion, since that tool will keep running until it calls GoTool.StopTool() or until GoView.Tool is reset. Some of the predefined tool classes can be used in either modeless or modal fashion–look for a Modal property on the tool.
The GoView.DefaultTool just provides the default tool to run when the current tool stops. I doubt you need to manipulate tools in your code here.
I think the problem with your code is that you aren’t specifying the position of the mouse for the move. I added that and simplified your code, and it works just fine:
PointF startingPosition = anObj.Center;
PointF endingPosition = new PointF(450, 100);
PointF intermediatePosition = new PointF((startingPosition.X+endingPosition.X)/2, (startingPosition.Y+endingPosition.Y)/2);
bool oldDragOut = view.AllowDragOut; // temporarily GoView.AllowDragOut to false!
view.AllowDragOut = false;
view.FirstInput.Buttons = MouseButtons.Left;
view.FirstInput.Delta = 0;
view.FirstInput.DocPoint = startingPosition;
view.FirstInput.DoubleClick = false;
view.FirstInput.InputState = GoInputState.Start;
view.FirstInput.Key = Keys.None;
view.FirstInput.Modifiers = Keys.None;
view.FirstInput.MouseEventArgs = null;
view.FirstInput.ViewPoint = view.ConvertDocToView(startingPosition);
view.LastInput.Buttons = MouseButtons.Left;
view.LastInput.Delta = 0;
view.LastInput.DocPoint = startingPosition;
view.LastInput.DoubleClick = false;
view.LastInput.InputState = GoInputState.Start;
view.LastInput.Key = Keys.None;
view.LastInput.Modifiers = Keys.None;
view.LastInput.MouseEventArgs = null;
view.LastInput.ViewPoint = view.ConvertDocToView(startingPosition);
view.DoMouseDown();
view.LastInput.InputState = GoInputState.Continue;
view.LastInput.DocPoint = intermediatePosition;
view.LastInput.ViewPoint = view.ConvertDocToView(intermediatePosition);
view.DoMouseMove();
// If view.AllowDragOut is true, GoToolDragging.Start will call
// Control.DoDragDrop on the GoView. Note that Control.DoDragDrop
// is MODAL, so it will not return until the drag-and-drop is finished.
// But if view.AllowDragOut is false, you can just do:
view.LastInput.InputState = GoInputState.Finish;
view.LastInput.DocPoint = endingPosition;
view.LastInput.ViewPoint = view.ConvertDocToView(endingPosition);
view.DoMouseUp();
view.AllowDragOut = oldDragOut;

Thanks! That works fine. I will try simulating other events using the tools/view and come back if I have more questions :-)