Cursussen/Courses Codesnippets     Top 
B4A-calendar - Fine tuning


1. Library project
It would be nice if you could use this calendar in many other projects, right?
You can turn the code you have now into a class module and later compile that code into a library. Lets try this.
Create a default B4A project:
Change the application label to calendar_library.
Change the package name to calendar_library (menu Project / Build Configurations).
Create a new Standard Class module and add it to the parent folder.
Name the class Calendar and click on the Calendar tab in the IDE.


2. Code adjustments
Now on to the code.
We are going to use the code from the calendar project.
Copy the code from the subroutines show_month, set_label, set_background and lblday_click below the existing code in the calendar class.
Change the name of the show_month subroutine to set_month_panel. This is a clearer name for what the code does in the subroutine. Also make the subroutine public!
Add an argument pnlsize and set the return type to Panel:
Public Sub set_month_panel(mnth As Int, yr As Int, pnlsize As String) As Panel
	' pnlsize "S" = for a year overview - default = empty string
The subroutine is going to use an internal panel so declare and initialize it (below the boxheight line is good).
Private pnl As Panel
pnl.Initialize("pnl")
pnl.RemoveAllViews
For this to work the panel needs an activity context. Add a declaration for the activity in the Class_Globals subroutine:
Private act As Activity	'ignore
Below the last next statement add the following lines:
pnl.Width = 7 * boxwidth + 1dip
pnl.Height = 8 * boxheight + 1dip
Return pnl
Now you only have to change some code in the set_month_panel for the test of the pnlsize argument (just before the screen adjustments)
If pnlsize = "S" Then	' for a year overview
	Private boxwidth As Int = 24dip
	Private boxheight As Int = 24dip
Else
	' screen adjustments
	…
End If
' date initializations
…
These are all the adjustments to the set_month_panel.


3. Activity code
To test the code sofar you need to add some code to the Main tab in the IDE.
The Activity_Create method is used to get the month of May on the display. In the Globals subroutine you can declare the variables (sv1 and cal). The cal variable is of the type calendar (which is the class we added in the project)!
Sub Globals
	'These global variables will be redeclared each time the activity is created.
	Private sv1 As ScrollView
	Private cal As calendar
End Sub
Sub Activity_Create(FirstTime As Boolean)
	Activity.LoadLayout("Layout")
	sv1.Initialize(2000dip)
	sv1.Panel.RemoveAllViews
	cal.Initialize(Me,"cal")
	Private pnl As Panel
	pnl.Initialize("pnl")
	pnl = cal.set_month_panel(5,2022,"")
	sv1.Panel.AddView(pnl,0dip,0dip,pnl.Width,pnl.Height)
	Activity.AddView(sv1,0dip,0dip,pnl.Width,pnl.Height)
End Sub
The sv1 ScrollView is initialized at a height of 2000dip. You can change this later in the code.
You call the subroutine for the month panel with cal.set_month_panel(mnth, yr, pnlsize). The set_month_panel is a method from the class calendar (variable cal).
Add the month panel to the scrollview and the scrollview to the activity and you should get the month of May displayed. (TIP: use a For loop and you can show a whole year)
Next we need to add some code to use the label click event of a day label.
In the Class_Globals we need some variables:
Private mCallback As Object
Private mEventname As String
Public lblticks As Long
The public subroutine Initialize is used to be able to initialize the calendar object.
Public Sub Initialize(Callback As Object, Eventname As String)
	mCallback = Callback
	mEventname = Eventname
End Sub
And then change the lblday_Click subroutine:
Public Sub lblday_Click
	Dim l As Label = Sender
	lblticks = l.tag
	If xui.SubExists(mCallback,mEventname & "_dayclick",2) Then
		CallSubDelayed(mCallback,mEventname & "_dayclick")
	End If
End Sub
The variable lblticks is declared public and is available in all routines that use the calendar object.
In the Main module you need to provide a subroutine with the name cal_dayclick (make sure the underscore is there!) below the other subroutines:
Public Sub cal_dayclick
	Dim dayticks As Long = cal.lblticks
	Log(dayticks)	' date ticks value
End Sub
Now you can test the project. A click on a daynumber label should show the date ticks value in the log pane.


4. Make library
Now you are ready to make a library from the calendar class.
Click on the calender tab in the IDE. Add 2 lines on top to let the IDE know that there is an event that will be raised.
#Event: dayclick
#RaisesSynchronousEvents: dayclick ... 
You can read more about this in the booklet: B4XCustomViews
Select in the menu Project the entry Compile to Library. Place the file in the AdditionalLibraries folder (see menu Tools / Configure Paths).


5. Test the library
Now you can test the library in a new project.
Don’t forget to include the library in the project (Libraries Manager pane in the IDE).
Private Sub B4XPage_Created (Root1 As B4XView)
	Root = Root1
	Root.LoadLayout("MainPage")
	B4XPages.SetTitle(Me,"Calendar_libtest")
	cal.Initialize(Me,"cal")
	Private pnl As Panel
	pnl.Initialize("pnl")
	pnl = cal.set_month_panel(5,2022,"")
	Root.AddView(pnl,0dip,0dip,pnl.Width,pnl.Height)
End Sub
Public Sub cal_dayclick
	Dim dayticks As Long = cal.lblticks
	Log(dayticks)	' date ticks value
End Sub
For an overview of a year you could call the set_month_panel with the argument pnlsize set to “S”. This will produce a small calendar (see first image in this tutorial).
By calling the set_month_panel subroutine for each month of a specific year and stacking them 2 months in a row in a panel from a scrollview you can get this overview. The height of the scrollview panel is then 6 times the height of the month panel. Give it a try!

An unspecified orientation should also work. Try it!
#Region  Project Attributes 
	'SupportedOrientations possible values: unspecified, landscape or portrait.
	#SupportedOrientations: unspecified
#End Region