# Layering UI controls?



## tcollins (May 18, 2018)

Is there a list of what controls will successfully block other controls when stacked?

For instance, a ui_switch declared after a ui_menu. The switch should block the menu from being accessed. Or not, apparently.


----------



## d.healey (May 18, 2018)

Menu - Highest
Button
Switch
Slider
Table
Knob
Value edit
Label/Waveform - Lowest


----------



## tcollins (May 18, 2018)

Thanks!


----------



## P.N. (May 19, 2018)

Hi. 

With the relatively new $CONTROL_PAR_Z_LAYER, you can block almost any control with any other control.

There are some limitations, though. As your example for the switch/menu, you can have the switch blocking the menu with this command, but the menu's control help will always show when the switch is hovered, even if the switch is above the menu.

I believe there are more inconsistencies like this, but it works, none-the-less.

Paulo


----------



## EvilDragon (May 19, 2018)

Z layer feature is just for visual z-order changes, it doesn't block interaction at all. At some point we might get an option for that as well, which would be very nice.


----------



## P.N. (May 19, 2018)

EvilDragon said:


> Z layer feature is just for visual z-order changes, it doesn't block interaction at all.



Sure it does. I use it all the time for that purpose.


----------



## P.N. (May 19, 2018)

```
on init
    set_ui_height_px(50)
    make_perfview
    
    
    declare ui_button $SWITCH
    set_control_par(get_ui_id($switch),$CONTROL_PAR_WIDTH,50)
    set_control_par(get_ui_id($switch),$CONTROL_PAR_HEIGHT,20)
    move_control_px($switch,500,1)

    make_persistent($SWITCH)
    read_persistent_var($SWITCH)

    declare ui_menu $menu
    set_control_par(get_ui_id($menu),$CONTROL_PAR_WIDTH,200)
    set_control_par(get_ui_id($menu),$CONTROL_PAR_HEIGHT,20)
    set_control_par(get_ui_id($menu),$CONTROL_PAR_Z_LAYER,$switch)
    move_control_px($menu,50,1)
        
    declare ui_button $button
    set_control_par(get_ui_id($button),$CONTROL_PAR_WIDTH,200)
    set_control_par(get_ui_id($button),$CONTROL_PAR_HEIGHT,20)
    set_control_par(get_ui_id($button),$CONTROL_PAR_Z_LAYER,abs($switch-1))
    move_control_px($button,50,1)

end on
```

$CONTROL_PAR_Z_LAYER only works on init, but clicking the switch button on the right and restarting the script shows the button going over the menu and blocking user interaction., and vice versa.


----------



## EvilDragon (May 19, 2018)

P.N. said:


> Sure it does. I use it all the time for that purpose.



No it doesn't. Say if you put a label above a slider, you can still operate the slider even if it's not visible because it's covered by the label. It's just visual z-order, and this implementation was confirmed by NI.


----------



## P.N. (May 19, 2018)

In my first post, i do say it works for "almost" all controls and that there are "inconsistencies".

I don't posess extra information of what was NI's goal for the implementation, but i did post code to back my claim for that particular example.

That example was referencing the menu/switch implementation. As you can see, the button in z-layer 1 effectively blocks the menu and allows for normal button interaction and the opposite is true as well.

It bypasses the declaration order completly. It's not just a "visual" implementation, at least not for the controls in my example.


----------



## P.N. (May 19, 2018)

As you said, the label is probably the weakest at blocking, because there are more combinations that work fine.
You can block a button with a slider, for example.


----------



## EvilDragon (May 20, 2018)

Basically the z-order of UI control types that David posted above holds true within each of the 3 Z layers. That's the implementation.

In any case, I'd be much happier with a dedicated control par for blocking vs non-blocking z-ordering. Eventually we'll probably have that, hopefully.


----------



## P.N. (May 20, 2018)

Yes, it would be better that blocking could be fully associated with the z_layer command or that there were dedidated commands for that purpose.

