B4A Library [Class]ClsWheel Input wheels

Attached you find a new CLASS ClsWheel.

It allows to display different data input screens with wheels.

What can be done ?
You can define nine different types of Wheel input screens:
  • DATE a date input : year / month / day
    A default value can be defined or Now, the current date.
    The returned value has the current DateFormat.
  • TIME_HM a time input : hour / minute
    A default value can be defined or Now, the current time.
    The returned value has the current TimeFormat.
  • TIME_HMS a time input : hour / minute / second
    A default value can be defined or Now, the current time.
    The returned value has the current TimeFormat.
  • DATE_TIME a date + time input : year / month / day / hour / minute
    A default value can be defined or Now, the current date and time.
    The returned value has the current DateFormat and TimeFormat.
  • CUSTOM a custom input with user defined input values.
    The number of side by side wheels is user defined (max. 5 wheels).
    A default value can be defined.
    A specific separation character can be defined, a blanc character is default.
  • INTEGER positive and negative integers
  • INTEGER_POS only positive integers
  • NUMBER positive and negative numbers
  • NUMBER_POS only positive numbers
Main functions:
Initialize initializes the wheel class Note: the Initialize routine hasone more parameter cContinusScrolling As Boolean (since version 1.3) .
Example :
whlDate.Initialize(Me, Activity, "Enter date", 3, Null, 24, 0, True)
Me = calling module, the current
Activity =
Enter date = title of the input
3 = number of wheels, this number is used only for CUSTOM input types
Null = no input data, set internally
24 = text size
0 = DATE input type
True = continus scrolling

Show show the input wheel(s)
Example :
whlDate.Show(lblSelection, "11/22/2001")
lblSelection = Label which gets the result
11/22/2001 = Default value to preset the wheels

Show2 show the input wheel(s)
Example :
whlCustum.Show2("whlCustom", "")
"whlCustom" = EventName
"" = no default value
The event is called 'Closed'.
The event routine in the calling module, for the example, must be
Sub whlCustom_Closed(Canceled As Boolean, Selection As String)

The width and height are defined by the program according to the font size.

If the width or the height exceed the screen width or height the font size is downscaled.

You can change most of the colors.

Needs the Reflection library.

Bug reports and suggestions are welcome.

I hope that the code is enough self explanatory, but if you want more explanations I can add them.
Anyway the best way to know what can be done is to test it.

PS. There is no logic in the custom input screen just to demonstrate the possibility.

Best regards.


EDIT: 2020.11.25 Version 2.7
Amended warning in line 946: Comparison of Object to other types will fail if exact types do not match.
EDIT: 2015.04.29 Version 2.0
Added a Tag property

EDIT: 2017.06.27 Version 2.6
Replaced DoEvents by Sleep(0)
Needs B4A version 7.00+

EDIT: 2017.03.30 Version 2.5
Amended the wish expressed HERE
Different font sizes for title and wheels.
With long titles, the font size of both, title and wheels, was reduced.
Now only the title font size is reduced.

EDIT: 2017.03.28 Version 2.4
Amended the error reported HERE
Problem with +/- in number wheels

EDIT: 2015.09.22 Version 2.3
Amended the error reported in post #185

EDIT: 2015.05.10 Version 2.2
Amended the variable declaration problem reported in post #175

EDIT: 2015.05.10 Version 2.1
Amended the timer problem reported in post #170

EDIT: 2014.09.09 Version 1.9
Added number wheels INTEGER, INTEGER_POS, NUMBER, NUMBER_POS wheels
Amended day scroll problem reported in post #141

EDIT: 2014.04.21 Version 1.7
Amended OutOfMemory problem reported HERE.

EDIT: 2013.09.15 Version 1.6
Added min MinYear and NumberOfYears properties to adapt the years to select

EDIT: 2013.08.08 Version 1.5
Added StartScroll and EdnScroll events

EDIT: 2013.06.14 Version 1.4
Modified OK event to Closed event post#37
Amended screen color problem post#36
Amendet getSeparationText error post #41

EDIT: 2013.06.12 Version 1.3
Mofied property routines.
Added Show2 for raising an event when clicking the OK button
Added optional continus scrolling

EDIT: 2013.05.28 Version 1.2
Amended the bug reported in post #32

EDIT: 2012.12.15 Version 1.1
Amended the reported bugs.
 

Attachments

  • Time_input.jpg
    Time_input.jpg
    32.9 KB · Views: 2,271
  • Custom_input.jpg
    Custom_input.jpg
    45.3 KB · Views: 2,189
  • ClsWheelV2_5.zip
    19.1 KB · Views: 474
  • ClsWheelV2_7.zip
    19.3 KB · Views: 490
Last edited:

gawie007

Member
Licensed User
Longtime User
Hi Klaus,

B4X:
Public Sub GetSeparationText(txt as String) As String
Return SepText
End Sub

Should it not read:
B4X:
Public Sub GetSeparationText As String
Since it is not receiving a value and only returning a String.

Kind regards
Gavin
 

klaus

Expert
Licensed User
Longtime User
B4X:
Public Sub getSeparationText As String
You are right !
This line was changed in version 1.3 its getSeparationText and not GetSeparationText as before to be considered as a property.

