Hi,


I am creating a simple shape editor, much like the Visual Studio form designer. You can create shapes, select them and move/resize them using drag handles just like in Visual Studio or most other applications (Visio, etc).

I have run into some problems trying to implement a MinimumSize property for the shapes.

First of all, this is how I'm resizing the shapes. Each shape has a Resize method, accepting two integers (dx and dy) that represent how much the shape must resize by, and one 'HitStatus', which determines in which direction the resize must take place (for example, from the TopLeft, or Bottom, or BottomRight, etc..)

What it does basically is use a large Select Case statement for the hit status. In each case, it changes the Bounds property of the shape (which determines the location and size), so that it is resized:
vb.net Code:
  1. Public Sub Resize(ByVal hitStatus As HitStatus, ByVal dx As Integer, ByVal dy As Integer)
  2.  
  3.    Dim newBounds As Rectangle = Me.Bounds
  4.  
  5.    Select Case hitStatus
  6.       Case HitStatus.TopLeft
  7.          newBounds = New Rectangle(newBounds.X + dx,
  8.                    newBounds.Y + dy,
  9.                    newBounds.Width - dx,
  10.                    newBounds.Height - dy)
  11.       Case HitStatus.Bottom
  12.          newBounds = New Rectangle(newBounds.X,
  13.                    newBounds.Y,
  14.                    newBounds.Width,
  15.                    newBounds.Height + dy)
  16.       'etc, for all sides
  17.    End Select
  18.  
  19.    Me.Bounds = newBounds
  20.  
  21. End Sub

This method is called in the OnMouseMove override of the 'canvas panel' that the shapes live in:
vb.net Code:
  1. Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
  2.    MyBase.OnMouseMove(e)
  3.  
  4.    If mouseDown Then
  5.       If Me.SelectedShape IsNot Nothing Then
  6.  
  7.          If hitStatus = Shape.HitStatus.Drag Then  'we are dragging
  8.  
  9.             Me.SelectedShape.Move(e.X - moveStart.X, e.Y - moveStart.Y)
  10.             moveStart = e.Location
  11.          
  12.          ElseIf hitStatus <> Shape.HitStatus.None Then  'we are resizing
  13.  
  14.             Me.SelectedShape.Resize(hitStatus, e.X - resizeStart.X, e.Y - resizeStart.Y)              
  15.             resizeStart = e.Location
  16.  
  17.          End If
  18.  
  19.       End If
  20.    End If
  21. End Sub


Using this code, I can resize the shapes from every direction.


Now on to the problem... I want to implement a MinimumSize, so that the shape cannot be resized any smaller than that.

Naively, I thought I could simply check, in the Resize method, whether the new bounds were smaller then the minimum, and if they were, I 'reset' them to the minimum. I accomplished that 'cleverly' using the Math.Max method:
vb.net Code:
  1. newBounds.Height = Math.Max(Me.MinimumSize.Height, newBounds.Height)
  2. newBounds.Width = Math.Max(Me.MinimumSize.Width, newBounds.Width)
  3. Me.Bounds = newBounds

But, this does not work properly... Yes, it does keep me from making the shape any smaller, but if I keep 'trying' (by moving the mouse further still), I get some strange behavior. It's a little hard to explain, so I made a little video of it:
http://www.youtube.com/watch?v=gPg8ZK2KJI8

In the first few seconds you can see me dragging + resizing from the bottom right corner, works fine. Then, I hit the minimum size, but I keep moving the mouse upwards (button still held down).
When I then move the mouse back to the bottom-right, the strange behavior occurs: the shape starts resizing even though I'm nowhere near the corner! If you try resizing a control in VS that way, you will see that it only starts to grow bigger again after the mouse has passed the corner.
I think this issue has to do with me resetting the resizeStart field after resizing. Should I only do that if the resize 'succeeded' (did not result in a too small shape), or something..?

Also, after that, I resize the shape from the left side. If I make it bigger, no problems. But then I make it smaller and hit the minimum size. The shape starts moving to the right..! That's obviously not what I had in mind
The reason why this happens is clear to me: newBounds is shifted to the right, while also growing smaller in size (correct). But after the Select Case statement, the size is reset to the minimum size. But, the bounds are still shifted! So I need to shift them back or something...?


Can anyone see how I can solve these issues? Any examples on resizing shapes or anything? I've tried various methods but my first naive (wrong) approach was the best yet... All others resulted in even stranger behavior!