I never mentioned "implementation" when i first posted - i was just refering to something that i know that works because i've applied it before in useful situations.
Maybe it wasn't intended on NI's part, but it works none-the-less.


In the meantime, for the OP, if you in fact wish to *block* a* menu* with a *button* (not just *visually*, but* block interaction* as well) you can use the z_layer trick, as i demonstrated above.


Best regards, 

Paulo.


----------



## magneto538 (Nov 15, 2018)

d.healey said:


> Menu - Highest
> Button
> Switch
> Slider
> ...



Actually I've just run some tests and I'd like to follow up to this.
With Kontakt 6's new UI controls, the order appears to be as follows:

TEXT EDIT - Highest
XY
TABLE
MENU
VALUE_EDIT
BUTTON
SWITCH
SLIDER
KNOB
LEVEL METER
WAVETABLE
WAVEFORM - Lowest


----------



## P.N. (Nov 15, 2018)

Does Kontakt 6 allow consistent $CONTROL_PAR_Z_LAYER override (both visually and in terms of blocking interaction) for any ui control?

Kontakt 5 only allows it for some controls (see above posts).


----------



## magneto538 (Nov 15, 2018)

P.N. said:


> Does Kontakt 6 allow consistent $CONTROL_PAR_Z_LAYER override (both visually and in terms of blocking interaction) for any ui control?
> 
> Kontakt 5 only allows it for some controls (see above posts).



Unfortunately the layering happens consistently only visually-wise. Everything underneath a UI control with a higher Z layer will be clickable. That's unfortunate and has been reported by many Beta testers already (including yours truly) but apparently there is no solution to this.


----------



## P.N. (Nov 15, 2018)

magneto538 said:


> Everything underneath a UI control with a higher Z layer will be clickable.



This is not true for Kontakt 5 and it's a point where Evil Dragon and i didn't seem to agree upon.

As posted in the example above, setting a button to a higher Z layer, will make it block interaction with a ui_menu, for example.

I can't speak for other controls, but this combination works and can be tested with the code example i posted above. (press the switch button, restart the script and see the menu being blocked by the button and vice versa).

I didn't test for Kontakt 6 as i don't own it yet.


----------



## magneto538 (Nov 15, 2018)

P.N. said:


> This is not true for Kontakt 5 and it's a point where Evil Dragon and i didn't seem to agree upon.
> 
> As posted in the example above, setting a button to a higher Z layer, will make it block interaction with a ui_menu, for example.
> 
> ...



Menu, buttons and switches share the same internal handling. They are pretty much alternatives to the same control, so that behaviour is expectable, but doesn't hold true for any other UI control.


----------



## P.N. (Nov 15, 2018)

Using the same example script i posted, you can try other controls.
Blocking seems to work with other control combinations too (in Kontakt 5).
Control help is messed up though.

The important thing here is, when assigning a higher Z layer to a control that is normally in a lower hierarchy, the blocked control (normally in a higher hierarchy) should have a lower Z layer assigned as well.


----------



## P.N. (Nov 15, 2018)

My tests show me a slider blocking a button, a table blocking a button, a slider blocking a menu... etc.
Easy to test just using the code above and replacing the controls.

Unless i'm missing something, this works...


----------



## P.N. (Nov 15, 2018)

After trying some other combinations, i'm yet to find a combination (that doesn't involve ui_labels) that doesn't properly override mouse interaction with assigned Z layers.

The only requirement is to always have Z layer assigned to all the overlayed controls.

Here's another example with a xy pad blocking (or being blocked) by a button.
The xy pad is set to mode 2 for easy confirmation that it's properly blocked.
Both controls are persistent.

Cheers,
Paulo.


