B4A Class Continuous knob

Hello.
I searched the forum and gave it a long thought (actually closed this -posting- window several times throughout the past weeks) but haven't managed to figure it out.

I'm trying to create a continuous rotary knob. It should return something like 1 when you rotate it to the right and -1 when you do the same, but to the left this time.

Everything I've seen has min-max values. And when you would reach the max value it would reset to the min, thus interrupting the seeking process in a disturbing fashion.

If anybody has a good solution, would you kindly point me in the right direction?

Thank you!
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The attached project should help you get started:

upload_2014-3-9_17-42-3.png
 

Attachments

  • Knob.zip
    10.8 KB · Views: 361

pauleffect

Member
Licensed User
Longtime User
I was just thinking about you, @Informatix.

Specifically, the bitmap plus library.

I'm trying to use Erel's code with bitmap plus. Once I'm satisfied with the outcome, I'll post the results.

Thank you both for your time.
 

Manuel Moreno-Eguilaz

New Member
Licensed User
Longtime User
Hi Erel,

Thank you very much for your attached project.

Is it possible to pass some parameters to the knob object when calling Initialize function?

I would like to limitate the minimum and maximum values in one Knob by passing these values in the creation process of the object.

Thank you. I love B4A.

Manuel
 

DT1111

Member
Licensed User
Longtime User
Hi Erel

Thanks for the Knob example and I have modified the pnl_Touch sub so that the knob will only rotate between 0 and 360 deg.

It worked when I rotate it slowly but when (my guess) I placed my finger close to the center plus various other point of contact combinations, and rotate, the 0 to 360 deg constraint fails.

I don't understand and can you please enlighten. Thanks.

B4X:
Sub pnl_Touch  (viewtag As Object, action As Int, X As Float, Y As Float, motionevent As Object) As Boolean
    If action = 0 Then 'ACTION_DOWN
        startAngle = ATan2(X - radius, Y - radius)
    Else If action = 2 Then 'ACTION_MOVE
        Dim angle As Float = ATan2(X - radius, Y - radius)
        currentAngle = currentAngle - angle + startAngle
        Dim delta As Int = (startAngle - angle) * 180 / cPI
        If delta > 180 Then
            delta = delta - 360
        Else If delta < -180 Then
            delta = delta + 360
        End If
       
        If (currentAngle * 180 / cPI < 0.0) Then
            currentAngle = 0.0
        Else If (currentAngle * 180 / cPI > 360.0) Then
            currentAngle = (360/180) * cPI
        End If
       
        CallSubDelayed2(CallBack, EventName & "_AngleChanged", delta)
        startAngle = angle
        cvs.DrawBitmapRotated(bmp, Null, destRect, currentAngle * 180 / cPI)
        pnl.Invalidate
    End If
    Return True
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
If you are only interested in the current value then you can use this code:
B4X:
Sub pnl_Touch  (viewtag As Object, action As Int, X As Float, Y As Float, motionevent As Object) As Boolean
   If action = 0 Then 'ACTION_DOWN
     startAngle = ATan2(X - radius, Y - radius)
   Else If action = 2 Then 'ACTION_MOVE
     Dim angle As Float = ATan2(X - radius, Y - radius)
     currentAngle = currentAngle - angle + startAngle
     currentAngle = (currentAngle + 2 * cPI) mod (2 * cPI)
     CallSubDelayed2(CallBack, EventName & "_AngleChanged", currentAngle * 180 / cPI)
     startAngle = angle
     cvs.DrawBitmapRotated(bmp, Null, destRect, currentAngle * 180 / cPI)
     pnl.Invalidate
   End If
   Return True
End Sub

The event handler:
B4X:
Sub Knob1_AngleChanged (CurrentAngleDegrees As Double)
   Log(CurrentAngleDegrees)
End Sub
 

DT1111

Member
Licensed User
Longtime User
Hi Erel

That is a neat solution. Actually my attempt is to put a "hard" stop at zero deg (rotating anti-CW) and another one at 360 deg (rotating CW).

At the moment my code above works intermittently. Don't know why.
 

DT1111

Member
Licensed User
Longtime User
Hi Informatix, thanks for the link. It is exactly what I have in mind ie the rotary knob. VERY impressive. Not quite rocket science but close IMHO.

It is not done via Designer and my preference is to use Designer as I have other things built around the knob. I am still interested how the same idea could be done using the above code though. Thanks again.
 
Top