public override uint MouseClick(MouseEventArgs e, GL_ControlBase control)
        {
            if (e.Button == MouseButtons.Right)
            {
                linkDragMode = LinkDragMode.None;
                return(REDRAW);
            }

            if (linkManager.hoveredConnection != null)
            {
                SelectedConnection = linkManager.hoveredConnection;
                UpdateSelection(REDRAW);
                return(REDRAW);
            }
            else
            {
                if (SelectedConnection != null)
                {
                    SelectedConnection = null;
                    return(REDRAW);
                }


                return(0);
            }
        }
        public override uint MouseDown(MouseEventArgs e, GL_ControlBase control)
        {
            if (e.Button != MouseButtons.Left)
            {
                linkDragMode = LinkDragMode.None;
                return(0);
            }

            if (WinInput.Keyboard.IsKeyDown(WinInput.Key.LeftCtrl))
            {
                SelectedConnection = new LinkConnection(Hovered3dObject, Hovered3dObject, Hovered3dObject.Links?.Keys.First() ?? "UnnamedConnection");
                linkDragMode       = LinkDragMode.Dest;
            }
            else if (SelectedConnection != null)
            {
                SceneDrawState.ZoneTransform = EditZoneTransform;

                //Check if mouse is on the Dest Point
                Point   linkingPoint       = GL_Control.ScreenCoordFor(SelectedConnection.Dest.GetLinkingPoint(this));
                Point   nextToLinkingPoint = GL_Control.ScreenCoordFor(SelectedConnection.Dest.GetLinkingPoint(this) + control.InvertedRotationMatrix.Row0 * 0.25f);
                Vector2 diff       = new Vector2(e.X, e.Y) - new Vector2(linkingPoint.X, linkingPoint.Y);
                Vector2 nextToDiff = new Vector2(nextToLinkingPoint.X, nextToLinkingPoint.Y) - new Vector2(linkingPoint.X, linkingPoint.Y);
                if (diff.LengthSquared < nextToDiff.LengthSquared)
                {
                    linkDragMode = LinkDragMode.Dest;
                    return(0);
                }

                //Check if mouse is on the Source Point
                linkingPoint       = GL_Control.ScreenCoordFor(SelectedConnection.Source.GetLinkingPoint(this));
                nextToLinkingPoint = GL_Control.ScreenCoordFor(SelectedConnection.Source.GetLinkingPoint(this) + control.InvertedRotationMatrix.Row0 * 0.25f);
                diff       = new Vector2(e.X, e.Y) - new Vector2(linkingPoint.X, linkingPoint.Y);
                nextToDiff = new Vector2(nextToLinkingPoint.X, nextToLinkingPoint.Y) - new Vector2(linkingPoint.X, linkingPoint.Y);
                if (diff.LengthSquared < nextToDiff.LengthSquared)
                {
                    linkDragMode = LinkDragMode.Source;
                    return(0);
                }

                linkDragMode = LinkDragMode.None;
            }

            return(0);
        }
        public override void DeleteSelected()
        {
            if (SelectedConnection == null)
            {
                return;
            }

            AddToUndo(new RevertableConnectionDeletion(
                          SelectedConnection.Source,
                          SelectedConnection.Dest,
                          SelectedConnection.Name));

            RemoveConnection(
                SelectedConnection.Source,
                SelectedConnection.Dest,
                SelectedConnection.Name);

            SelectedConnection = null;

            UpdateSelection(REDRAW);
        }
        public override uint MouseUp(MouseEventArgs e, GL_ControlBase control)
        {
            if (linkDragMode != LinkDragMode.None && Hovered3dObject != null)
            {
                if (SelectedConnection.Source == SelectedConnection.Dest) //just created
                {
                    if (SelectedConnection.Source == Hovered3dObject)
                    {
                        SelectedConnection = null;
                    }
                    else
                    {
                        AddConnection(SelectedConnection.Source, Hovered3dObject, SelectedConnection.Name);

                        UpdateLinkDestinations();

                        AddToUndo(new RevertableConnectionAddition(SelectedConnection.Source, Hovered3dObject, SelectedConnection.Name));

                        SelectedConnection.Dest = Hovered3dObject;

                        UpdateSelection(0);
                    }
                }
                else if (linkDragMode == LinkDragMode.Source)
                {
                    ChangeSelectedConnection(Hovered3dObject, SelectedConnection.Dest, SelectedConnection.Name);
                }

                else
                {
                    ChangeSelectedConnection(SelectedConnection.Source, Hovered3dObject, SelectedConnection.Name);
                }
            }

            linkDragMode = LinkDragMode.None;

            return(base.MouseUp(e, control) | REDRAW);
        }
        private void ChangeSelectedConnection(I3dWorldObject newSource, I3dWorldObject newDest, string newName)
        {
            if (newSource == SelectedConnection.Source && newDest == SelectedConnection.Dest && newName == SelectedConnection.Name)
            {
                return; //nothing has changed
            }
            if (newSource == newDest)
            {
                return; //a link can't load to itself
            }
            if (newName == "")
            {
                return; //a links name can't be empty
            }
            if (newSource is Rail)
            {
                return; //Rails can't have links
            }
            AddToUndo(new RevertableConnectionChange(
                          newSource, newDest, newName,
                          SelectedConnection.Source,
                          SelectedConnection.Dest,
                          SelectedConnection.Name
                          ));

            RemoveConnection(
                SelectedConnection.Source,
                SelectedConnection.Dest,
                SelectedConnection.Name
                );

            AddConnection(newSource, newDest, newName);

            UpdateLinkDestinations();

            SelectedConnection = new LinkConnection(newSource, newDest, newName);
        }