The problem from your post#40 was already amended in version 1.3.
Since version 1.3 a new Show2 routine was introduced to get an event raised when leaving the wheel input panel.
I added also a single column wheel example in version 1.3.

Version 1.4 is now availabel in the first post.

Best regards.
 

gawie007

Member
Licensed User
Longtime User
Hi Klaus,
Thanks for the reply.
I have just this minute started using your "new" class 1.3 - will add 1.4 in a bit.
It has cleared all my issues and works well. I have deleted my Event too since your one works perfectly.
The single whlCustomSingle is also a good example. ;

I did try the get/setSeparationText which you have amended in 1.4.
I only stumbled across this because I thought the single list had added a space to the end of my list item - a few lines of code less for me to worry about now.

Thanks for the fine work!
 

roncoa

Member
Licensed User
Longtime User
Hello, Klaus, your work is very nice, great.
Can you made a sub show3 with the possibility to insert the wheel in any position of the screen?
for example:
show3 (cEventName As String, DefaulValue As String, Left as Int, Top as Int)

Thanks.
 

klaus

Expert
Licensed User
Longtime User
I'm not convinced of the usefulness of such a routine.
For me these wheels work similar to modal dialogs, which means that the user can only select data and nothing else.

But you can add this routine in the class :
B4X:
'Show the wheel panel
'cEventName = EventName for the _Closed event
'DefaultValue = the wheels will be set to this value
'Enter "" for now (for DATE, TIME_HM. TIME_HMS and DATE_TIME
'Left = left coordinate
'Top = top coordinate
'Example:
'<code>TimeHMWheel.Show3 ("TimeHMWheel", "", 10dip, 30dip)</code>
Public Sub Show3(cEventName As String, DefaulValue As String, Left As Int, Top As Int)
    
    Left = Min(Left, 100%x - pnlMain.Width)
    Top = Min(Top, 100%y - pnlMain.Height)
    pnlMain.Left = Left
    pnlMain.Top = Top
    
    EventName = cEventName
    
    If SubExists(Callback, EventName & "_Closed") = False Then
        ToastMessageShow("There is no " & EventName & "_Closed", False)
        Return
    End If
    
    EventEnabled = True

    InitDefaultValues(DefaulValue)
End Sub
The routine limits the left and top values to ensure that the dialog remains on the screen.

Best regards.
 

gawie007

Member
Licensed User
Longtime User
Hi Klaus,
When I enter the following:
B4X:
   Dim NumberArrayList(3) As List
   NumberArrayList(0).Initialize
   NumberArrayList(1).Initialize
   NumberArrayList(2).Initialize
   
   For i = 0 To 9
      NumberArrayList(0).Add(i)
      NumberArrayList(1).Add(i)
      NumberArrayList(2).Add(i)
   Next
   
   whlThreeNumbers.Initialize(Me, Activity,"Enter duration (0-999s)", 3,NumberArrayList, 30, 4, True)

   'Change from default colours
   whlThreeNumbers.BackgroundColor = Colors.Black
   whlThreeNumbers.WindowLineColor = Colors.Black
   whlThreeNumbers.WindowColor = Colors.Gray

   whlThreeNumbers.setSeparationText("")
   
   whlThreeNumbers.Show2("whlThreeNumbers","555")
I do not get the wheels set to 555.

In your Class on line 380
B4X:
   Txt = Regex.Split(SepText, DefaulValue)
Txt results in an array: Txt[0=,1=5,2=5,3=5]
it appears to be one out for some reason.

I tested the following:
B4X:
   Dim txt(3) As String
   txt = Regex.Split("","555")
   txt = Regex.Split(" ","5 5 5")
   txt = Regex.Split(",","1,2,3")
The first txt reproduced the result above and the last two worked as expected.
Even though the last two worked, they still did not set the wheels to the correct positions.

I hope this is of use.
Kind regards
Gavin
 
Last edited:

klaus

Expert
Licensed User
Longtime User
I have never thought of using the Custom wheels to enter numbers.
Nor using "" as separation text.

I tested your example and there are two problems:
- Regex.Split("", "555") gives as you pointed out 0, 5, 5, 5
- The wheels are not set to the default value. This is due to the fact that you define for the wheel contents values of type Int, 5 in your example. After Regex.Split the program is looking for String variables "5" and doesn't find them because the wheel content lists can store every type.

I modified your code like this
B4X:
For i = 0 To 9
     Dim ii As String
     ii = i
     NumberArrayList(0).Add(ii)
     NumberArrayList(1).Add(ii)
     NumberArrayList(2).Add(ii)
Next
with " " as the separation text and it works as expected.

I think that it would be more efficient to define a new input wheel type for numbers instead of adapting the Custom type.

If you really need it I can add it.

Best regards.
 

gawie007

Member
Licensed User
Longtime User
Hi Klaus,

I have always wanted this type of class - which I thank you for!
My HTC Desire has it as standard and they are slick.
A nice feature the Desire has when setting the time is that if you flick the minutes fast, it will stop at 15 minute intervals
eg: Start:0, flick down: 15, flick down: 30, flick down: 45, flick up:30.
Slower scrolling moves as normal.
Your Class will overtake the numberDialog guaranteed.
+/- to change numbers - too awkward compared to this great class!

