public ScaleMatrixTopControl(IObject3DControlContext context)
            : base(context)
        {
            theme = AppContext.Theme;

            zValueDisplayInfo = new InlineEditControl()
            {
                ForceHide = () =>
                {
                    // if the selection changes
                    if (RootSelection != activeSelectedItem)
                    {
                        return(true);
                    }

                    // if another control gets a hover
                    if (Object3DControlContext.HoveredObject3DControl != this &&
                        Object3DControlContext.HoveredObject3DControl != null)
                    {
                        return(true);
                    }

                    // if we clicked on the control
                    if (hadClickOnControl)
                    {
                        return(false);
                    }

                    return(false);
                },
                GetDisplayString = (value) => "{0:0.0}".FormatWith(value)
            };

            zValueDisplayInfo.VisibleChanged += (s, e) =>
            {
                if (!zValueDisplayInfo.Visible)
                {
                    hadClickOnControl = false;
                }
            };

            zValueDisplayInfo.EditComplete += (s, e) =>
            {
                var selectedItem = activeSelectedItem;

                Matrix4X4 startingTransform      = selectedItem.Matrix;
                var       originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                Vector3   topPosition            = GetTopPosition(selectedItem);
                var       lockedBottom           = new Vector3(topPosition.X, topPosition.Y, originalSelectedBounds.MinXYZ.Z);

                Vector3 newSize = Vector3.Zero;
                newSize.Z = zValueDisplayInfo.Value;
                Vector3 scaleAmount = ScaleMatrixCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, Object3DControlContext.GuiSurface.ModifierKeys);

                var scale = Matrix4X4.CreateScale(scaleAmount);

                selectedItem.Matrix = selectedItem.ApplyAtBoundsCenter(scale);

                // and keep the locked edge in place
                AxisAlignedBoundingBox scaledSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                var newLockedBottom = new Vector3(topPosition.X, topPosition.Y, scaledSelectedBounds.MinXYZ.Z);

                selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedBottom - newLockedBottom);

                Invalidate();

                Object3DControlContext.Scene.AddTransformSnapshot(startingTransform);
            };

            Object3DControlContext.GuiSurface.AddChild(zValueDisplayInfo);

            DrawOnTop = true;

            topScaleMesh = PlatonicSolids.CreateCube(arrowSize, arrowSize, arrowSize);

            CollisionVolume = topScaleMesh.CreateBVHData();

            Object3DControlContext.GuiSurface.BeforeDraw += Object3DControl_BeforeDraw;
        }
        public override void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver)
        {
            var selectedItem = RootSelection;

            activeSelectedItem = selectedItem;
            if (MouseIsOver)
            {
                zValueDisplayInfo.Visible = true;
            }
            else if (!hadClickOnControl)
            {
                zValueDisplayInfo.Visible = false;
            }

            if (MouseDownOnControl)
            {
                IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

                if (info != null &&
                    selectedItem != null)
                {
                    AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();

                    Vector3 delta = info.HitPosition - initialHitPosition;

                    Vector3 newPosition = originalPointToMove + delta;

                    if (Object3DControlContext.SnapGridDistance > 0)
                    {
                        // snap this position to the grid
                        double snapGridDistance = Object3DControlContext.SnapGridDistance;

                        // snap this position to the grid
                        newPosition.Z = ((int)((newPosition.Z / snapGridDistance) + .5)) * snapGridDistance;
                    }

                    Vector3 topPosition  = GetTopPosition(selectedItem);
                    var     lockedBottom = new Vector3(topPosition.X, topPosition.Y, originalSelectedBounds.MinXYZ.Z);

                    Vector3 newSize = Vector3.Zero;
                    newSize.Z = newPosition.Z - lockedBottom.Z;

                    // scale it
                    Vector3 scaleAmount = ScaleMatrixCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, Object3DControlContext.GuiSurface.ModifierKeys);

                    var scale = Matrix4X4.CreateScale(scaleAmount);

                    selectedItem.Matrix = selectedItem.ApplyAtBoundsCenter(scale);

                    // and keep the locked edge in place
                    AxisAlignedBoundingBox scaledSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                    var newLockedBottom = new Vector3(topPosition.X, topPosition.Y, scaledSelectedBounds.MinXYZ.Z);

                    selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedBottom - newLockedBottom);

                    Invalidate();
                }
            }

            base.OnMouseMove(mouseEvent3D, mouseIsOver);
        }