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,279
  • Custom_input.jpg
    Custom_input.jpg
    45.3 KB · Views: 2,196
  • ClsWheelV2_5.zip
    19.1 KB · Views: 477
  • ClsWheelV2_7.zip
    19.3 KB · Views: 496
Last edited:

klaus

Expert
Licensed User
Longtime User
@rboeck,
Are you speaking about derezs' Wheel library or about the ClsWheel class from this thread.

In the ClsWheel class both solutions are possible, but need some modifications in the class.
The second solution is not that easy, having a longclick event in the main code wouldn't be a good solution it would be better to modify the class code.
The longclick event must be treated in the Touch routine of the year ScrollView you cannot have a LongClick event for a ScrollView.
Then you need to change the content of the year ScrollView and after a selection you must set it back to the original content.
I'm not sure that selecting the decennium and then selecting the correct year is faster than scrolling over a hundred years.

Best regards.
 

Harris

Expert
Licensed User
Longtime User
@Harris,
I'm afraid that this is an error in the DateTime.TimeFormat function because it works for most time zones and there is one hour difference for some time zones like Greenwich time.

Date and Time seem to cause the most issues (it seems to me). Overall, on a scale of 1 to 100, we are 99% bug free which is real accomplishment.

I do, on too many occasions run into odd "behavior" in my code. For example, a checkbox hides and unhides a panel. The second time of unhiding this panel, the following sub gets fired:

B4X:
Sub EditText2_FocusChanged (HasFocus As Boolean)
   If HasFocus = True Then
          Msgbox(" focus","")

      whlTimeHM.Show(EditText2, "")
   End If
End Sub

Once I cancel the wheel view, it will never behave this way again (until I restart the app). Odd indeed.

Thanks for your expert response. :sign0188:
 

klaus

Expert
Licensed User
Longtime User
1) Problem with the checkbox hiding a panel.
I remember having had a problem similar to yours with Basic4PPC.
The problem is probably when you hide the panel and there is a view on it that has the focus it's focus is tranfered to the next view in the OS list (depends on the order you add the views). In your case the focus is transfered to EditText2. Try to remove it and add it again or better use a Label or if you really want an EditText the solution below.

2) Problem when you quit the wheel, it doesn't matter if it's with OK or Cancel, the EditText keeps the focus. So when you click again on it there is no FocusChange and no FocusChanged event is raised.
As a workaround you could add a Touch event to the EditText with the Reflection library.
B4X:
Dim obj As Reflector
obj.Target = EditText2
obj.SetOnTouchListener("EditText2_Touch")
'
'
'
Sub EditText2_Touch(viewtag As Object, action As Int, X As Float, Y As Float, motionevent As Object) As Boolean
    If action = Activity.ACTION_DOWN Then
        whlTimeHM.Show(EditText2, EditText2.Text)
    End If
    Return True
End Sub
If you return True EditText2 doesn't get the focus ('consumes' the event).
If you return False EditText2 gets the focus (the event is sent back to the OS).
Don't add a Click event because if the EditText doesn't have the focus you need a first click to set the focus and only the second click raises the Click event.

But anyway it's better to use Labels instead of EditTexts because the user is not supposed to modify the content with the keyboard.
I showed that it works also with EditTexts but didn't test it as far as you did.

Best regards.
 

Harris

Expert
Licensed User
Longtime User
But anyway it's better to use Labels instead of EditTexts because the user is not supposed to modify the content with the keyboard.
I showed that it works also with EditTexts but didn't test it as far as you did.

Thanks Klaus,

It does work much better with labels... no odd behavior.
I can see where the edittext may gain focus when the panel is made visible - causing the focus change to get fired.
 

gjoisa

Active Member
Licensed User
Longtime User
continuous wheels

I loved this class . I was in search since a long time for this type of lib(Class) . Is it possible to have continuous wheel like ios date wheel ? i.e . date should not stop on 31 or 30 . after 31 is reached 1,2,3 should appear .:sign0098:
 

melamoud

Active Member
Licensed User
Longtime User
feature request

Klaus, hi

great class, the only minor thing I would love if you can add, (I added it to my copy) is the ability to get callback (event) at the end,
the whole thing with the Label does not work for me,
I want to call show and get called on event when the user press ok

I added an event name in the initialize sub, and this line at the end of the btnOK_Click sub

CallSub2 (Callback,eventName,GetSelection)

maybe another small thing, is instead of passing default value with the seperation text etc, it will be easier to pass an array of values

just my 2 cents

thanks for a great class!
 

maleche

Active Member
Licensed User
Longtime User
Is there a method to have the "wheels" roll over from the beginning? I'm attempting to build an vehicle Odometer.
Thanks!
 

padvou

Active Member
Licensed User
Longtime User
Is it possible to show two of them wheels side by side?
 
Last edited:

klaus

Expert
Licensed User
Longtime User
No and yes.

No, you cannot put two wheel panels side by side.
But feel free to modify the class to fit your requirements.

