protected override void OnSceneChanged()
 {
     base.OnSceneChanged();
     if (this.mouseoverObject != null && this.mouseoverObject.IsInvalid)
     {
         this.mouseoverObject = null;
     }
 }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.mouseoverAction = ObjectEditorAction.None;
            this.mouseoverObject = null;
            this.mouseoverSelect = false;
        }
        protected void UpdateMouseover(Point mouseLoc)
        {
            bool lastMouseoverSelect = this.mouseoverSelect;
            ObjectEditorSelObj lastMouseoverObject = this.mouseoverObject;
            ObjectEditorAction lastMouseoverAction = this.mouseoverAction;

            if (this.actionAllowed && !this.CamActionRequiresCursor && this.CamAction == CameraAction.None)
            {
                this.ValidateSelectionStats();

                // Determine object at mouse position
                this.mouseoverObject = this.PickSelObjAt(mouseLoc.X, mouseLoc.Y);

                // Determine action variables
                Vector3     mouseSpaceCoord     = this.GetSpaceCoord(new Vector3(mouseLoc.X, mouseLoc.Y, this.selectionCenter.Z));
                float       scale               = this.GetScaleAtZ(this.selectionCenter.Z);
                const float boundaryThickness   = 10.0f;
                bool        tooSmall            = this.selectionRadius * scale <= boundaryThickness * 2.0f;
                bool        mouseOverBoundary   = MathF.Abs((mouseSpaceCoord - this.selectionCenter).Length - this.selectionRadius) * scale < boundaryThickness;
                bool        mouseInsideBoundary = !mouseOverBoundary && (mouseSpaceCoord - this.selectionCenter).Length < this.selectionRadius;
                bool        mouseAtCenterAxis   =
                    MathF.Abs(mouseSpaceCoord.X - this.selectionCenter.X) * scale < boundaryThickness ||
                    MathF.Abs(mouseSpaceCoord.Y - this.selectionCenter.Y) * scale < boundaryThickness;
                bool shift = (Control.ModifierKeys & Keys.Shift) != Keys.None;
                bool ctrl  = (Control.ModifierKeys & Keys.Control) != Keys.None;

                bool anySelection = this.actionObjSel.Count > 0;
                bool canMove      = this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Move));
                bool canRotate    = (canMove && this.actionObjSel.Count > 1) || this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Rotate));
                bool canScale     = (canMove && this.actionObjSel.Count > 1) || this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Scale));

                // Select which action to propose
                this.mouseoverSelect = false;
                if (ctrl)
                {
                    this.mouseoverAction = ObjectEditorAction.RectSelect;
                }
                else if (anySelection && !tooSmall && mouseOverBoundary && mouseAtCenterAxis && this.selectionRadius > 0.0f && canScale)
                {
                    this.mouseoverAction = ObjectEditorAction.Scale;
                }
                else if (anySelection && !tooSmall && mouseOverBoundary && canRotate)
                {
                    this.mouseoverAction = ObjectEditorAction.Rotate;
                }
                else if (anySelection && mouseInsideBoundary && canMove)
                {
                    this.mouseoverAction = ObjectEditorAction.Move;
                }
                else if (shift)                 // Lower prio than Ctrl, because Shift also modifies mouse actions
                {
                    this.mouseoverAction = ObjectEditorAction.RectSelect;
                }
                else if (this.mouseoverObject != null && this.mouseoverObject.IsActionAvailable(ObjectEditorAction.Move))
                {
                    this.mouseoverAction = ObjectEditorAction.Move;
                    this.mouseoverSelect = true;
                }
                else
                {
                    this.mouseoverAction = ObjectEditorAction.RectSelect;
                }
            }
            else
            {
                this.mouseoverObject = null;
                this.mouseoverSelect = false;
                this.mouseoverAction = ObjectEditorAction.None;
            }

            // If mouseover changed..
            if (this.mouseoverObject != lastMouseoverObject ||
                this.mouseoverSelect != lastMouseoverSelect ||
                this.mouseoverAction != lastMouseoverAction)
            {
                // Adjust mouse cursor based on proposed action
                if (this.mouseoverAction == ObjectEditorAction.Move)
                {
                    this.Cursor = CursorHelper.ArrowActionMove;
                }
                else if (this.mouseoverAction == ObjectEditorAction.Rotate)
                {
                    this.Cursor = CursorHelper.ArrowActionRotate;
                }
                else if (this.mouseoverAction == ObjectEditorAction.Scale)
                {
                    this.Cursor = CursorHelper.ArrowActionScale;
                }
                else
                {
                    this.Cursor = CursorHelper.Arrow;
                }
            }

            // Redraw if action gizmos might be visible
            if (this.actionAllowed)
            {
                this.Invalidate();
            }
        }