A Rotating Button Component

see source code listing

note: 8-09-2018 I have corrected some errors in this component.

This article describes a rotating button component for the Delphi programming language.
The button position is controlled by mouse movements.
Application may be in the control of simulated laboratory equipment.
Picture below shows some buttons on a form:

The buttons have a 3D effect showing rotation.
A mousedown on a button followed by mouse movement changes the button position.

Button properties

The rotation button component is a descendant of the TGraphicControl class.

Picture above shows the (published) properties that shape a rotating button.

Painting is done on a bitmap, which is created when the button is painted for the first time.
The bitmap is destroyed together with the button component.
After drawing, the bitmap is copied to the button canvas.
This prevents flickering which would result when painting was done directly on the button canvas.

The output position of the button is a number from 0 to 255 (byte).
Because a pixel distance is very small it is not convenient to obtain the button position
directly from the pixel where to mouse is pointing to.
The following (published) properties control the button position:
- pixelratio : the number of pixels that increment or decrement the button position
- maximum : the maximum button position
- position : the current button position
orientation
- orHorizontal : button changed by mouse movement in horizontal direction
- orVertical : button changed by mouse movement in vertical direction

Events

- onChange
- onButtonPaint
- onEnter
- onLeave
onChange
provides the new button position.

onButtonPaint
This event is raised after pianting of the bitmap is finished but before the bitmap
is copied to the button canvas.
So, this event enables modifications to the bitmap such as the display of values.
Read property map to get the bitmap.

onEnter, onLeave
These events occur when the mouse pointer enters or leaves the button.

Program description

Obtaining the 3D effect

Consider a vertically oriented button:

Variable i steps from 0 at point A to the button height at point B.
For each step the angle a is calculated (in radians).
At center C, a = p/2
The arctan( ) function outputs negative values for quadrants 2 and 4.
When passing C downwards (quadrant 2), a has to be incremented by p.

When moving the mouse over the button with the mousebutton pressed
mousemove events provide the (x,y) coordinates of the mouse pointer.
These (x,y) values are compared with previous values and the difference is the number of passed pixels.
Variable pixelcount holds this button movement in pixels.
The button position simply is this pixelcount value divided by property pixelratio.

Button rotation
Before I described the 3D effect, but there is no button rotation, the notches cannot move.
Movement is done by adding the pixelcount to the circle arc (a.radius) before calculating the modulus.

Care must be taken to have the notches move in the mouse direction.
There is a tricky difference between vertical and horizontal oriented buttons.
Please look at the source code for details.

The Delphi project

This project consists of
- form1, unit1 : buttons and code to test the component
- unit dav7rotationbtn which holds the TDav7RotationBtn class.
This concludes the description of this rotating button component