Yes, you can define custum wheel panels with sevreral wheels side by side, like the custom wheel in the example code.

Best regards.
 

Uitenhage

Member
Licensed User
Longtime User
Custom wheels only returns 2 results

I added this great class to my project with 3 wheels and only got the first 2 wheel's selections returned.

In clsWheels Sub GetSelection I replaced

B4X:
   Case CUSTOM
      Selection = Sel(0) & SepText & Sel(1)

with:
B4X:
   Case CUSTOM
      'Selection = Sel(0) & SepText & Sel(1)
      Dim i As Int
      For i = 0 To WheelNb - 1
         Selection = Selection & Sel(i) & SepText
      Next
      Selection = Selection.SubString2(0, Selection.Length - SepText.Length)

:sign0089:
 

gawie007

Member
Licensed User
Longtime User
Hi Klaus,

Thank you for a brilliant Class!
It was just what I needed.

I have also used it to use a single list with the class. (This is in case someone else also would like to use it as a single item list)
After trying to modify your code, I have set it back to how it was and managed to do it this way:

B4X:
Sub InitWheelData
'The class expects an array of lists, so send it an array dimmed to 1: lstDay(1)
Dim lstDay(1) As List
lstDay(0).Initialize

'For demo purposes:
lstDay(0).Add("Mon")
lstDay(0).Add("Wed")
lstDay(0).Add("Fri")

whlDay.Initialize(Me, Activity, "Delivery Day", 1, lstDay, 24, 4)
End Sub

This may be apparent to most of you but hopefully I can help some people save a bit of time.

Cheers

Gavin
 

drachmad

Member
Licensed User
Longtime User
Thanks for a great class, I like it.
But since version 1.2 it seem there is a bug.

If the button is click for the first time, not all of the screen is dimmed. But the second time it is fine.
It is more easier to look at it if back ground is set to white.
Designer -> Activity -> Color -> White
It should be in the pnlScreen but I can not find the reason.
A screen capture is attached.
 

Attachments

  • ClsWheel.png
    ClsWheel.png
    9.2 KB · Views: 272

drachmad

Member
Licensed User
Longtime User
Before you change in V1.3, I got an idea from Erel AnotherDatePicker v.1.1
to change your class into:

Public Sub Initialize(Target As Object, EventName As String, Parent As Activity, cTitle As String, cWheelNb As Int, cWheelContent() As List, cFontSize As Float, cWheelType As Int) As Boolean
mTarget = Target
mEventName = EventName

Private Sub btnCancel_Click
CallSub3(mTarget, mEventName & "_Closed", True, GetSelection)
holder.RemoveView
End Sub

Private Sub btnOK_Click
CallSub3(mTarget, mEventName & "_Closed", False, GetSelection)
holder.RemoveView
End Sub

--------------------

Dim whlTimeHM As ClsWheel
whlTimeHM.Initialize(Me, "Time", Activity, "T i m e", 2, Null, 30, 1)

Sub Time_Closed (Cancelled As Boolean, Selection As String)
If Cancelled Then
...
else
...
end if
End Sub

I think Erel idea is more flexible for the user, Canceled or Ok is up to the user to respond.
BTW, I have checked, if only "pnlScreen.Visible = False" the panel count in the main activity is increase every time. Don't you think it is better to .RemoveView?
 

klaus

Expert
Licensed User
Longtime User
The problem of the wrong color will be solved with a DoEvents just after adding pnlScreen. It seems that Android takes, for big screens, too much time to fill the panel with the color before the next statements.

Concerning the Closed event I will change it.

I have checked, if only "pnlScreen.Visible = False" the panel count in the main activity is increase every time.
No, because you should Initialize a given wheel type only once and then use Show or Show2.
However it is increased for each different wheel type.
I was already thinking about this because with 7 different wheel types I got Out of Memory messages when testing some other features.
But this needs some more testing.

Best regards.
 

drachmad

Member
Licensed User
Longtime User
Thanks Klaus, you are right about the doevents and the increasing panel.
I put the initialize at the click because it is not the main process in my application. I thought it can reduce the memory and time.
Thanks again for the great class dan support.
 

gawie007

Member
Licensed User
Longtime User
Hi Klaus,

I have not yet downloaded your updated class.

I am using the CUSTOM wheel.

I add a list of strings for the options for example: Opt A Opt B, Opt C.

If I enter
whlOpt.Show(lblWheelValue, "Opt B")
Opt A is selected(first item on wheel) and not Opt B or whatever value I set it to.

The only thing I am doing differently is:
Dim lblWheelValue as label in Globals,
and
If FirstTime - lblWheelValue.Initialize("lblWheelValue") in Activity Create
i.e. I do not use panel.addview or add it in the designer.
The event I raise saves the selected value.
I am only doing this because the show method requires lblWheelValue.


This may be because I am using one list and it is looking for a minimum of two with SepText??

Thanks for a great class!
 
Last edited:
Top