How can I control the visual (z) ordering or depth of layers to move one to the front when touched? It must be obvious, but I couldn't seem to find it in the documentation. Many thanks!
Are you talking in
ui, you'd use a view's
Yes, it is not obvious how you would directly control the ordering of layers from the
scenedocumentation. One way to "bring to the front" would be to remove, then re-add a layer ( I haven't tested this, but ui worked that way). Sending a specific layer to the back would then seem to require removing all other layers, and re-adding them in order.
JonB, yes it's in a scene. I will try your suggestion re adding and removing all the layers, but this seems a bit much in any kind of dynamic environment with a reasonable number of layers doesn't it?! :/
ccc. I'm not clear what you are pointing at? Please tell me which bit of the documentation controls the layer 'height' (z coordinate). Coz I can't see it. As per original post, I HAVE read the docs...
Surely I can't be the first person to have this issue?! :)
I have tried
add_layer()and yes, this will bring a chosen layer to the front of a scene.
Is this really the only way to do it through? I have to keep track of all the layers z heights, and at each redraw every single layer is removed, and then they're all added back, one by one, in the right order? 60 times a second?! :/
moddhayward, try only changing the z-order when you WANT a z-order that is different than the current one. Once you have changed the z-order, it should stay that way until you change it again. As you point out, doing so repeatedly in scene.draw(), up to 60 times a second, is NOT the way to go.
I was pointing to
scene.Layerbecause JonB's question (that you answered later) in the post before mine was about
Ok, I played around with this a little, it turns out that
root_layer.sublayerscan be manipulated, which ultimately defines the drawing order.
root_layer.sublayers.reverse()works. I would imagine
sortwould also work for arbitrary ordering (e.g. sort with a key), though I didn't try it, since both sort in place. I suspect you could also set this list directly, for instance in Cards.py we see
self.root_layer.sublayers = , indicating that you can indeed manipulate
The docs say not to modify the
sublayersdirectly, I suspect that might really mean don't add or remove layers directly using the list -- maybe there is some "registering" of Layers happening under the hood, but once they have been added, you can modify the order manually.
As ccc says, just reorder this list when something changes that requires reordering. Also, for many simple cases, I'd imagine you want a simple bring to front or send to back, which could be implemented as follows inside your scene class:
def bring_to_front(self, layer): """bring layer to the front, if it exists as a sublayer (otherwise nothing changes). This assumes that sublayer is the bottom layer, so sorts the list so layer is at the end.""" self.root_layer.sublayers.sort( key=lambda x: x == layer, reverse=False) def send_to_back(self,layer): """send layer to the back, if it exists as a sublayer (otherwise nothing changes). This assumes that sublayer is the bottom layer, so sorts the list so layer is at the front""" self.root_layer.sublayers.sort( key=lambda x: x == layer, reverse=True)
( I may have mixed these up -- not in front of pythonista right now, and I forgot if the "top layer" was the first or last item in the sublayer list -- the above is written assuming that the top layer is the last item in the list, i.e that add_sublayer appends to the list rather than inserts)
ccc, that wasn't obvious but fair enough! :)
I actually wanted a pretty dynamic environment/game. Even if I 'only change it when it needs changing' I still have to keep track of all z heights and run a chunk of code to decide IF a change has happened, between any of the layers, 60 times a second. This is some distance from simply passing a z height to the canvas, and no doubt considerably slower.
Thank you for all your help though, at least I know the limitations now.