Coming to grips with Purebasic

Everything else that doesn't fall into one of the other PB categories.
superjacent
User
User
Posts: 27
Joined: Mon Oct 01, 2007 1:38 pm
Location: Melbourne, Australia
Contact:

Coming to grips with Purebasic

Post by superjacent »

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.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

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.
oh... and have a nice day.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

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:

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

8)

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! :twisted:

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!!!

8)
Last edited by Rook Zimbabwe on Mon Jun 23, 2008 3:34 pm, edited 1 time in total.
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

There's some stuff on events in the survival guide...

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... )
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

blueznl wrote:file:///F:/data/webpages/nightliv/datatalk/pure4.htm#4_events
lol?
oh... and have a nice day.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

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
( 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... )
byo
Enthusiast
Enthusiast
Posts: 635
Joined: Mon Apr 02, 2007 1:43 am
Location: Brazil

Post by byo »

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.
Proud registered Purebasic user.
Because programming should be fun.
superjacent
User
User
Posts: 27
Joined: Mon Oct 01, 2007 1:38 pm
Location: Melbourne, Australia
Contact:

Post by superjacent »

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.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

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).
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... :D

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! 8)

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! :wink:
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Amiga5k
Enthusiast
Enthusiast
Posts: 329
Joined: Fri Apr 25, 2003 8:57 pm

Post by Amiga5k »

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... :D

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 ***
Post Reply