Page 1 of 1

Gadget z-depth reversed?

Posted: Wed Sep 19, 2007 7:23 am
by Mistrel
When I add new gadgets to a window the new gadgets will overlap the old ones. Ok, I get that. But why do the gadgets behind the overlapping gadgets have a higher priority?

Is there any way to force priority for foreground gadgets?

In this example button "two" is drawn on top of button "one". But if you click on the overlapping area the button in the back is activated instead of the one on top.

Code: Select all

OpenWindow(0,640,480,120,100,"")
CreateGadgetList(WindowID(0))
ButtonGadget(0, 10, 10, 70, 50, "One")
ButtonGadget(1, 40, 40, 70, 50, "Two")

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
End
Here is another example with a scroll area

Code: Select all

OpenWindow(0,640,480,120,100,"")
CreateGadgetList(WindowID(0))

ScrollAreaGadget(0,10,10,70,50,140,100,30,#PB_ScrollArea_BorderLess)
CloseGadgetList()

ButtonGadget(2, 40, 40, 70, 50, "Two")

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
End

Posted: Wed Sep 19, 2007 8:53 am
by Trond
Gadgets doesn't have Z-depth.

Re: Gadget z-depth reversed?

Posted: Wed Sep 19, 2007 11:31 am
by PB
Thanks to Sparkie:

Code: Select all

OpenWindow(0,640,480,120,100,"")
CreateGadgetList(WindowID(0))
ButtonGadget(1, 10, 10, 70, 50, "Bottom")
ButtonGadget(2, 40, 40, 70, 50, "Top")
SetWindowLong_(GadgetID(1), #GWL_STYLE, GetWindowLong_(GadgetID(1), #GWL_STYLE) | #WS_CLIPSIBLINGS)
SetWindowPos_(GadgetID(1), #HWND_BOTTOM, -1, -1, -1, -1, #SWP_NOSIZE | #SWP_NOMOVE)

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Sparkie's original code was from my question here:
http://www.purebasic.fr/english/viewtopic.php?t=17952
.

Posted: Wed Sep 19, 2007 5:27 pm
by Mistrel
That's perfect! I've modified it a bit to force gadgets to be drawn on-top instead of forcing a particular gadget to the bottom.

Thank you. :)

I couldn't find a way to push a single gadget to the top so this procedure will have to be used on gadgets that overlap and the gadgets they obscure.

Code: Select all

Procedure ForceGadgetZOrder(gadget)
	;/ Flip the gadget draw order and force
	;/ the topmost gadget to recieve focus
	;/ first for overlapping gadgets

	SetWindowLong_(GadgetID(gadget),#GWL_STYLE,GetWindowLong_(GadgetID(gadget),#GWL_STYLE)|#WS_CLIPSIBLINGS)
	SetWindowPos_(GadgetID(gadget),#HWND_TOP,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE)
EndProcedure

OpenWindow(0,640,480,120,100,"")
CreateGadgetList(WindowID(0))
ForceGadgetZOrder(ButtonGadget(#PB_Any,10,10,70,50,"Bottom"))
ForceGadgetZOrder(ButtonGadget(#PB_Any,40,40,70,50,"Top"))

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow

Posted: Mon May 11, 2009 1:42 pm
by akj
This is the routine I've used successfully in a number of programs:

Code: Select all

Procedure SetGadgetZOrder(gadget, zorder=0)
; Correct the z-order and draw order for [potentially] overlapping gadgets
; Call with zorder=0 just after creating each gadget
; Call with zorder=1 to later bring a gadget to the top of the z-order
; Call with zorder=-1 to later bring a gadget to the bottom of the z-order
; www.purebasic.fr/english/viewtopic.php?t=28802
If zorder=0
  SetWindowLong_(GadgetID(gadget),#GWL_STYLE,GetWindowLong_(GadgetID(gadget),#GWL_STYLE)|#WS_CLIPSIBLINGS)
EndIf
If zorder>=0
  SetWindowPos_(GadgetID(gadget),#HWND_TOP,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE)
Else
  SetWindowPos_(GadgetID(gadget),#HWND_BOTTOM,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE)
EndIf
EndProcedure