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!
Forum Archive
Layer ordering?
Are you talking in scene or ui?
For ui, you'd use a view's bring_to_front or send_to_back methods.
http://omz-software.com/pythonista/docs/ios/scene.html#scene.Layer ?
Yes, it is not obvious how you would directly control the ordering of layers from the scene documentation. 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?! :)
edit
I have tried remove_layer() and 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.Layer because JonB's question (that you answered later) in the post before mine was about ui vs. scene.
Ok, I played around with this a little, it turns out that root_layer.sublayers can be manipulated, which ultimately defines the drawing order.
For instance root_layer.sublayers.reverse() works. I would imagine sort would 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 sublayers directly.
The docs say not to modify the sublayers directly, 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[0] 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[0] 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.