public override bool OnMouseUp(Point mouseCurPos, MouseButtons button, BaseViewport viewport)
        {
            if (viewport.ViewportType != BaseViewport.ViewportTypes.PERSPECTIVE &&
                button == MouseButtons.Left)
            {
                RubberBand       rubberBand          = controller.RubberBand;
                MapObject        selectionGroup      = controller.Selection;
                SolidGrabHandles handles             = rubberBand.Handles;
                Matrix4          fromGridSpaceMatrix = viewport.Camera.GetViewMatrix().ClearTranslation();

                // check for the program to decide if it needs to go the next grab handle mode
                bool isHoveringSelectedSolid = IsSelectedSolidAabbHit(mouseCurPos.X, mouseCurPos.Y, viewport);
                bool hasNoNewSelection       = currentAction != SolidToolActionType.Select;

                Vector3 snappedDownMousePosition = GeneralUtility.SnapToGrid(
                    new Vector3(mouseDownPos.X, mouseDownPos.Y, 0), viewport.GridSize);
                Vector3 snappedCurMousePosition = GeneralUtility.SnapToGrid(new Vector3(mouseCurPos.X, mouseCurPos.Y, 0),
                                                                            viewport.GridSize);
                bool mouseHasNotMoved = snappedDownMousePosition == snappedCurMousePosition;

                if (isHoveringSelectedSolid && mouseHasNotMoved && hasNoNewSelection)
                {
                    handles.NextMode();
                }
                else
                {
                    switch (currentAction)
                    {
                    case SolidToolActionType.Create:
                        controller.CreateSolid(fromGridSpaceMatrix);
                        break;

                    case SolidToolActionType.Drag:
                        // set new position
                        Vector3 displacement = rubberBand.Bounds.Center - selectionGroup.Bounds.Center;
                        controller.Selection.PerformOperation(new TranslateOperation(displacement));
                        break;

                    case SolidToolActionType.Transform:
                        Vector3             oldBoundVector = selectionGroup.Bounds.Max - selectionGroup.Bounds.Min;
                        Vector3             newBoundVector = rubberBand.Bounds.Max - rubberBand.Bounds.Min;
                        IMapObjectOperation operation      = null;

                        switch (handles.Mode)
                        {
                        case SolidGrabHandles.HandleMode.Resize:
                            operation = new ResizeTransformation(fromGridSpaceMatrix, oldBoundVector,
                                                                 newBoundVector,
                                                                 handles.LastHitStatus, viewport.GridSize);
                            break;

                        case SolidGrabHandles.HandleMode.Rotate:
                            operation = new RotateTransformation(fromGridSpaceMatrix, Vector3.Zero, Vector3.Zero,
                                                                 rubberBand.Transformation);
                            break;

                        case SolidGrabHandles.HandleMode.Skew:
                            operation = new SkewTransformation(fromGridSpaceMatrix, Vector3.Zero, Vector3.Zero,
                                                               rubberBand.Transformation,
                                                               handles.LastHitStatus);
                            break;
                        }

                        if (operation != null)
                        {
                            controller.Selection.PerformOperation(operation);
                        }
                        break;
                    }

                    controller.UpdateUserInterface();
                }

                rubberBand.SetToZeroVolume();
                rubberBand.ShowGrabhandles = true;
                currentAction = SolidToolActionType.None;
            }

            return(true);
        }