From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
JackDunaway

Programmatic Manipulation of Object Layer (z-order)

Status: New

Unfortunately, we ran into issues with rearranging the Z-order of controls at run-time, and have decided to pause development of this feature.

I would like to be able to change the z-order of FP Objects programmatically. For starters, I envision the following properties:

 

  1. Layer - Explicitly sets the z-order layer in which an object resides.
  2. Promote/Demote - Implicitly sets z-order layer by -1 or +1 (assuming Layer 0 is frontmost)
  3. Send to Back/Send to Front - Explicitly sets z-order to the foremost or rearmost layer
  4. (Optional) Container property "Layers" - Returns an array of all layer indices currently in use by the container (Page, Panel, Cluster, etc.)
  5. (Optional) Container method "Layer.Objects" - Returns array of references to all objects on a layer
 
ControlLayers.gif
 
Question at this point: can more than one object reside on a layer, or should each object represent a discrete z-order? Does changing the z-order of one object likewise affect the z-order of other objects? Discuss in the comments.

 

15 Comments
JackDunaway
Trusted Enthusiast

So, I had a brief conversation with myself a moment ago after searching "layer" as opposed to searching "layers" prior to posting:

 

Self: You mean, like this?

Self: Oops.

PJM_Labview
Active Participant

It is really too bad that other idea did not got more kudos. I had wanted this for years (I think I requested this the first time over 8 years ago).

 

By the way, your image make it a low easier to see at a glance what the idea is, so maybe you will got more vote through this one...



  


vipm.io | jki.net

AristosQueue (NI)
NI Employee (retired)

> Question at this point: can more than one object reside on a layer, or should each

> object represent a discrete z-order? Does changing the z-order of one object likewise

> affect the z-order of other objects? Discuss in the comments.

 

One possibility: Make the Layer property read-only and provide methods for "Move To Back", "Move Backward", "Move To Front" and "Move Forward". That avoids the question of two at the same level since the system would be maintaining each one's level position. It also avoids questions about "What if they set level greater than the number of objects on the panel? Are new objects added *behind* that one?" As long as you can read the Layer property, I think you'd be able to use the four methods to effectively manipulate the stack. Thoughts?

JackDunaway
Trusted Enthusiast

>> Make the Layer property read-only and provide methods for "Move To Back", "Move Backward", "Move To Front" and "Move Forward".

 

This interface could get tedious. Say you have 10 objects on a panel, and you want to simply swap the z-order of objects 4 and 5. You would consequently also need to call methods on objects 6, 7, 8, and 9 to perform this swap. (This is also a tedious issue with the current IDE UI for object layer manipulation. I would expect the IDE to have smarter layer tools if this Idea is implemented)

 

I'm currently leaning toward one object per layer. That makes "layer" a misnomer (since I think of a "layer" as capable of hosting multiple objects), so z-order is more appropriate terminology.

 

I'm also leaning toward being able to explicitly set the z-order of any given object. In doing so, it *might* increment the layer of one or more objects below it, that is, if it displaces an object that previously held that z-order slot. (The idea of sparse z-order slots is a must.)

AristosQueue (NI)
NI Employee (retired)

> and you want to simply swap the z-order of objects 4 and 5.

 

Why not just call "Move Backward" on 5?

 

For the record, the methods already exist on VIs, but they only work on VIs being edited, not VIs that are running.

JackDunaway
Trusted Enthusiast

>> Why not just call "Move Backward" on 5?

  

D'oh. I didn't even think of the two relative motions "Move Forward/Backward" (no need to touch 6, 7, 8, or 9). I didn't even consider this (trivially) simple solution since I use "Move to Front/Back" in order to reference a known datum (the front or the back). Relative movements - when the initial order is unknown - yield ambiguous z-orders.

 

Regardless, it would not be trivial to swap items 2 and 7. You would need to call the "Move Forward" method 5 times for Object 7, then call "Move Backward" 4 times for Object 2 (remembering, that it's 4 and not 5, since one automatic demotion happened from the promotion of Object 7).

 

It may be low-hanging fruit to expose these four methods for manipulating z-order, and this might be a good start for programmatic control. Long-term, I would like to see an interface (both API and IDE) that allows simpler and more powerful reordering of z-order.

AristosQueue (NI)
NI Employee (retired)

Good argument.

 

Ok... how about a method on VI that returns an array of control refnums that is all controls in z-plane order and another method that takes an array and sets the z-plane order in the order of the array. On the set function, we can have a rule for any refnums that aren't included in the array, like "if it isn't in the array, it goes z-plane order to the back," or something like that. That would give the ability to reorder arbitrarily in a single operation and commit many reorders in one step.

JackDunaway
Trusted Enthusiast

>> Ok... how about a method on VI that returns an array of control refnums that is all controls in z-plane order and another method that takes an array and sets the z-plane order in the order of the array.

 

This seems like a pretty low-level accessor that could be a useful supplement to the mid-level "Set/Get z-order", but it would not make a good primary interface for z-order manipulation.

 

Consider a simple example: you have one control ref and want to explicitly set it's z-order. You would need to call Control.Owner.FrontPanel.GetAllZOrders, search the array for the index, perform an array operation, and reset using Control.Owner.FrontPanel.SetAllZOrders. Additionally, the code module to perform this task would expose all object references on a wire, and hopefully the developer will perform the correct array ops. Additionaly, shall we create a mutex around the Get/Set op to avoid a race condition? 😉

AristosQueue (NI)
NI Employee (retired)

> Additionaly, shall we create a mutex around the Get/Set op to avoid a race condition?

 

Same race condition exists with "Control.SetLayer( Control.GetLayer() + 1 )"

 

 

 

JackDunaway
Trusted Enthusiast

>> Same race condition exists with "Control.SetLayer( Control.GetLayer() + 1 )"

 

True, which could be avoided by making the operation atomic with a "Promote/Demote" method that has a SlotsToMove integer input. Nevertheless, I have exhaustively (exasperatingly?) voiced my ideas, and it's time to sit back and see if this Idea "makes the team". 🙂