Z-ordering canvases

BlitzPlus Forums/BlitzPlus Programming/Z-ordering canvases

Cold Harbour(Posted 2004) [#1]
I’m writing a modal window system for my app. It’s going well but for one problem.

In order for the z-ordering of the windows to work properly I need to kill the canvases used and recreate them in the new z-order. This produces a flickering effect since createcanvas() immediately draws a big black box as soon as it’s called – even without flipping it.

I’ve noticed that other apps don’t have this problem. I have to use canvases to get the gadget action right. Soooo…..

1)Can you change the z-ordering of canvases without destroying it and redrawing (first drawn is always on top ect)?
2)Can you make createcanvas() wait for a flipcanvas before drawing anything – including the black square.

Anyone who’s written an app in bp must know what I’m banging on about here.

Thanks a lot.

This is in Windows desktop GUI mode btw.


soja(Posted 2004) [#2]
Just off the top of my head, to work around #2, you might try creating the canvas off screen, hiding it, moving it to where you want, then showing it. Not sure about flicker. And I don't think you can change the internal z-ordering of gadgets without destroying/recreating them, unless (I don't remember) Disable/EnableGadget works.

I wish there were easy z-order gadget commands.


Cold Harbour(Posted 2004) [#3]
I like the sound of your offscreen creation method soja.
That might just work if I can get the timing right.

Thanks :)

Anyone else written a child window engine in BP?


Cold Harbour(Posted 2004) [#4]
OK, I've just tried this. Initially redrawing the child windows out of view, flipping it and then setgadgetshaping the parent gadget back into view and you know what….. it works really really well.

One line of code totally changed the look and feel of my app!

Once again thanks for the idea soja!


skn3(Posted 2004) [#5]
Have you tried api :) ?

Here is a working userlib + example that I quickly whipped up.

;USERLIB
;.lib "user32.dll"
;SetWindowPos%(hwnd%,hwndafter%,x%,y%,width%,height%,flags%):"SetWindowPos"

;BLITZ FUNCTION
;function BringGadgetToTop(gadget)
;	SetWindowPos(QueryObject(gadget,1),0 ,0,0,0,0 ,1+2)
;end function
; ------------------------------------------------------------------------------------------------------------


Global window = CreateWindow("Test window",(ClientWidth(Desktop())/2)-300,(ClientHeight(Desktop())/2)-200,600,400,0,1+2)
Global red    = CreateCanvas(100,100,100,100,window,1)
Global blue   = CreateCanvas(150,150,100,100,window,1)

Global button = CreateButton("Change Z order",300,100,200,150,window)
Global flag   = True

SetBuffer CanvasBuffer(red)
ClsColor 255,0,0
Cls
FlipCanvas(red)

SetBuffer CanvasBuffer(blue)
ClsColor 0,0,255
Cls
FlipCanvas(blue)

Repeat
	Select WaitEvent()
		Case $803 : Exit
		Case $401
			If EventSource() = button
				If flag = False
					flag = True
					;bring red to front
					BringGadgetToTop(red)
				Else
					flag = False
					;bring blue to front
					BringGadgetToTop(blue)
				End If
			End If
	End Select
Forever

Function BringGadgetToTop(gadget)
	SetWindowPos(QueryObject(gadget,1),0 ,0,0,0,0 ,1+2)
End Function



Cold Harbour(Posted 2004) [#6]
Well skn3[ac], what can I say. That is exactly what I needed. Very elegant solution.

Thank you for taking to time to write that code. It’s very much appreciated!


skn3(Posted 2004) [#7]
That's ok. Glad to help. I wasn't sure it would work on a canvas (because of the way blitz faffs up layering) but it did :D


soja(Posted 2004) [#8]
skn, that's very interesting that it works on canvases... I remember trying this and it didn't work for me with other gadgets (I think?)

maybe I was doing it wrong -- if so, good news! I'll have to try again.


Cold Harbour(Posted 2004) [#9]
Yep it works better then I could have hoped.



skn, I'd say that your code should go in the archives since it solves a key problem with BP.