Anyway, I am posting my modification to your code.
I have not made sure that it is bulletproof but it works (after going down many wrong avenues).

I just added an Else If section that checks whether DefaulValue can be a number.
It may not be perfect but it works for me.
B4X:
   Case CUSTOM
      If DefaulValue = "" Then
         For i = 0 To WheelNb - 1
            ScrollPos(i) = lblHeight * WheelContentNb(i)
         Next
      Else If IsNumber(DefaulValue) Then   '*************************************************************************************
         Dim Txt(WheelNb) As String
         If DefaulValue.Contains(SepText) = True OR WheelNb = 1 Then
            If WheelNb = 1 Then
               ScrollPos(0) = lblHeight *(WheelContent(0).IndexOf(DefaulValue) + WheelContentNb(i))
            Else
               For i = 0 To WheelNb - 1
                  Txt(i) = DefaulValue.SubString2(i, i+1)
               Next
               For i = 0 To WheelNb - 1
                  Dim matchFound As Int
                  Dim intWheelContent, intTxt As Int
                  
                  For matchFound = 0 To WheelContent(i).Size-1
                     intWheelContent = WheelContent(i).Get(matchFound)
                     intTxt = Txt(i)
                     
                     If intWheelContent = intTxt Then
                        Exit
                     End If
                  Next
                  ScrollPos(i) = lblHeight *(matchFound + WheelContentNb(i))
               Next
            End If
         End If
      Else   '*****************************************************************************************************************
         Dim Txt(WheelNb) As String
         If DefaulValue.Contains(SepText) = True OR WheelNb = 1 Then
            If WheelNb = 1 Then
               ScrollPos(0) = lblHeight *(WheelContent(0).IndexOf(DefaulValue) + WheelContentNb(i))
            Else
               Txt = Regex.Split(SepText, DefaulValue)
               For i = 0 To WheelNb - 1
                  ScrollPos(i) = lblHeight *(WheelContent(i).IndexOf(Txt(i)) + WheelContentNb(i))
               Next
            End If
         Else
            ToastMessageShow("Wrong separation text !", False)
            For i = 0 To WheelNb - 1
               ScrollPos(i) = WheelContentNb(i)
            Next
         End If
      End If
   End Select

My example when using this is:
B4X:
   Dim NumberArrayList(3) As List
   NumberArrayList(0).Initialize
   NumberArrayList(1).Initialize
   NumberArrayList(2).Initialize
   
   For i = 0 To 9
      NumberArrayList(0).Add(i)
      NumberArrayList(1).Add(i)
      NumberArrayList(2).Add(i)
   Next
   
   whlThreeNumbers.Initialize(Me, Activity,"Enter duration (0-999s)", 3,NumberArrayList, 30, 4, True)

   whlThreeNumbers.setSeparationText("")
   
   whlThreeNumbers.Show2("whlThreeNumbers","123")

Please note that when using numbers, set setSeparationText to .setSeparationText("") as it will only work when entered like this!

e.g.: .setSeparationText(" ") or .setSeparationText(",") or .setSeparationText(".") will fail.
 
Last edited:

ilan

Expert
Licensed User
Longtime User
really great klaus !!!

looks very nice !!

i want to call a sub after i press the ok button how can i do it?

thanx

EDIT: i allready got it thank you
 
Last edited:

margret

Well-Known Member
Licensed User
Longtime User
Is there an option to have the wheels stay on the screen all the time without the buttons and then to send updated values of an interactive change. I have a project where I would like to use the wheels and as they are changed, calculations are made from the interactive change and the information can then be updated to the screen. I do not need the OK or Cancel buttons.
 

alienhunter

Active Member
Licensed User
Longtime User
Hi Klaus ,

question why is the custom wheel limited at 5 wheels ? is there a reason just want to understand why
thanks AH
 

ilan

Expert
Licensed User
Longtime User
modify the class

in Private Sub btnOK_Click and in Private Sub btnCancek_Click

remove pnlscreen.visible = false

B4X:
Private Sub btnCancel_Click
    If EventEnabled = True Then
        If SubExists(Callback, EventName & "_Closed") = True Then
            CallSub3(Callback, EventName & "_Closed", True, getSelection)
        End If
    End If
    'pnlScreen.Visible = False 'remove this
End Sub

Private Sub btnOK_Click
    If EventEnabled = True Then
        If SubExists(Callback,  EventName & "_Closed") = True Then
            CallSub3(Callback, EventName & "_Closed", False, getSelection)
        End If
    Else
        If CallbackView <> "" Then
            Dim lbl As Label
            lbl = CallbackView
            lbl.Text = getSelection
        End If
    End If
    'pnlScreen.Visible = False 'remove this
  
End Sub
 

klaus

Expert
Licensed User
Longtime User
In the Show routine you can transmit preset values that positions the wheels at the given values.
I found it more efficient to transmit a preset value, which means the current content of the returning view, rather than a preset index.

Best regards.
 
Top