```
on init
    set_ui_height_px(50)
    make_perfview
    
    declare ui_button $SWITCH
    set_control_par(get_ui_id($switch),$CONTROL_PAR_WIDTH,50)
    set_control_par(get_ui_id($switch),$CONTROL_PAR_HEIGHT,20)
    move_control_px($switch,500,1)

    make_persistent($SWITCH)
    read_persistent_var($SWITCH)

    declare ui_xy ?pad[2]
    set_control_par(get_ui_id(?pad),$CONTROL_PAR_WIDTH,200)
    set_control_par(get_ui_id(?pad),$CONTROL_PAR_HEIGHT,20)
    set_control_par(get_ui_id(?pad),$CONTROL_PAR_MOUSE_MODE,2)
    set_control_par(get_ui_id(?pad),$CONTROL_PAR_Z_LAYER,$switch)
    move_control_px(?pad,50,1)
    make_persistent(?pad)
 
    declare ui_button $button
    set_control_par(get_ui_id($button),$CONTROL_PAR_WIDTH,200)
    set_control_par(get_ui_id($button),$CONTROL_PAR_HEIGHT,20)
    set_control_par(get_ui_id($button),$CONTROL_PAR_Z_LAYER,abs($switch-1))
    move_control_px($button,50,1)
    make_persistent($button)
end on
```


----------



## P.N. (Nov 15, 2018)

Here's a more practical example of a XY and a table being blocked by buttons.
One thing to notice is, despite being blocked, the XY still displays mouse over activity (even if the control remains blocked).

Replacing the table with a ui_value_edit, for example, works fine. Not even the mouse over interaction (for the menu edit arrows) is registered.


----------



## P.N. (Nov 15, 2018)

Last example. Same as above but with a ui_value_edit instead of a table.


----------



## P.N. (Nov 18, 2018)

Is anyone else interested in testing this Z_LAYER functionality a little better?
@Tod , @Lindon , @polypx , @Polkasound , @geronimo ? 

I have provided test code and a couple of nki's (a couple of errors in those, nothing important) demonstrating some of my findings.

I didn't test all possible combinations, but some of them work on my end without issues, or in some cases, with minimum issues.

This thread has begun in May, and there's still some confusion regarding what Z_LAYER can and can't do to block control interaction and thus override Kontakt's default control hierarchy.

Since this is probably something can turn out to be a very useful "trick" for many developer's, i encourage anyone who may be interested to give it a try and report your results.

Thank you.

Paulo


----------



## Tod (Nov 22, 2018)

Hi Paulo, I did DL you files but I'm still on Kontakt 5.7.1. I could update but I'm not quite ready to do that yet. Sorry I couldn't be more help.

Also, I'm not sure what this is all about. I assume it's for putting something like a switch over a menu, as an example, and I'm not sure how that might be used other then maybe something like putting an option of "Yes" or "No" for saving a preset?


----------



## P.N. (Nov 22, 2018)

Hi, Tod.

That could be a scenario. Yes/No, or something in those lines.
But the applications go beyond that.

I've already used blocking in a real product.

The application was:
- The menu was too big (x axis) to allow space for an extra CC/velocity toggle button, that would only be available for a couple of menu entries.
- Since the name of those particular menu entries was small, the CC/velocity toggle buttons appears on TOP of the menu, whenever the relevant menu entries are selected. The key word here is "top", differenciating itself from the bottom menu (blocking it).

Another very cool application for this would be, creating a table preset system based on tables...

Meaning, instead of chosing a preset name, you could select and click miniature tables, that are a true visual representation of what the user saved.

This has been done before with fixed factory presets via images, but with Z_LAYER, it would be possible to create a dynamic implementation of this.



One of the nkis above shows a button blocking a value edit (it also works for text edits).

Unless there was a big misunderstanding (and i apologize if that was the case), some users are rejecting or ignoring the fact that this is possible to do with Z_LAYER.

The nki's show that Z_LAYER doesn't solely operate on visual changes, but has some effects on interactivity as well.

The reason i'm trying to get to the bottom of this is because there seems to be no defined rule to what is possible using Z_LAYER so more testing is needed. (Not all combinations/controls behave the same.)


