Page 1 of 1

Splitter broken gadgetlist

Posted: Tue Sep 06, 2016 5:30 am
by TomyB
PureBasic 5.50 32/64 (but also older versions)
Window 10 Home (VirtualBox)

Description:
Create a Window with a SplitterGadet on it.
Use any gadget to fill the splitter. Not sure if any but all gadget i used fired an error (No active gadgetlist) except ScintillaGadget (no error it just messes up the window layout).
Create some new gadgets and exchange them in splittergadget (just to see that its working without problems). SetGadgetAttribute(#Splitter, #PB_Splitter_SecondGadget, #YourGadget). This should work.
Now create a new window and just close it. Thats enough to mess up the splitter. (doesnt matter if its a parent window or not)
If you try again to exchange gadgets in splitter you will get an error message "No active gadgetlist" and the program stops, if you used ScintillaGaget you wont get any error the program keeps running and the splitter/window layout gets messed up.

some short ugly code to test:

Code: Select all

EnableExplicit

Enumeration Window
  #WindowMain
  #WindowDummy
EndEnumeration

Enumeration Menu
  #MenuMain
EndEnumeration

Enumeration MenuItems
  #MenuFileOpenWindow
  #MenuFileNew
  #MenuFileClose
EndEnumeration

Enumeration Toolbar
  #ToolbarMain
EndEnumeration

Enumeration Gadget
  #SplitterMain
  #CanvasDummy
EndEnumeration

Global NewList Gadgets.i()

;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Procedure WindowDummy()
  OpenWindow(#WindowDummy, #PB_Ignore, #PB_Ignore, 450, 180, "Dummy Window. Just close me again.", #PB_Window_SystemMenu|#PB_Window_WindowCentered)
EndProcedure

Procedure MenuFileClose()
  
  If (ListSize(Gadgets()) = 1): ProcedureReturn: EndIf
  
  PreviousElement(Gadgets()) 
  SetGadgetAttribute(#SplitterMain, #PB_Splitter_SecondGadget, Gadgets())
  HideGadget(Gadgets(), 0)
  NextElement(Gadgets())
  HideGadget(Gadgets(), 1)
  DeleteElement(Gadgets())
  
EndProcedure

Procedure MenuFileNew()
  
  Protected CurrentGadget.i = Gadgets()
  
  AddElement(Gadgets())
  
  Gadgets() = EditorGadget(#PB_Any, 0, 0, 0, 0)
  
  SetGadgetAttribute(#SplitterMain, #PB_Splitter_SecondGadget, Gadgets())
  
  PreviousElement(Gadgets()) 
  
  HideGadget(Gadgets(), 1)
  
  NextElement(Gadgets())
  
  SetGadgetText(Gadgets(), Str(ListIndex(Gadgets()) + 1))
  
EndProcedure
;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Define buffer.i

OpenWindow(#WindowMain, #PB_Ignore, #PB_Ignore, 800, 600, "Splitter Bug Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)

CreateImageMenu(#MenuMain, WindowID(#WindowMain))
MenuTitle("File")
MenuItem(#MenuFileOpenWindow, "Open Window")


CreateToolBar(#ToolbarMain, WindowID(#WindowMain))
ToolBarStandardButton(#MenuFileNew, #PB_ToolBarIcon_New)
ToolBarStandardButton(#MenuFileClose, #PB_ToolBarIcon_Delete)


CanvasGadget(#CanvasDummy, 0, 0, 0, 0)

AddElement(Gadgets())

Gadgets() = EditorGadget(#PB_Any, 0, 0, 0, 0)

SplitterGadget(#SplitterMain, 0, 5 + MenuHeight(), WindowWidth(#WindowMain), WindowHeight(#WindowMain) - MenuHeight() - 5, #CanvasDummy, Gadgets())

SetGadgetState(#SplitterMain, 30)
SetGadgetAttribute(#SplitterMain, #PB_Splitter_FirstMinimumSize, 30)
SetGadgetAttribute(#SplitterMain, #PB_Splitter_SecondMinimumSize, WindowHeight(#WindowMain))

SetGadgetText(Gadgets(), "1" + #CRLF$ + "Use the New Files Button to create gadgets inside splitter." + #CRLF$ + "Use the Close File button to remove gadgets inside splitter." + #CRLF$ + "Use the Menu to create a new Window." + #CRLF$ + "Now try again to create a gadget inside splitter. Program crashes for me here.")

BindMenuEvent(#WindowMain, #MenuFileOpenWindow, @WindowDummy())
BindMenuEvent(#WindowMain, #MenuFileNew, @MenuFileNew())
BindMenuEvent(#WindowMain, #MenuFileClose, @MenuFileClose())


StartDrawing(CanvasOutput(#CanvasDummy))
DrawText(10, 10, "Tabbar")
StopDrawing()
;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Procedure WindowMain_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #WindowMain
          ProcedureReturn #False
        Case #WindowDummy
          CloseWindow(#WindowDummy)
      EndSelect
    Case #PB_Event_Menu
      Select EventMenu()
      EndSelect
    Case #PB_Event_Gadget
      Select EventGadget()
      EndSelect
  EndSelect
  
  ProcedureReturn #True
  
EndProcedure

Repeat
Until WindowMain_Events(WaitWindowEvent()) = #False

Edit: Sorry forgot to say that the compiled file runs and doesnt crash, but the gadget wont be added to the splitter after you opend a window.

Re: Splitter broken gadgetlist

Posted: Tue Sep 06, 2016 7:12 am
by infratec
Hi,

an easier demonstration:

Code: Select all

OpenWindow(0, 0, 0, 450, 180, "1", #PB_Window_SystemMenu|#PB_Window_WindowCentered)

TextGadget(#PB_Any, 10, 10, 50, 20, "jhjh")

OpenWindow(1, 0, 0, 450, 180, "2", #PB_Window_SystemMenu|#PB_Window_WindowCentered)
CloseWindow(1)

TextGadget(#PB_Any, 10, 40, 50, 20, "jhjh")

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Bernd

Re: Splitter broken gadgetlist

Posted: Tue Sep 06, 2016 8:11 am
by Demivec
Not a bug.

@TomyB: For simplicity the gadget list defaults to the one for the last window created. You need to switch to the proper gadget list if you are creating more than one window.

Make this change for your example to work correctly:

Code: Select all

Procedure MenuFileNew()
  
  Protected CurrentGadget.i = Gadgets()
  Protected previousGadgetList = UseGadgetList(WindowID(#WindowMain)) ; <=== change, switch to correct gadget list and remember previous one
  
  AddElement(Gadgets())
  
  
  Gadgets() = EditorGadget(#PB_Any, 0, 0, 0, 0)
  
  SetGadgetAttribute(#SplitterMain, #PB_Splitter_SecondGadget, Gadgets())
  
  PreviousElement(Gadgets()) 
  
  HideGadget(Gadgets(), 1)
  
  NextElement(Gadgets())
  
  SetGadgetText(Gadgets(), Str(ListIndex(Gadgets()) + 1))
  
  UseGadgetList(previousGadgetList) ; <=== change, restore previous gadget list
EndProcedure

@infratec: Your code can be corrected as follows:

Code: Select all

OpenWindow(0, 0, 0, 450, 180, "1", #PB_Window_SystemMenu) ; <==== change, can't specify #PB_Window_WindowCentered without a parent window

TextGadget(#PB_Any, 10, 10, 50, 20, "jhjh")

OpenWindow(1, 0, 0, 450, 180, "2", #PB_Window_SystemMenu|#PB_Window_WindowCentered)
CloseWindow(1)

UseGadgetList(WindowID(0))   ; <==== Specify gadget list of the correct window to use
TextGadget(#PB_Any, 10, 40, 50, 20, "jhjh")

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Splitter broken gadgetlist

Posted: Tue Sep 06, 2016 8:49 am
by infratec
I know there was something :wink:

But in the hurry I found only OpenGadgetList() which was the wrong one.

Maybe these 2 procedures should be combined or at least there should be a hint in the help of both procedures.

Bernd

Re: Splitter broken gadgetlist

Posted: Wed Sep 07, 2016 3:19 am
by TomyB
Oh ok im sorry then.

Didn't know that.

Could somebody move this to the fails section then :)

Edit: Thanks Demivec.