Coming to grips with Purebasic
-
- User
- Posts: 27
- Joined: Mon Oct 01, 2007 1:38 pm
- Location: Melbourne, Australia
- Contact:
Coming to grips with Purebasic
Okay, I'm coming from a Realbasic background and I'm wanting to clarify a few issues.
Within RB Windows are created and within each window there's a place to write module level code. Code that only belongs to the particular window. Also variables can be created that have module level scope, each function or procedure within the window (module) can access these variables.
Relating the above to Purebasic, how is this done? My initial thoughts are that for each window it's a matter of writing separate code files which contain only the procedures and variables relevant to the particular window. I assume these separate code files would then be included at the beginning of the main start-up code file.
Any links to samples would be appreciated.
Within RB Windows are created and within each window there's a place to write module level code. Code that only belongs to the particular window. Also variables can be created that have module level scope, each function or procedure within the window (module) can access these variables.
Relating the above to Purebasic, how is this done? My initial thoughts are that for each window it's a matter of writing separate code files which contain only the procedures and variables relevant to the particular window. I assume these separate code files would then be included at the beginning of the main start-up code file.
Any links to samples would be appreciated.
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
in PB there is no such thing like seperated modules for multiple windows of one process structure.
have a look here:
http://www.purebasic.fr/english/viewtop ... 030#175030
http://www.purebasic.fr/english/viewtop ... 031#175031
examples to handle multiple windows from within one event-loop.
have a look here:
http://www.purebasic.fr/english/viewtop ... 030#175030
http://www.purebasic.fr/english/viewtop ... 031#175031
examples to handle multiple windows from within one event-loop.
oh... and have a nice day.
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
It is the gadgets on each window that you use. Make gadget names unique per window... Then when the gadget in that window is pressed you do what you need to do in that window...
A simple example:

Seee you can't click on a control that isn't displayed... but you can call one that isn't displayed... if you know the infernal secret!
Let us say I wanted to call the Clear LI_0 button on the first window from the second window, I could... passing parameters to it would be difficult {that means I haven't fully figured this out yet!!} but I could simply add the function call to my program and it would. I could even create a button on the second window that would emulate a press on the first.
If you need to.
This means you do not have to duplicate code. My Restaurant POS program is barely 500k just because of this!!!

A simple example:
Code: Select all
Enumeration
#Window_1
#Window_0
EndEnumeration
Enumeration
#Button_REFILL_LI_1
#Button_OPN1
#Button_CLR_LI_1
#ListIcon_1
#Button_REFILL_LI_0
#Button_OPN2
#Button_CLR_LI_0
#ListIcon_0
EndEnumeration
Structure VisualDesignerGadgets
Gadget.l
EventFunction.l
EndStructure
Global NewList EventProcedures.VisualDesignerGadgets()
; we make a simple neat procedure to fill nonsense into the Listicon gadgets that we can call by button
; and indicate where to act!
Procedure FilltheList(where)
For x = 0 To 12 ; we are going to fill the ListIconGagdet
jerk = Random(3)+3 ; from 3 - 6
For h = 0 To jerk
chrs = Random(25) + 65 ; capital letters of english alphabet
letter$ = Chr(chrs) ; change that random into a character
word$ = word$ + letter$ ; add it to the word
Next
line$ = Str(x)
AddGadgetItem(where, -1, word$) ; throw it on the list indicated
word$ = "" ; simple cleanup
Next
EndProcedure
Procedure Button_REFILL_LI_1_Event(Window, Event, Gadget, Type)
Debug "#Button_REFILL_LI_1"
FilltheList(#ListIcon_1) ; call out LI Fill procedure
EndProcedure
Procedure Button_OPN1_Event(Window, Event, Gadget, Type)
Debug "#Button_OPN1"
HideWindow(#Window_1, 1) ; hide the second window
HideWindow(#Window_0, 0) ; unhide firstsecond
EndProcedure
Procedure Button_CLR_LI_1_Event(Window, Event, Gadget, Type)
Debug "#Button_CLR_LI_1"
ClearGadgetItemList(#ListIcon_1)
EndProcedure
Procedure ListIcon_1_Event(Window, Event, Gadget, Type)
Debug "#ListIcon_1" ; using SELECT CASE this time
Result = GetGadgetState(#ListIcon_1) ; what row clicked on?
Select Result
Case -1
ProcedureReturn -1
Default
Text$ = GetGadgetItemText(#ListIcon_1, Result)
MessageRequester("PICK","You selected: "+text$+Chr(10)+"Please press [OK] and"+Chr(10)+"do something Else!")
Text$ = "" ; simple cleanup
EndSelect
EndProcedure
Procedure Button_REFILL_LI_0_Event(Window, Event, Gadget, Type)
Debug "#Button_REFILL_LI_0"
FilltheList(#ListIcon_0) ; call out LI Fill procedure
EndProcedure
Procedure Button_OPN2_Event(Window, Event, Gadget, Type)
Debug "#Button_OPN2"
HideWindow(#Window_0, 1) ; hide the first window
HideWindow(#Window_1, 0) ; unhide the second
EndProcedure
Procedure Button_CLR_LI_0_Event(Window, Event, Gadget, Type)
Debug "#Button_CLR_LI_0"
ClearGadgetItemList(#ListIcon_0)
EndProcedure
Procedure ListIcon_0_Event(Window, Event, Gadget, Type)
Debug "#ListIcon_0"
; you clicked on something! we can do something here like pop up a message box about what you clicked
Result = GetGadgetState(#ListIcon_0) ; what row was clicked on
If Result = -1
Goto Exit_LI0_Loop ; gonna do this with SELECT CASE next time
ElseIf Result > -1
Text$ = GetGadgetItemText(#ListIcon_0, Result)
MessageRequester("PICK","You selected: "+text$+Chr(10)+"Please press [OK] and"+Chr(10)+"do something Else!")
Text$ = "" ; simple cleanup
EndIf
Exit_LI0_Loop:
; **** just a jump out
EndProcedure
Procedure RegisterGadgetEvent(Gadget, *Function)
If IsGadget(Gadget)
AddElement(EventProcedures())
EventProcedures()\Gadget = Gadget
EventProcedures()\EventFunction = *Function
EndIf
EndProcedure
Procedure CallEventFunction(Window, Event, Gadget, Type)
ForEach EventProcedures()
If EventProcedures()\Gadget = Gadget
CallFunctionFast(EventProcedures()\EventFunction, Window, Event, Gadget, Type)
LastElement(EventProcedures())
EndIf
Next
EndProcedure
Procedure Open_Window_0()
If OpenWindow(#Window_0, 5, 5, 400, 244, "Window 0", #PB_Window_SystemMenu | #PB_Window_TitleBar )
If CreateGadgetList(WindowID(#Window_0))
ListIconGadget(#ListIcon_0, 15, 20, 225, 170, "Column1", 100, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
RegisterGadgetEvent(#ListIcon_0, @ListIcon_0_Event())
ButtonGadget(#Button_CLR_LI_0, 15, 195, 225, 35, "CLEAR LIST 0")
RegisterGadgetEvent(#Button_CLR_LI_0, @Button_CLR_LI_0_Event())
ButtonGadget(#Button_OPN2, 245, 165, 145, 65, "OPEN WINDOW 1")
RegisterGadgetEvent(#Button_OPN2, @Button_OPN2_Event())
ButtonGadget(#Button_REFILL_LI_0, 250, 20, 140, 40, "REFILL")
RegisterGadgetEvent(#Button_REFILL_LI_0, @Button_REFILL_LI_0_Event())
EndIf
EndIf
EndProcedure
Procedure Open_Window_1()
If OpenWindow(#Window_1, 417, 5, 400, 243, "Window 1", #PB_Window_Invisible | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
If CreateGadgetList(WindowID(#Window_1))
ListIconGadget(#ListIcon_1, 160, 15, 225, 170, "Column1", 100, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
RegisterGadgetEvent(#ListIcon_1, @ListIcon_1_Event())
ButtonGadget(#Button_CLR_LI_1, 165, 195, 220, 35, "CLEAR LIST 1")
RegisterGadgetEvent(#Button_CLR_LI_1, @Button_CLR_LI_1_Event())
ButtonGadget(#Button_OPN1, 10, 165, 145, 65, "OPEN WINDOW 0")
RegisterGadgetEvent(#Button_OPN1, @Button_OPN1_Event())
ButtonGadget(#Button_REFILL_LI_1, 10, 20, 140, 40, "REFILL")
RegisterGadgetEvent(#Button_REFILL_LI_1, @Button_REFILL_LI_1_Event())
EndIf
EndIf
EndProcedure
Open_Window_1()
Open_Window_0()
; now that the windows are open... we need to put someht8ing in our lists
FilltheList(#ListIcon_0)
FilltheList(#ListIcon_1)
Repeat
Event = WaitWindowEvent()
Gadget = EventGadget()
Type = EventType()
Window = EventWindow()
Select Event
Case #PB_Event_Gadget
CallEventFunction(Window, Event, Gadget, Type)
EndSelect
Until Event = #PB_Event_CloseWindow
End

Seee you can't click on a control that isn't displayed... but you can call one that isn't displayed... if you know the infernal secret!

Let us say I wanted to call the Clear LI_0 button on the first window from the second window, I could... passing parameters to it would be difficult {that means I haven't fully figured this out yet!!} but I could simply add the function call to my program and it would. I could even create a button on the second window that would emulate a press on the first.
If you need to.
This means you do not have to duplicate code. My Restaurant POS program is barely 500k just because of this!!!

Last edited by Rook Zimbabwe on Mon Jun 23, 2008 3:34 pm, edited 1 time in total.
There's some stuff on events in the survival guide...
http://www.xs4all.nl/~bluez/datatalk/pure4.htm#4_events
http://www.xs4all.nl/~bluez/datatalk/pure4.htm#4_events
Last edited by blueznl on Sun Jun 22, 2008 6:43 pm, edited 1 time in total.
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Fixed. I was updating the bloody thing, and used a local link by accident. Thx. Kaeru.
http://www.xs4all.nl/~bluez/datatalk/pure4.htm#4_events
http://www.xs4all.nl/~bluez/datatalk/pure4.htm#4_events
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
IMHO, as long as all windows belong to your application, you don't need to specify a lot of callbacks just capture the EventGadget() number and it'll work across many different windows.
Of course that you can extend PB's builtin events with your own, by retrieving a gadget (windows) individual messages. But I find myself working real easily by capturing events and using the #PB_EventType_... constants.
But Rook's example is really nice and straight-forward.
Of course that you can extend PB's builtin events with your own, by retrieving a gadget (windows) individual messages. But I find myself working real easily by capturing events and using the #PB_EventType_... constants.
But Rook's example is really nice and straight-forward.
Proud registered Purebasic user.
Because programming should be fun.
Because programming should be fun.
-
- User
- Posts: 27
- Joined: Mon Oct 01, 2007 1:38 pm
- Location: Melbourne, Australia
- Contact:
Thanks all, it gives me something to work with.
I'm seeing similarities with C++ where all the prototypes must be defined prior to the calling of the "main()" program, though in Purebasic's case it's the entire definition of the procedures and functions prior to calling the main loop (or starting window).
Within a PB application that is massive, is it the norm to therefore write up the functions in separate files and simply include those files at the beginning of the main loop. Purely for readability and less clutter.
I'm seeing similarities with C++ where all the prototypes must be defined prior to the calling of the "main()" program, though in Purebasic's case it's the entire definition of the procedures and functions prior to calling the main loop (or starting window).
Within a PB application that is massive, is it the norm to therefore write up the functions in separate files and simply include those files at the beginning of the main loop. Purely for readability and less clutter.
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
Actually that is just me... You can DECLARE those procedures as well at the start and keep them AFTER the main loop, I prefer not to use too many DECLAREs...I'm seeing similarities with C++ where all the prototypes must be defined prior to the calling of the "main()" program, though in Purebasic's case it's the entire definition of the procedures and functions prior to calling the main loop (or starting window).

You aren't locked in to any coding style though... It is BASIC. As long as your code is commented well and easy to understand we can help you with any of it!

I saw "we" I mean some of us... more than others...
and my purpose on this board is to show people what NOT to do!

Also, I believe RealBasic could be called an object oriented language, whereas PB is 95% free of such craziness 
But seriously, PB can do it...but in its own way (and almost always producing smaller and faster code as the result).
It takes some getting used to if you're coming from an OOP background, but in the end I think you'll find that it is well worth it. However, if you are planning on writing very very large programs with several persons sharing code, etc. an OOP language may be the best way to go in many cases, simply because of encapsulation and other weird sounding concepts...
For games, though, there really is only one way to go: Commodore 64 Basic!! (Just kidding)
Russell

But seriously, PB can do it...but in its own way (and almost always producing smaller and faster code as the result).
It takes some getting used to if you're coming from an OOP background, but in the end I think you'll find that it is well worth it. However, if you are planning on writing very very large programs with several persons sharing code, etc. an OOP language may be the best way to go in many cases, simply because of encapsulation and other weird sounding concepts...

For games, though, there really is only one way to go: Commodore 64 Basic!! (Just kidding)

Russell
*** Diapers and politicians need to be changed...for the same reason! ***
*** Make every vote equal: Abolish the Electoral College ***
*** www.au.org ***
*** Make every vote equal: Abolish the Electoral College ***
*** www.au.org ***