----------



## EvilDragon (Nov 22, 2018)

P.N. said:


> Unless there was a big misunderstanding (and i apologize if that was the case), some users are rejecting or ignoring the fact that this is possible to do with Z_LAYER.



It was just what was told to us while this was in beta, that's all - they just exposed Kontakt's internal Z-layering as it is, without any specific implementation regarding blocking of elements between layers. Me and some other devs asked for this feature (blocking between Z-layers) to be explicit, rather than jumbled as it is now, from what you can see. Just another control parameter that would explicitly say "this control blocks all other controls that are below it regardless of Z layer they're on, and regardless of UI control type".


----------



## P.N. (Nov 23, 2018)

It's perfectly fine to make comments based on reports. Afterall, no one has the time to test everything alone.
That being said, looking back at our past exchanges on this matter, i did state i tested it myself, provided some code, but that didn't seem to have any effect on your position.

I think you and magneto could have handled this a little bit better... 

But let's not make a big deal out of this. The point of this forum, and most of my posts is to help out other users and share kontakt tricks.

About this Z_LAYER command topic, i know most developers would specially like blocking labels. That's probably the number one priority to many, but i hope this thread inspires developers to use Z_LAYER as it's implemented now too, because it can still be quite useful, even with its inconsistencies.

Paulo


----------



## magneto538 (Feb 25, 2019)

Hi all,

Here's a script that allows to check the interactions between all the controls available, as well as priority of each control over the others. Hopefully this will turn out useful.

To show a control of a specific type, just enable its related button.


