Disappearing gadgets

Just starting out? Need help? Post your questions and find answers here.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Disappearing gadgets

Post by Foz »

As a new user, expect some silly questions that I can't find an answer to by searching the forums. :)

I'm attempting to get a feel with handling the gui, so I'm trying out different things, however something that has stumped me is a disappearing gui when I dynamically add controls.

Here's what I have:

Code: Select all

EnableExplicit

Enumeration
  #Window_Main
EndEnumeration

Enumeration
  #ScrollArea_0
  #Hyperlink_Test
EndEnumeration

Procedure Open_Window_Main()
  If OpenWindow(#Window_Main, 0, 0, 640, 480, "Central",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateGadgetList(WindowID(#Window_Main))
      HyperLinkGadget(#Hyperlink_Test, 20, 20, 80, 30, "Test", RGB(0, 0, 0))
      
      ScrollAreaGadget(#ScrollArea_0, 120, 10, 520, 460, 640, 480, 20, #PB_ScrollArea_Single)
      CloseGadgetList()
    EndIf
  EndIf
EndProcedure

Procedure HelloWorld()
  Enumeration
    #btnHelloWorld
    #btnQuit
  EndEnumeration

  OpenGadgetList(#ScrollArea_0)
    ButtonGadget(#btnHelloWorld, 50, 50, 80, 40, "Hello World")
    ButtonGadget(#btnQuit, 0, 0, 80, 30, "Quit")
  CloseGadgetList()
  
  Protected Event 
  Protected WindowID 
  Protected GadgetID 
  Protected EventType 
  
  Repeat ; Start of the event loop
    
    Event = WaitWindowEvent() ; This line waits until an event is received from Windows
    WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
    GadgetID = EventGadget() ; Is it a gadget event?
    EventType = EventType() ; The event type
    
    If Event = #PB_Event_Gadget
      If GadgetID = 0
        MessageRequester("Test", "Hello World", #PB_MessageRequester_Ok)
      EndIf
    EndIf
    
  Until Event = #PB_Event_CloseWindow Or Event = #PB_Event_Gadget And GadgetID = #btnQuit ; End of the event loop
  
  If Event = #PB_Event_CloseWindow
    End
  EndIf 
  
  FreeGadget(#btnHelloWorld)
  FreeGadget(#btnQuit)
EndProcedure

Procedure Main()
  Open_Window_Main()
  
  Protected Event 
  Protected WindowID 
  Protected GadgetID 
  Protected EventType 
  
  Repeat ; Start of the event loop
    
    Event = WaitWindowEvent() ; This line waits until an event is received from Windows
    WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
    GadgetID = EventGadget() ; Is it a gadget event?
    EventType = EventType() ; The event type
    
    If Event = #PB_Event_Gadget
      If GadgetID = #Hyperlink_Test
        HelloWorld()
      EndIf
    EndIf
    
  Until Event = #PB_Event_CloseWindow ; End of the event loop
EndProcedure

Main()

End
;
My theory is when you click the hyperlink (which appears as a button for some unknown reason in Linux), it should dynamically add two buttons to the scrollarea.

What happens (at least for me) is that all the gadgets disappear. All I can do is just close the window.

Any clues?
freak
PureBasic Team
PureBasic Team
Posts: 5941
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

You are reusing the same numbers for the two buttons as you are using for the other two gadgets.
Thats why the other two get automatically freed, and since they contain your
new gadgets, everything is gone.

The notation of a "gadgetlist" (OpenGadgetList(), CreateGadgetList()) only
affects where a gadget is placed. The list of gadget numbers is actually a global
one, so each gadget in the program must have a unique number even if they
are on different windows or in different containers.

The #PB_Any feature can be used to create gadgets with dynamic numbers that do not
collide with any existing ones, which is probably the best way to handle
a dynamic gui.
quidquid Latine dictum sit altum videtur
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Why wuold you put the main program loop inside a procedure? :)

It seems it would simply be like watching your program ping and pong itself to death going back and forth... 8)

and yep... #PB_Any is the best way to set things up to dynamically reallocate new buttons.

in fact you could make a procedure to reallocate the buttons and check inside that to see if they are the original buttons abd restore those buttons.

I use something like this to hidegadgets or disable them in my POS program. If the database (where the menu items are stored has an INACTIVE in it then the buttons disappear! :D
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

All good advice :D

and as it seems you missed this in the enumeration part of the manual...

The reserved constant #PB_Compiler_EnumerationValue store the next value which will be used in the enumeration. Can be useful to chain several enumerations.

So change the start of the Helloworld procedure to:-

Procedure HelloWorld()
Enumeration #PB_Compiler_EnumerationValue
#btnHelloWorld
#btnQuit
EndEnumeration

and it works.... of a fashion :)
Paid up PB User !
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

Thank you for your help. I could do with the Dunces Hat emoticon :) Of course the Enum would reset back to 0 each time it starts a new one. Duh!

Anyway, the idea behind having the main program loop is reduce the number of global variables. Ideally down to 0 would be good :) Plus there is the side benefit of having it as a collapsible region. :)

I did see #PB_Compiler_EnumerationValue, but I have no idea what it does or how it works. Without knowing, I'm loathe to use it. Could someone enlighten me?

Anyway, I've modified the code, and manually set the numbers and it works as expected. But I'm intrigued on how to use the #PB_Any. I understand using it for static items that won't change or raise events, but I'm at a loss on how I'm supposed to use #PB_Any and then actually reference them for events or changes.
Could somebody point me in the right direction?
freak
PureBasic Team
PureBasic Team
Posts: 5941
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

like this:

Code: Select all

btnQuit = ButtonGadget(#PB_Any, 0, 0, 80, 30, "Quit") 

; The variable btnQuit now holds the number representing the button and can
; be used anywhere a static number would be used...
;
SetGadgetText(btnQuit, "Please don't ;)")
It works for the other kinds of PB library objects (images, files, ...) in the same way.
quidquid Latine dictum sit altum videtur
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

*blinks*

That's freaking awesome!

Cheers!
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

The #PB_Coiler_EnumerationValue is a compiler constant that holds the value +1 that was last used in an Enumeration. Look in the manual under Enumerations for further details.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

Thank you, I finally understand it!

I see why it says it's for chaining together Enums, but I think that doing so could result in bad code. At least when I go back to debug it anyway.

I think I'll stick to the #PB_Any trick as that seems to be the best way of doing it.

As a side question. when defining these gadget variables I've left the type out (which works fine) but I hate doing that - it leads down the slippery path of sloppy coding (mine is bad enough without being helped along by the language).
I checked the manual, but it doesn't say. What type are they?
byo
Enthusiast
Enthusiast
Posts: 635
Joined: Mon Apr 02, 2007 1:43 am
Location: Brazil

Post by byo »

Foz wrote:As a side question. when defining these gadget variables I've left the type out (which works fine) but I hate doing that - it leads down the slippery path of sloppy coding (mine is bad enough without being helped along by the language).
I checked the manual, but it doesn't say. What type are they?
Do you mean this?

Code: Select all

mytext.l = TextGadget(#PB_Any, 10, 10, 100, 18, "Example")
Since the mytext will store the gadget number, use long integers. :wink:
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

Excellent, thank you.

Could this info be added to the manual please? That way, I can RTFM :)
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Foz wrote:Excellent, thank you.

Could this info be added to the manual please? That way, I can RTFM :)
Take a look at the bottom of General Syntax Rules.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

Ah... slight problem - I'm using Linux, and the General Syntax Rules isn't there. In fact when I click on "Reference Manual", the menu page that links to it appears in Windows but doesn't appear in Linux.

Erm... whoopsie! Could that be fixed at all?

Anyway, I've copied over the CHM from the windows version and I'll use that for the time being.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

I take that back. I restarted my comp and it now appears.
Post Reply