KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: Using an invisible button as a speed counter
PRODUCT: 4D | VERSION: 11 | PLATFORM: Mac & Win
Published On: June 18, 2009

A speed counter is a button that can be used to increment a value. The speed counter effectively lets the user get precise values while also being able to jump quickly to large numbers. In this case it is only used to increment a value, but a decrement button could be made just as easily. When the user first clicks the button and holds their mouse button down, the value increments slowly, but the longer they hold the button down the faster it increments. In this way they can jump to a high number very quickly just by holding the mouse button down.

The idea of a "speed counter" requires a button to respond immediately when the mouse button is pressed down over a button. With a speed counter, your variable begins slowly incrementing when you press the mouse button and increments faster the longer the button is down. To handle this, an invisible button to track that initial "mouse down" and the form's On Timer event can be used. Invisible button objects trigger the On click form event as soon as the mouse button goes down, while other buttons do not trigger until the button comes up. The form used for this example is shown here:



The variable on the left is a Real, myVar. The arrow on the right is a picture variable with an invisible button overlaying it. The code for how to acheive the "speed counter" behavior is pretty simple.

Here is the code for the invisible button, note that buttonFlag is a process variable used as a flag for when the button is down:

Case of
 : (Form event=On Clicked )
   buttonFlag:=True
   SET TIMER(10)
 : (Form event=On Mouse Leave )
   SET TIMER(0)
   buttonFlag:=False
   count:=0
End case


In the On Clicked form event the button flag and Form Timer are set. When the user mouses out of the button, then both are turned off, in the On Mouse Leave form event. In the On Mouse Leave form event the count Process variable is also set to zero. We will see from the Form Method that this resets the speed that the count is performed at.

The following code is from the Form Method:

Case of
 : (Form event=On Load )
   C_LONGINT(count)
   C_REAL(myVar)
   C_BOOLEAN(buttonFlag)
   buttonFlag:=False
   count:=0
 : (Form event=On Timer )
   C_LONGINT($x;$y;$MouseState)
   GET MOUSE($x;$y;$MouseState)
   If (($MouseState=1) & (buttonFlag))
      count:=count+1
      myVar:=myVar+0.1
      Case of
       : (count>40)
         SET TIMER(-1)
       : (count>20)
         SET TIMER(2)
       : (count>5)
         SET TIMER(15)
       : (count<5)
         SET TIMER(25)
      End case
   Else
      SET TIMER(0)
      buttonFlag:=False
      count:=0
   End if
End case


The On Load form event is basically only there for declaring and initializing variables. The On Timer form even handles the speed counter. GET MOUSE is used to make sure that the user still has the mouse button down and then the buttonFlag variable is used to make sure that the invisible button has been pressed. If either of these are false then the Timer is reset and the flag and count are reset as well. If both are true then count and myVar are incremented. Based on the amount of times count has been incremented (which is effectively how long the mouse button has been down) the timer can be reset to be faster as the button is down longer.

Commented by Thomas Fitch on June 24, 2009 at 4:06 PM
In his comment Atanas said:

"The smallest the number the sooner the next On Timer event will fire up."

While that is true in general be careful when implementing the idea with SET TIMER; there are two "special" values. Passing -1 forces the Form's On Timer event to run as soon as possible and passing 0 turns off the timer, so On Timer will not run until SET TIMER is called again.
Commented by Atanas Atanassov on June 24, 2009 at 8:23 AM
It is worth to mention that the value in SET TIMER command is the number of ticks between two On Timer form events. The smallest the number the sooner the next On Timer event will fire up.