```
on init
  make_perfview
  set_ui_height(8)

  declare $i

  declare ui_xy ?Xy[2]
  declare ui_knob $Knob(0, 12, 1)
  declare ui_menu $Menu
  declare ui_label $Label(2, 2)
  declare ui_table %Table[5](1, 1, 127)
  declare ui_button $Button
  declare ui_slider $Slider(1, 12)
  declare ui_switch $Switch
  declare ui_waveform $Waveform(1, 1)
  declare ui_wavetable $Wavetable
  declare ui_text_edit @TextEdit
  declare ui_value_edit $ValueEdit(1, 12, 1)
  declare ui_level_meter $LevelMeter
  declare ui_file_selector $FileSelector

  declare %ids[14]
  declare const $ids__SIZE := 14
  %ids[0] := get_ui_id(?Xy)
  %ids[1] := get_ui_id($Knob)
  %ids[2] := get_ui_id($Menu)
  %ids[3] := get_ui_id($Label)
  %ids[4] := get_ui_id(%Table)
  %ids[5] := get_ui_id($Button)
  %ids[6] := get_ui_id($Slider)
  %ids[7] := get_ui_id($Switch)
  %ids[8] := get_ui_id($Waveform)
  %ids[9] := get_ui_id($Wavetable)
  %ids[10] := get_ui_id(@TextEdit)
  %ids[11] := get_ui_id($ValueEdit)
  %ids[12] := get_ui_id($LevelMeter)
  %ids[13] := get_ui_id($FileSelector)

  declare !names[14]
  declare const $names__SIZE := 14
  !names[0] := "Xy"
  !names[1] := "Knob"
  !names[2] := "Menu"
  !names[3] := "Label"
  !names[4] := "Table"
  !names[5] := "Button"
  !names[6] := "Slider"
  !names[7] := "Switch"
  !names[8] := "Waveform"
  !names[9] := "Wavetable"
  !names[10] := "TextEdit"
  !names[11] := "ValueEdit"
  !names[12] := "LevelMeter"
  !names[13] := "FileSelector"

  declare %Show[14]
  declare $Show__n
 
  declare ui_button $Show0
  make_persistent($Show0)
  %Show[0] := get_ui_id($Show0)
  declare ui_button $Show1
  make_persistent($Show1)
  %Show[1] := get_ui_id($Show1)
  declare ui_button $Show2
  make_persistent($Show2)
  %Show[2] := get_ui_id($Show2)
  declare ui_button $Show3
  make_persistent($Show3)
  %Show[3] := get_ui_id($Show3)
  declare ui_button $Show4
  make_persistent($Show4)
  %Show[4] := get_ui_id($Show4)
  declare ui_button $Show5
  make_persistent($Show5)
  %Show[5] := get_ui_id($Show5)
  declare ui_button $Show6
  make_persistent($Show6)
  %Show[6] := get_ui_id($Show6)
  declare ui_button $Show7
  make_persistent($Show7)
  %Show[7] := get_ui_id($Show7)
  declare ui_button $Show8
  make_persistent($Show8)
  %Show[8] := get_ui_id($Show8)
  declare ui_button $Show9
  make_persistent($Show9)
  %Show[9] := get_ui_id($Show9)
  declare ui_button $Show10
  make_persistent($Show10)
  %Show[10] := get_ui_id($Show10)
  declare ui_button $Show11
  make_persistent($Show11)
  %Show[11] := get_ui_id($Show11)
  declare ui_button $Show12
  make_persistent($Show12)
  %Show[12] := get_ui_id($Show12)
  declare ui_button $Show13
  make_persistent($Show13)
  %Show[13] := get_ui_id($Show13)

  $i := 0
  while ($i<14)
    set_control_par(%ids[$i],$CONTROL_PAR_POS_X,0)
    set_control_par(%ids[$i],$CONTROL_PAR_POS_Y,0)
    set_control_par(%ids[$i],$CONTROL_PAR_WIDTH,200)
    set_control_par(%ids[$i],$CONTROL_PAR_HEIGHT,180)
    set_control_par_str(%Show[$i],$CONTROL_PAR_TEXT,!names[$i])
    set_control_par(%Show[$i],$CONTROL_PAR_VALUE,1)
    set_control_par(%Show[$i],$CONTROL_PAR_POS_X,300)
    set_control_par(%Show[$i],$CONTROL_PAR_POS_Y,$i*20)
    inc($i)
  end while
end on

function ui__Show
  $i := 0
  while ($i<14)
    if (get_control_par(%Show[$Show__n],$CONTROL_PAR_KEY_ALT)=1)
      set_control_par(%Show[$i],$CONTROL_PAR_VALUE,get_control_par(%Show[$Show__n],$CONTROL_PAR_VALUE))
    end if
    set_control_par(%ids[$i],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL*abs(get_control_par(%Show[$i],$CONTROL_PAR_VALUE)-1))
    inc($i)
  end while
end function

on persistence_changed
  $i := 0
  while ($i<14)
    set_control_par(%ids[$i],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL*abs(get_control_par(%Show[$i],$CONTROL_PAR_VALUE)-1))
    inc($i)
  end while
end on

on ui_control($Show0)
  $Show__n := 0
  call ui__Show
end on

on ui_control($Show1)
  $Show__n := 1
  call ui__Show
end on

on ui_control($Show2)
  $Show__n := 2
  call ui__Show
end on

on ui_control($Show3)
  $Show__n := 3
  call ui__Show
end on

on ui_control($Show4)
  $Show__n := 4
  call ui__Show
end on

on ui_control($Show5)
  $Show__n := 5
  call ui__Show
end on

on ui_control($Show6)
  $Show__n := 6
  call ui__Show
end on

on ui_control($Show7)
  $Show__n := 7
  call ui__Show
end on

on ui_control($Show8)
  $Show__n := 8
  call ui__Show
end on

on ui_control($Show9)
  $Show__n := 9
  call ui__Show
end on

on ui_control($Show10)
  $Show__n := 10
  call ui__Show
end on

on ui_control($Show11)
  $Show__n := 11
  call ui__Show
end on

on ui_control($Show12)
  $Show__n := 12
  call ui__Show
end on

on ui_control($Show13)
  $Show__n := 13
  call ui__Show
end on
```


----------

