It is cross-platform. You define each steps using a list element. An example is included below. It also supports images though it is primarily for displaying text.
Code: Select all
DeclareModule Tour
Structure Screen
Title.s
Description.s
ImageHandle.i
EndStructure
Declare.i Start(List Screens.Screen(), ParentWindowID.i = 0)
EndDeclareModule
Module Tour
Structure State
WindowID.i
CurrentPage.i
TotalPages.i
List Screens.Screen()
TitleGadget.i
DescGadget.i
ImageGadget.i
BtnBack.i
BtnNext.i
ChkDismiss.i
Result.i
EndStructure
Procedure UpdateUI(*State.State)
SelectElement(*State\Screens(), *State\CurrentPage)
SetGadgetText(*State\TitleGadget, *State\Screens()\Title)
SetGadgetText(*State\DescGadget, *State\Screens()\Description)
If *State\Screens()\ImageHandle <> -1 And IsImage(*State\Screens()\ImageHandle)
SetGadgetState(*State\ImageGadget, ImageID(*State\Screens()\ImageHandle))
HideGadget(*State\ImageGadget, #False)
ResizeGadget(*State\DescGadget, 20, 200, 360, 80)
Else
HideGadget(*State\ImageGadget, #True)
ResizeGadget(*State\DescGadget, 20, 90, 360, 200)
EndIf
DisableGadget(*State\BtnBack, Bool(*State\CurrentPage = 0))
If *State\CurrentPage = *State\TotalPages - 1
SetGadgetText(*State\BtnNext, "Finish")
Else
SetGadgetText(*State\BtnNext, "Next")
EndIf
SetWindowTitle(*State\WindowID, "Onboarding Step " + Str(*State\CurrentPage + 1) + " of " + Str(*State\TotalPages))
EndProcedure
Procedure.i Start(List UserScreens.Screen(), ParentWindowID.i = 0)
Protected State.State
CopyList(UserScreens(), State\Screens())
State\TotalPages = ListSize(State\Screens())
If State\TotalPages = 0 : ProcedureReturn #False : EndIf
State\WindowID = OpenWindow(#PB_Any, 0, 0, 400, 380, #Empty$, #PB_Window_ScreenCentered, ParentWindowID)
StickyWindow(State\WindowID, #True)
LoadFont(10, "Arial", 24, #PB_Font_Bold)
State\TitleGadget = TextGadget(#PB_Any, 20, 20, 360, 26, #Empty$, #PB_Text_Center)
SetGadgetFont(State\TitleGadget, FontID(10))
State\ImageGadget = ImageGadget(#PB_Any, WindowWidth(State\WindowID) / 2 - 20, 75, 120, 120, 0)
State\DescGadget = TextGadget(#PB_Any, 20, 210, 360, 200, #Empty$)
State\ChkDismiss = CheckBoxGadget(#PB_Any, 20, 342, 200, 25, "Don't show this again")
State\BtnBack = ButtonGadget(#PB_Any, 210, 340, 80, 30, "Back")
State\BtnNext = ButtonGadget(#PB_Any, 300, 340, 80, 30, "Next")
UpdateUI(@State)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case State\BtnNext
If State\CurrentPage < State\TotalPages - 1
State\CurrentPage + 1
UpdateUI(@State)
Else
State\Result = GetGadgetState(State\ChkDismiss)
If IsFont(10)
FreeFont(10)
EndIf
CloseWindow(State\WindowID)
Break
EndIf
Case State\BtnBack
If State\CurrentPage > 0
State\CurrentPage - 1
UpdateUI(@State)
EndIf
EndSelect
EndSelect
ForEver
ProcedureReturn State\Result
EndProcedure
EndModule
NewList MyTour.Tour::Screen()
; Sample image
Define imgSample = CreateImage(#PB_Any, 120, 120)
StartDrawing(ImageOutput(imgSample))
Box(0,0,120,120, RGB(200, 200, 200))
Circle(60,60,40, RGB(50, 50, 50))
StopDrawing()
AddElement(MyTour())
MyTour()\Title = "Introduction"
MyTour()\Description = "This is step one of your modular tour."
MyTour()\ImageHandle = -1 ; Use -1 for no image
AddElement(MyTour())
MyTour()\Title = "Did You Know?"
MyTour()\Description = "Simply call Tour::Start() and it returns the checkbox result."
MyTour()\ImageHandle = -1
AddElement(MyTour())
MyTour()\Title = "Almost Finished!"
MyTour()\Description = "One more step to go. Check the box below if you want to skip this in the future."
MyTour()\ImageHandle = -1
AddElement(MyTour())
MyTour()\Title = "Ready to Launch!"
MyTour()\Description = "Click 'Finish' to close the tour and start using the application!"
MyTour()\ImageHandle = imgSample
; Capture the user's preference
Define DontShowAgain = Tour::Start(MyTour())
If DontShowAgain
Debug "User wants to skip this in the future. Save this to your config file!"
EndIf
