Page 1 of 1

Simple drawing selection shape (or rubberband shape) Rate Topic: -----

#1 modi123_1  Icon User is offline

  • Suitor #2
  • member icon



Reputation: 12822
  • View blog
  • Posts: 50,623
  • Joined: 12-June 08

Post icon  Posted 29 July 2008 - 03:28 PM

Background:
Someone in the forum was looking on how to make an elipse track a mouse click and hold, until release. This user called it 'rubberband' shape, but I knew it as the 'dashed select tool' common to MS Paint or any other graphics program. I took two minutes out of my life to build a demo program for the user, but it seems they came to his-or-her's own solution. Instead of pitching the program I'll offer it up to everyone to use.

Outline
The concept is pretty simple, and happens in a few steps.
1. The user clicks down the mouse button (in this case ANY mouse button). (mouse down)
1.a. This location is saved in a variable to be used as our top left corner for the ellipse.
2. User drags the mouse (while button is still down).
2.a The shape tracks with the mouse's movement through the _pNow object.
3. User releases the mouse button (mouse up).
3.a This location is saved in a variable to calculate and show the final static (not tracking the mouse pointer anymore) shape.

Bonus
I left the 'drawrectangle' code in the paint method to show how flexible this can be.

Notes
Side note, the "invalidate" call forces the control to repaint itself (hence why most of the action is going on in the form's paint method).

How to Use
To run this code, create a new windows form application. In the form automatically provided - dump this code.

Public Class Form1
	Private _bRubberBandingOn As Boolean = False '-- State to control if we are drawing the rubber banding object
	Private _pClickStart As New Point '-- The place where the mouse button went 'down'.
	Private _pClickStop As New Point '-- The place where the mouse button went 'up'.
	Private _pNow As New Point '-- Holds the current mouse location to make the shape appear to follow the mouse cursor.

	Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
		'-- 1.0  Flip the state.
		Me._bRubberBandingOn = Not _bRubberBandingOn

		'-- 2.0 if the state is on
		If Me._bRubberBandingOn Then
			'-- 2.1 make sure the object exists (create if not)
			If _pClickStart = Nothing Then _pClickStart = New Point

			'-- 2.2 Save the mouse's start postition
			_pClickStart.X = e.X
			_pClickStart.Y = e.Y
			'-- 2.3 Save the current location for the immediate drawing
			_pNow.X = e.X
			_pNow.Y = e.Y
		End If
		'-- 3.0 Invalidate and for the paint method to be called.
		Me.Invalidate()
	End Sub

	Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
		'-- 1.0 If the rubber banding is on, set the current location, and force the redraw.
		If Me._bRubberBandingOn Then
			'-- 1.1 make sure the object exists (create if not)
			If _pNow = Nothing Then _pNow = New Point
			'-- 1.2 Save the current location for the immediate drawing
			Me._pNow.X = e.X
			Me._pNow.Y = e.Y
			'-- 1.3 Invalidate and for the paint method to be called.
			Me.Invalidate()
		End If
	End Sub

	Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
		'-- 1.0  Flip the state.
		Me._bRubberBandingOn = Not Me._bRubberBandingOn
		'-- 2.0 if the state is off
		If Not Me._bRubberBandingOn Then
			'-- 2.1 make sure the object exists (create if not)
			If _pClickStop = Nothing Then _pClickStop = New Point
			'-- 2.2 Save the mouse's stop postition
			_pClickStop.X = e.X
			_pClickStop.Y = e.Y
			'-- 2.3 Invalidate and for the paint method to be called.
			Me.Invalidate()
		End If
	End Sub

	Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
		'-- 1.0 The rectangle used by .NET to get the draw area
		Dim _rRectangle As New Rectangle
		'-- 2.0 The pen.  You can change the color or pixel width to your heart's content
		Dim _penNew As New Pen(Color.Black, 3)
		'-- 3.0 Set the rectangle's top left x/y to the click location.
		_rRectangle.X = _pClickStart.X
		_rRectangle.Y = _pClickStart.Y
		'-- 4.0  If the state is on...
		If Me._bRubberBandingOn Then
			'-- 4.1 Set the rectangle's  width using the 'now' mouse location just set in the 'Form1_MouseMove' event
			_rRectangle.Width = Me._pNow.X - _pClickStart.X
			_rRectangle.Height = Me._pNow.Y - _pClickStart.Y
		Else '-- else if we are done having the shape follow the mouse
			'-- 4.2 Set the rectangle's  width using the 'stop' mouse location just set in the 'Form1_MouseUp' event
			_rRectangle.Width = Me._pClickStop.X - _pClickStart.X
			_rRectangle.Height = Me._pClickStop.Y - _pClickStart.Y

		End If
		'-- 5.0  Let's be cheeky and make it a dashed style
		_penNew.DashStyle = Drawing2D.DashStyle.Dash
		'-- 6.0 Draw the elipse
		e.Graphics.DrawEllipse(_penNew, _rRectangle)
		'-- 7.0 Notice the rectangle is the same thing!
		'-- e.Graphics.DrawRectangle(_penNew, _rRectangle)
	End Sub
End Class


Is This A Good Question/Topic? 4
  • +

Page 1 of 1