Page 1 of 1

Gadget Arrays

Posted: Thu Jan 21, 2021 12:15 am
by eck49
Is it simple to have an array/list/map of gadgets?

How could you set up, let's say, a bank of buttons or text gadgets if you don't know at compile time how many you will need?

Can you have a loop like this:

ForEach GadgetList()
set some properties, test others
Next

Or code like this

SetGadgetText(GadgetArray(3),"This is three")

Just a design possibility at present. Not even at pseudo-code stage!

Re: Gadget Arrays

Posted: Thu Jan 21, 2021 12:42 am
by mk-soft

Re: Gadget Arrays

Posted: Thu Jan 21, 2021 5:03 am
by firace
No need for explicitly creating an array - A simple example:

Code: Select all


OpenWindow(0, 260, 24, 500, 300, "Test")

userchoice  = val(InputRequester("", "How many boxes do you want (5-28)?", "5"))

if userchoice < 5 or userchoice > 28 : end : endif 

For x = 0 To userchoice -1   
  ;; the number of CheckBoxGadgets is determined at runtime
  CheckBoxGadget(x, 23 + (x/7 * 120 ), 13+ Mod(x,7)*20 ,100, 22, str(x)) 
Next  

Repeat : Until WaitWindowEvent() = 13116


Re: Gadget Arrays

Posted: Thu Jan 21, 2021 6:13 pm
by eck49
Thank you both.

Creating them in a loop, yes.
Looking at the gadget list and checking the type of each, yes.

But it's messy if the associated gadgets are not all created at the same time, and others of the same type are created in between.
Is there a better way than having a separate list of gadget numbers to keep track of them?

Re: Gadget Arrays

Posted: Fri Jan 22, 2021 12:40 am
by RNBW
The following code produces a grid of StringGadgets:

Code: Select all

;produces a multiple column of Stringgadgets

#WindowWidth  = 840
#WindowHeight = 350
#gWidth = 100
#gHeight = 25

noRows.i  = Val(InputRequester("", "How many rows do you want (2-8)?", ""))
noCols.i = Val(InputRequester("", "How many columns do you want (2-8)?", ""))

If OpenWindow(0, 100, 200, #WindowWidth, #WindowHeight, "PureBasic - Gadget Demonstration", #PB_Window_MinimizeGadget)
  For row=0 To noRows -1
    For col = 0 To noCols -1
      StringGadget(row*8+col, 20 + col*100, 10 + row*24, #gWidth+1, #gHeight+1, "")
    Next
  Next
 
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow Or Quit = #True
 
EndIf

Re: Gadget Arrays

Posted: Fri Jan 22, 2021 12:41 am
by TI-994A
eck49 wrote:Is it simple to have an array/list/map of gadgets?

How could you set up, let's say, a bank of buttons or text gadgets if you don't know at compile time how many you will need?
Yes, it is quite simple. Like so:

Code: Select all

; dynamic gadgets (simple POC)

Global Dim textGadgets(0)
Global Dim buttonGadgets(0)

Procedure createGadgets(gadgetType, number)  
  Select gadgetType      
      
    Case #PB_GadgetType_Text
      
      If number > 0
        ReDim textGadgets(number - 1)
        x = 20 : y = 20
        For i = 0 To (number - 1)
          textGadgets(i) = TextGadget(#PB_Any, x, y, 540, 30, "Text #" + Str(i + 1), #PB_Text_Border)
          y + 40          
        Next i
      EndIf      
      
    Case #PB_GadgetType_Button
      
      If number > 0
        ReDim buttonGadgets(number - 1)
        x = 20 : y = 230
        For i = 0 To (number - 1)
          buttonGadgets(i) = ButtonGadget(#PB_Any, x, y, 100, 40, "Button #" + Str(i + 1))
          x + 110          
        Next i        
      EndIf      
      
  EndSelect  
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
mainWindow = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 600, 350, "Dynamic Gadgets", wFlags)
addGadgets = ButtonGadget(#PB_Any, 20, 280, 560, 50, "Create More Gadgets")

createGadgets(#PB_GadgetType_Text, 2)
createGadgets(#PB_GadgetType_Button, 3)

Repeat
  Select WaitWindowEvent()      
      
    Case #PB_Event_CloseWindow
      appQuit = #True 
      
    Case #PB_Event_Gadget
      Select EventGadget()      
          
        Case addGadgets   
          
          For i = 0 To ArraySize(textGadgets())
            If IsGadget(textGadgets(i))
              FreeGadget(textGadgets(i))
            EndIf            
          Next i
          
          For i = 0 To ArraySize(buttonGadgets())
            If IsGadget(buttonGadgets(i))
              FreeGadget(buttonGadgets(i))
            EndIf
          Next i
          
          createGadgets(#PB_GadgetType_Text, 5)
          createGadgets(#PB_GadgetType_Button, 5)
          
        Case buttonGadgets(0) To buttonGadgets(ArraySize(buttonGadgets()))       
          
          For i = 0 To ArraySize(buttonGadgets())
            If EventGadget() = buttonGadgets(i)
              DisableGadget(buttonGadgets(i), #True)
              If i <= ArraySize(textGadgets()) 
                If IsGadget(textGadgets(i))
                  SetGadgetText(textGadgets(i), "Button #" + Str(i + 1) + " was clicked!")
                EndIf              
              EndIf              
            EndIf
          Next i        
          
      EndSelect  
      
  EndSelect      
Until appQuit
Bear in mind that sizing and positioning of these dynamic gadgets require proper handling as well.

Re: Gadget Arrays

Posted: Fri Jan 22, 2021 12:53 am
by Kiffi
Here's the Dialog-Version (including correct resizing an eventhandling):

Code: Select all

EnableExplicit

#Dialog = 0
#Xml = 0

Define XML$
Define Counter

Runtime Procedure ButtonEvent()
  
  Debug GetGadgetText(EventGadget())
  
EndProcedure

XML$ = "<window id='#PB_Any' name='test' text='test' minwidth='300' minheight='300' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
       "  <gridbox columns='3' rowexpand='yes'>"

For Counter = 1 To 9
  XML$ + "<button name='Button" + Counter + "' text='Button " + Counter + "' onevent = 'ButtonEvent()' />"
Next

XML$ + "  </gridbox>" +
       "</window>"

If ParseXML(#Xml, XML$) And XMLStatus(#Xml) = #PB_XML_Success
  
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
    
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
    
  Else  
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf

Re: Gadget Arrays

Posted: Mon Feb 22, 2021 2:55 pm
by eck49
Thank you all, it is good to have spectrum of approaches, to suit different circumstances.

I'm particularly taken with the idea of having a grid of gadgets with the gadget numbers composed from the grid coordinates. This would make referring to a particular one very transparent - although you would have avoid accidental clashes with unrelated gadgets.

Re: Gadget Arrays

Posted: Mon Feb 22, 2021 3:15 pm
by skywalk
If your gui is complex, it is better to keep the gadgets in some data structure(map,structured array,etc) to be able to cycle through them programmatically. I find #PB_Any is helpful in gadget creation. But for simple gui's, hardcoding the gadget # in an enumeration is straight to the point.