Last modifiedby & filed under KSP Scripting (NI Kontakt) - Tutorials, KSP: Custom UI (design).

In this Complex User Interface tutorial we will build a fully functional UI with multiple Screens: main screen, FX screen and about screen. Whereas the FX screen holds a sub menu for two different FX: a LoPass filter and a LoFi FX.

In this article we only create the GUI with a functional Navigation, the FX Knobs are not working! Refer to the engine par article to make them work.

You can skip this article:

  • If you are already working on Sublime and more advanced. Just move to working with macros
  • If you are on Kontakt 6. Also check out the ui_panel article which simplyfies a lot now.

Better not skip this

  • If you are new to kontakt scripting because this article still helps to better understande the other articles.

KSP Full UIHaving multiple screens in one script tab is a common way modern Kontakt user interfaces are built, giving the best usability. The downside: coding gets more complex since we have to put ALL controls (like sliders, buttons, labels, images etc) into one script tab. We also have to create multiple button actions to hide all controls & bg images of inactive screens, and show the active ones. So all controls are still there but not visible and not accessible. Since KSP is a simple language it can get very frustrating & confusing. Luckily we got macros with Sublimne 3 which makes coding a lot easier, faster and less error-prone

However in this article we work without macros, so the code is more complex as it actually would be. But this classic way helps to learn kontakt scripting better, before we move on to macros with later tutorials. But enough talking, let’s start coding now

If you are a beginner it is recommended to read the basic tutorials first.

License: This ksp script is licensed under a Creative Commons Attribution 4.0 International License.
You may use it for your projects (also commercially) and edit it as you like, as long as you keep all credits

Requirements: no requirements, the script works without sublime 3 compiling

Download all files to this tutorial premium

  • Open Resource Container: Buttons, Knobs, Wallpapers
  • NKI file: the working script

DOWNLOAD


License: This ksp script is licensed under a Creative Commons Attribution 4.0 International License.

You may use it for your projects (also commercially) and edit it as you like, as long as you keep all credits

 

Content:

1. create resource container

2. create wallpapers

3. create knobs & buttons

4. Script – init callback

5. Script – the navigation buttons (on ui_control)

6. Script – the functions (show / hide UI elements)

7. The Full Script


4. Script – init callback

on init
  set_ui_height_px(540)
  make_perfview
  set_script_title("Multiple UI")
  set_control_par_str($INST_ICON_ID,$CONTROL_PAR_PICTURE,"yb_ico"){sets your brand icon}

initialize the UI, set the basic wallpaper and make it viewable outside the script tab

{DECLARE : Global Vars}
    declare $count

declare global variables which are used throughout the whole script several times

main nav buttons for our screens (main, fx, about)

Navigation Buttons

{SET: MAIN NAV}
 declare %arr_btn_nav_main[3]
first we need an array which is holding all navigation buttons so that we can access them better later on
{constants nav main}
 declare $BTN_NAV_WIDTH := 167
 declare $BTN_NAV_HEIGHT := 39

Then we declare some constants holding the size and the width of our navigation buttons in pixels.

{btn nav main}
 $count := 0
 declare ui_switch $btn_nav_main {declares / add a button}
 make_persistent($btn_nav_main) {keeps the button's last value when closing & reopening Kontakt}
 %arr_btn_nav_main[$count] := get_ui_id($btn_nav_main) {adds the main button to your array, at position 0 since $count = 0}
 set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_PICTURE,"btn_nav_main") {sets the picture of the element 0 in your array which is the main button}
 set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_TEXT,""){removes the default button text which would be 'btn_nav_main'}
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_Y,424)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_X,20)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_WIDTH,$BTN_NAV_WIDTH)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_HEIGHT,$BTN_NAV_HEIGHT)

Now we declare the first of our navigation buttons. This one will show the main screen when clicking on it (and hide all other screens at the same time).

With set_control_par we will decline all button parameters like the button image and the position of the button. We are working with the array above. With the $count variable we can adress the specific button stored in that array. This way we can duplicate the whole code block by just changing the button variable via adjusting $count, by changing the x position ($CONTROL_PAR_POS_X),  and by changing the button image ($CONTROL_PAR_PICTURE)

{btn nav fx}
 $count := 1
 declare ui_switch $btn_nav_fx {alter the button name}
 make_persistent($btn_nav_fx)
 %arr_btn_nav_main[$count] := get_ui_id($btn_nav_fx){adds the fx button to your array, at position 1 since $count = 1 now}
 set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_PICTURE,"btn_nav_fx") {alter the button image}
 set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_TEXT,"")
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_Y,424)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_X,241) {alter the x-position}
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_WIDTH,$BTN_NAV_WIDTH)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_HEIGHT,$BTN_NAV_HEIGHT)

as said we can now copy the whole code block for each of the other nav buttons. We simply need to alter the button name, $count, x-position and  the button image.
This is a place where macros would come in very handy to save some lines of code

{btn nav about}
 $count := 2
 declare ui_switch $btn_nav_about {alter the button name}
 make_persistent($btn_nav_about)
 %arr_btn_nav_main[$count] := get_ui_id($btn_nav_about)
 set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_PICTURE,"btn_nav_about") {alter the button image}
 set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_TEXT,"")
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_Y,424)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_X,447) {alter the x-position}
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_WIDTH,$BTN_NAV_WIDTH)
 set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_HEIGHT,$BTN_NAV_HEIGHT)

 

premium content

sub nav for the FX Types (Lopass & LoFi FX)

FX Navigation 

{SET: SUBNAV}
 declare %arr_btn_subnav[2] {new array}
 
{constants sub nav}
 declare $BTN_SUBNAV_WIDTH := 81 {new constant}
 declare $BTN_SUBNAV_HEIGHT := 81 {new constant}
$count := 0
 declare ui_switch $btn_nav_lopass
 %arr_btn_subnav[$count] := get_ui_id($btn_nav_lopass)
 set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_PICTURE,"btn_nav_lopass")
 set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_TEXT,"")
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_Y,308) {new y-position}
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_X,211) {new x-position}
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_WIDTH,$BTN_SUBNAV_WIDTH)
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_HEIGHT,$BTN_SUBNAV_HEIGHT)

this is almost the same code like with the main nav buttons. Since we are using different images for the FX Navigation we have to use differentt constants for a new width and height.

Also the x and y position is different now. We also need new variables and a new array holding the button id’s. The array itself works the same.

$count := 1
 declare ui_switch $btn_nav_lofi
 %arr_btn_subnav[$count] := get_ui_id($btn_nav_lofi)
 set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_PICTURE,"btn_nav_lofi")
 set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_TEXT,"")
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_Y,308)
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_X,347)
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_WIDTH,$BTN_SUBNAV_WIDTH)
 set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_HEIGHT,$BTN_SUBNAV_HEIGHT)

Wallpapers / Background Images for all screens

The wallpaper for the main screen will be our init wallpaper. The other two wallpapers will be set as label and overlay the init wallpaper (read more in this tutorial)

   {SET: WALLPAPERS}
     declare @wp_init
     declare @wp_about
     declare @wp_fx
     @wp_init := "bg_main"
     @wp_about := "bg_about"
     @wp_fx := "bg_fx"

    set_control_par_str($INST_WALLPAPER_ID,$CONTROL_PAR_PICTURE,@wp_init) {sets the initial wallpaper which is 608 pixel high}
    declare %arr_wp[2]

first we set some string variables which are holding the file names of our wallpapers. The init wallpaper is set quickly via set_control_par_str($INST_WALLPAPER_ID,$CONTROL_PAR_PICTURE,@wp_init)

The other two wallpapers (fx and about screen) will overlay our initital wallpaper by getting visible or hidden on specific navigation actions of which more below.

{wp fx}
    $count := 0

    declare ui_label $lbl_wp_fx(1, 1)
    %arr_wp[$count] := get_ui_id($lbl_wp_fx)
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_PICTURE,"bg_fx"){sets image}
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_TEXT,"")
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_Y,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_X,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_WIDTH,632){full size width}
    set_control_par(%arr_wp[$count], $CONTROL_PAR_HEIGHT,540){full size height}
    read_persistent_var($btn_nav_fx) {get the last state of the FX nav button from the last Kontakt session}

    if(get_control_par(%arr_btn_nav_main[1] ,$CONTROL_PAR_VALUE) # 1) {check if FX nav button is pressed}
        set_control_par(%arr_wp[$count], $CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    end if

{wp about}
    $count := 1

    declare ui_label $lbl_wp_about(1, 1)
    %arr_wp[$count] := get_ui_id($lbl_wp_about)
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_PICTURE,"bg_about")
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_TEXT,"")
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_Y,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_X,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_WIDTH,632)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_HEIGHT,540)
    read_persistent_var($btn_nav_about) {get the last state of the about nav button from the last Kontakt session}

    if(get_control_par(%arr_btn_nav_main[2], $CONTROL_PAR_VALUE) # 1){check if about nav button is pressed}
        set_control_par(%arr_wp[$count], $CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    end if

we declare a label for the overlaying FX wallpaper. Again we are using an array to better access the wallpapers.

The position of all wallpapers is x=0px and y=0p

if(get_control_par(%arr_btn_nav_main[2], $CONTROL_PAR_VALUE) # 1) Checks if the FX nav button is pressed, since we only want to show the overlaying fx wallpaper when this is true. Otherwise we want to hide the wallpaper

The FX Controls (Knobs, labels buttons)

Now we set up the knobs for the lofi and lopass FX. Of course you can also add own FX and knobs. The code pattern is always the same.

FX Controls
{SET: FX Controls}
 {constants for fx controls}
 declare $UNIT_FX_WIDHT := 80
 declare $KNOB_FX_WIDHT := 36
 declare $KNOB_FX_HEIGHT := 36
 declare $KNOB_FX_SPACER := 12
 declare $KNOB_FX_POS_Y := 200
Calculacte Block Center

All constants we need for this segment.

$UNIT_FX_WIDHT the width of one knob unit, defined by the largest item. In this case the top and bottom labels.

$KNOB_FX_WIDHT the width of one knob

$KNOB_FX_HEIGHT the height of one knob

$KNOB_FX_SPACER with this we cane adjust the distance from one knob unit to another, later on

$KNOB_FX_POS_Y with this we can vertically position the whole knob block later on by jsut adjusting this constant

declare $knob_center 
$knob_center := ($UNIT_FX_WIDHT - $KNOB_FX_WIDHT)/2 {calucaltion to center align the knob unit based on the label width}

Center UnitThe Knob’s label (like bits, samplerate,..) the Knob itself, and the display below are forming one unit.

The label (width = 80px) is wider than the knob (width = 36 px) so we want to calculate an indent for the knob’s indent to center them all relatively to the label.

We only need the left indent for centering the knobs, so we subtract the knobs width (36px) from the total width (80px) and divide the result by 2 (80px - 36px)/2 = 22

declare $number_of_knobs {the amount of knobs inside the fx block eg. lopass filter has 2 knobs}
declare $knob_block_center {variable to indent the whole knob block so that it is centered depending on how many knobs are inside the unit (total width)}

{SET : LOFI FX CONTROLS}
    declare %arr_fx_knob_lofi[4] {array holding all knob id's}
    declare %arr_fx_lbl_lofi[4] {array holding all label id's}
    declare %arr_fx_lbl_lofi_val[4] {array holding all display id's}

    $number_of_knobs := 4 {4 knobs for the lofi FX}
    $knob_block_center := (632 - ($UNIT_FX_WIDHT + $KNOB_FX_SPACER) * $number_of_knobs)/2 {calcualtes the spacer in pixels to center the knobs block}

Calculacte Block Center now we want to center the whole fx block relating to the full UI width which is 632px. So we have to sum all unit widths plus all spacer widths between the units. Then we subtract this value from the total UI width and divide it by 2: (total UI width - (unit width + spacer width) * unit amount)  / 2.

You may have noticed that we now added one spacer too much. Actually it’s only 3 spacer not 4 so you can alter your calculation like this if you want to do it exactly:
(total_width – (unit_width * unit_amount) + (spacer_width * (unit_amount – 1)) )  / 2

 

{BITS UNIT}
  {--knob}
  $count := 0
  declare ui_slider $knob_lofi_bits(0, 1000000)
  %arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_bits)
  set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
  set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
  set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
  set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)

Now we decalre the LoFi  Knobs (bits, samplerate , noise, color). Like with the nav buttons we first declare the actual knob build the array to adress it and set all the values like knob picture.

$CONTROL_PAR_MOUSE_BEHAVIOUR indicates how the knob reacts on mouse movements in this case it only reacts on vertical movements. Also read this  tutorial

{--label top}
$count := 0
declare ui_label $lbl_lofi_bits(1, 1)
%arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_bits)
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_bits")
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

UI LabelsThe top label for the knob’s name. The values are almost identical to the knobs values except x & y position and the picture.

For the y position we take the Knob’s y position but subtract a few pixels to move it above the knob. You can do it approximately since one or more pixel more or less don’t hurt. In this case it’s -24px  set_control_par(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y- 2 4).

set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

For the x-position we calculate take the whole unit’s point of origin with a simple sum:
block_indent_to_center + (unit_with + spacer) * actual_knob_starting_with_0

{--label bottom}
declare ui_label $lbl_lofi_bits_val(1, 1)
%arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_bits_val)
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count) 

set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4) {auto positions the label below the knob}

The bottom label code is pretty identical to the top label code except the y-position which moves the label below the knob now.

For this we do some math again:
knob_point_of_origin + knob_height + extra_spacer

$KNOB_FX_POS_Y + $KNOB_FX_HEIGHT + 4

Now we just declare the rest of the units which is the identical code so we can just copy & paste it. We only need to increase $count for calculations and addressing the next unit:

{SAMPLERATE UNIT}
{--knob}
$count := 1
declare ui_slider $knob_lofi_srate(0, 1000000)
%arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_srate)
set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
{--label top}
$count := 1
declare ui_label $lbl_lofi_srate(1, 1)
%arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_srate)
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_srate")
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
{--label bottom}
declare ui_label $lbl_lofi_srate_val(1, 1)
%arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_srate_val)
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)


{NOISE UNIT}
$count := 2
{--knob}
declare ui_slider $knob_lofi_noise(0, 1000000)
%arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_noise)
set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
{--label top}
declare ui_label $lbl_lofi_noise(1, 1)
%arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_noise)
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_noise")
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
{--label bottom}
declare ui_label $lbl_lofi_noise_val(1, 1)
%arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_noise_val)
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

{COLOR UNIT}
$count := 3 {stands for the 4th unit}
{--knob}		
declare ui_slider $knob_lofi_color(0, 1000000)
%arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_color)
set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
{--label top}
declare ui_label $lbl_lofi_color(1, 1)
%arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_color)
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_color")
set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
{--label bottom}
declare ui_label $lbl_lofi_color_val(1, 1)
%arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_color_val)
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

 NOTE: The LoPass Block isn’t shown since it’s the exact same code scheme (but you can see it in the full code below)

hiding all controls & elements (which are not active)

{HIDE CONTROLS}
    if ($btn_nav_fx # 1)
        {subnav}
            $count:=0
            while($count < num_elements(%arr_btn_subnav))
                set_control_par(%arr_btn_subnav[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
                inc($count)
            end while
        {fx}
            {hide all lopass knobs}
            $count := 0
            while ($count < num_elements(%arr_fx_knob_lopass))
                set_control_par(%arr_fx_knob_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
                inc($count)
            end while
            {hide all lopass top labels}
            $count := 0
            while ($count < num_elements(%arr_fx_lbl_lopass))
                set_control_par(%arr_fx_lbl_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
                inc($count)
            end while
            {hide all lopass bottom labels}
            $count := 0
            while ($count < num_elements(%arr_fx_lbl_lopass_val))
                set_control_par(%arr_fx_lbl_lopass_val[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
                inc($count)
            end while
            {hide all lofi knobs}
            $count := 0
            while ($count < num_elements(%arr_fx_knob_lofi))
                set_control_par(%arr_fx_knob_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
                inc($count)
            end while
            {hide all lofi top labels}
            $count := 0
            while ($count < num_elements(%arr_fx_lbl_lofi))
                set_control_par(%arr_fx_lbl_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
                inc($count)
            end while
            {hide all lofi bottom labels}
            $count := 0
            while ($count < num_elements(%arr_fx_lbl_lofi_val))
                set_control_par(%arr_fx_lbl_lofi_val[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
                inc($count)
            end while
    end if

for this we simply move through each array with a while loop to hide all controls.

This is where macros are come in very handy since with this method you have to add all additional knobs in here as well, in case you wann do more fx or add other buttons.

Of course you could also do one big array matrix holding all knobs and labels

5. script – the navigation buttons (on ui_control)

unfortunately we need to be a little confusing now. Becasue actually we need some functions which are only explained in chapter 6

but don’t worry just paste the functions from chapter 6 at this place. This is because we have to declare functions before we call them. But for a better understanding we will explain the on ui control first.

function hide_all
  ...
end function
 
function show_main
  ...
end function
 
function show_main
  ...
end function

bringing the nav buttons to life

{main nav}
on ui_control($btn_nav_main)
    call hide_all {hides all elemnts and sets all buttons to 0 (including this button)}
    call show_main {shows the corresponding elements again including bg-wallpaper}
    $btn_nav_main := 1 {sets this button active again}
end on
 
on ui_control($btn_nav_fx)
    call hide_all
    call show_fx
    $btn_nav_fx := 1
end on
 
on ui_control($btn_nav_about)
    call hide_all
    call show_about
    $btn_nav_about := 1
end on
 
{fx nav / subnav}
on ui_control ($btn_nav_lofi)
    call hide_all
    $btn_nav_lofi := 1
    $btn_nav_fx := 1
    call show_fx
end on
 
on ui_control ($btn_nav_lopass)
    call hide_all
    $btn_nav_lopass := 1
    $btn_nav_fx := 1
    call show_fx
end on

With the on ui_control we can define actions which get called whenever the related nav button is hit. Thereby we will call several functions to hide or show our screens depenidng on which button is pressed.

For this we call the hide_all functions which hides (surprisingly)  ALL ui elements and wallpapers without exceptions.

After this function we call te nav related function which shows again only the specific elements for the related screen

At last we set the pressed nav button to 1 agin. Because with the hide_all function all buttons are set to 0 (off status). This is necessary because we don’t want two or more nav buttons to be in pressed state at the same time.

6. script – the functions (show / hide UI elements)

function hide_all
    $btn_nav_main := 0
    $btn_nav_fx := 0 
    $btn_nav_about := 0 
    $btn_nav_lopass := 0 
    $btn_nav_lofi := 0

This is the hide_all function. Each time we add new controls to our UI we also have to update this function.

First we set all navigation buttons to 0. Because like said when clicking a nav button all other buttons should be set to non-pressed status.

Important: we have to declare the functions before we call them. So simply paste them before the “on ui controls.” (see above)

    $count := 0
    while ($count < num_elements(%arr_wp))
            set_control_par(%arr_wp[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL) {hides each element of %arr_wp}
            inc ($count)
    end while
end function

Then we need to “walk thorugh” each ui array we have assigend before to hide all controls. We do this via while loops.

set_control_par(%arr_wp[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL) hides each element inside the array %arr_wp.

Remember we have different arrays for different UI elemnts so we really need to do this for any UI array we created:

%arr_wp %arr_btn_subnav %arr_fx_knob_lopass %arr_fx_lbl_lopass %arr_fx_lbl_lopass_val %arr_fx_knob_lofi %arr_fx_lbl_lofi %arr_fx_lbl_lofi_val

The hide_all function

function hide_all
    $btn_nav_main := 0
    $btn_nav_fx := 0
    $btn_nav_about := 0
    $btn_nav_lopass := 0
    $btn_nav_lofi := 0
    {wallpapers}
    $count := 0
    while ($count < num_elements(%arr_wp))
        set_control_par(%arr_wp[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
        inc ($count)
    end while
 
    {subnav}
    $count:=0
    while($count < num_elements(%arr_btn_subnav))
        set_control_par(%arr_btn_subnav[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
        inc($count)
    end while
 
    {fx controls}
    $count := 0
    while ($count < num_elements(%arr_fx_knob_lopass))
        set_control_par(%arr_fx_knob_lopass[$count], CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
    end while
 
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lopass))
        set_control_par(%arr_fx_lbl_lopass[$count], CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
    end while
 
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lopass_val))
        set_control_par(%arr_fx_lbl_lopass_val[$count], CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
    end while
 
    $count := 0
    while ($count < num_elements(%arr_fx_knob_lofi))
        set_control_par(%arr_fx_knob_lofi[$count], CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
    end while
 
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lofi))
        set_control_par(%arr_fx_lbl_lofi[$count], CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
    end while
 
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lofi_val))
        set_control_par(%arr_fx_lbl_lofi_val[$count], CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
    end while
end function

show main screen function

function show_main
    while ($count < num_elements(%arr_wp))
        set_control_par(%arr_wp[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL) {hides all label wallpapers which are already hidden actually}
        inc ($count)
    end while
end function

In our case this function isn’t neccessarily required, since the main screen only contains the initial wallpaper which is always visible and all other controls get already hidden by the hide_all function. But usually your init screen isn’t empty so just fill this function with your elements.

we skip the show about screen function since in this case its exactly the same except the

show about screen function

function show_about
  {SHOW WALLPAPER}
  set_control_par(%arr_wp[1],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
end function

In our case this function is also very simple since we only load a separate overlaying wallpaer showing all our credits within the wallpaper iamge itself:

set_control_par(%arr_wp[1],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)

show fx function

Buttons Subnav 2Remember the FX screen has a sub nav, so two buttons for the LoPass & LoFi FX.

function show_fx
    {SHOW WALLPAPER}
    set_control_par(%arr_wp[0],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
    {SHOW SUBNAV BUTTONS}
    $count:=0
    while($count < num_elements(%arr_btn_subnav))
        set_control_par(%arr_btn_subnav[$count],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
        inc($count)
    end while
 
    {SHOW LOPASS}
    if($btn_nav_lopass = 1)
        {--knob}
        $count := 0
        while ($count < num_elements(%arr_fx_knob_lopass))
            set_control_par(%arr_fx_knob_lopass[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
            inc($count)
        end while
        {--lbl top}
        $count := 0
        while ($count < num_elements(%arr_fx_lbl_lopass))
            set_control_par(%arr_fx_lbl_lopass[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
            inc($count)
        end while
        {--lbl bottom}
        $count := 0
        while ($count < num_elements(%arr_fx_lbl_lopass_val))
            set_control_par(%arr_fx_lbl_lopass_val[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
            inc($count)
        end while
    end if
 
    {SHOW LOFI}
    if($btn_nav_lofi = 1)
        {--knob}
        $count := 0
        while ($count < num_elements(%arr_fx_knob_lofi))
            set_control_par(%arr_fx_knob_lofi[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
            inc($count)
        end while
        {--lbl top}
        $count := 0
        while ($count < num_elements(%arr_fx_lbl_lofi))
            set_control_par(%arr_fx_lbl_lofi[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
            inc($count)
        end while
        {--lbl bottom}
        $count := 0
        while ($count < num_elements(%arr_fx_lbl_lofi_val))
            set_control_par(%arr_fx_lbl_lofi_val[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
            inc($count)
        end while    
    end if    
end function

this function checks which subnav button is currently pressed to show the specific fx screen (with all its elements). Again we walk through all related arrays via while loops but in this case we show the UI elements via $HIDE_PART_NOTHING:  set_control_par(%arr_fx_knob_lopass[$count], CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)

Also we must not forget to show the correct background wallpaper for the FX screen:
set_control_par(%arr_wp[0],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)

That’s it! If you got any questions use the comments below or contact us

7. The Full Script

{#####################################################################################
This script is licensed under a Creative Commons Attribution 4.0 International License.
http://creativecommons.org/licenses/by/4.0/

Author: Björn Friese
Web: yummybeats.com

- more KSP tutorials at blog.yummybeats.com
#######################################################################################}
on init 
  {INIT UI}
      set_ui_height_px(540)
      make_perfview
      set_script_title("Multiple UI")
      set_control_par_str($INST_ICON_ID,$CONTROL_PAR_PICTURE,"yb_ico")

  {DECALRE : BG WALLPAPERS}


  {DECLARE : Global Vars}
    declare $count
      declare $this
      declare $a
      declare $b
      declare $font_1 := 4
      declare $active_screen

{SET: MAIN NAV}
  declare %arr_btn_nav_main[3]
  {constants nav main}
  declare $BTN_NAV_WIDTH := 167
  declare $BTN_NAV_HEIGHT := 39

  {btn nav main}
  $count := 0
  declare ui_switch $btn_nav_main
  make_persistent($btn_nav_main)
  %arr_btn_nav_main[$count] := get_ui_id($btn_nav_main)
  set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_PICTURE,"btn_nav_main")
  set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_TEXT,"")
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_Y,424)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_X,20)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_WIDTH,$BTN_NAV_WIDTH)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_HEIGHT,$BTN_NAV_HEIGHT)

  {btn nav fx}
  $count := 1
  declare ui_switch $btn_nav_fx
  make_persistent($btn_nav_fx)
  %arr_btn_nav_main[$count] := get_ui_id($btn_nav_fx)
  set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_PICTURE,"btn_nav_fx")
  set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_TEXT,"")
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_Y,424)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_X,241)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_WIDTH,$BTN_NAV_WIDTH)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_HEIGHT,$BTN_NAV_HEIGHT)

  {btn nav about}
  $count := 2
  declare ui_switch $btn_nav_about
  make_persistent($btn_nav_about)
  %arr_btn_nav_main[$count] := get_ui_id($btn_nav_about)
  set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_PICTURE,"btn_nav_about")
  set_control_par_str(%arr_btn_nav_main[$count],$CONTROL_PAR_TEXT,"")
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_Y,424)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_POS_X,447)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_WIDTH,$BTN_NAV_WIDTH)
  set_control_par(%arr_btn_nav_main[$count], $CONTROL_PAR_HEIGHT,$BTN_NAV_HEIGHT)

  {SET: SUBNAV}
    declare %arr_btn_subnav[2]
    {constants nav main}
    declare $BTN_SUBNAV_WIDTH := 81
    declare $BTN_SUBNAV_HEIGHT := 81

    $count := 0
    declare ui_switch $btn_nav_lopass
    %arr_btn_subnav[$count] := get_ui_id($btn_nav_lopass)
    set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_PICTURE,"btn_nav_lopass")
    set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_TEXT,"")
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_Y,308)
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_X,211)
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_WIDTH,$BTN_SUBNAV_WIDTH)
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_HEIGHT,$BTN_SUBNAV_HEIGHT)

    $count := 1
    declare ui_switch $btn_nav_lofi
    %arr_btn_subnav[$count] := get_ui_id($btn_nav_lofi)
    set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_PICTURE,"btn_nav_lofi")
    set_control_par_str(%arr_btn_subnav[$count],$CONTROL_PAR_TEXT,"")
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_Y,308)
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_POS_X,347)
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_WIDTH,$BTN_SUBNAV_WIDTH)
    set_control_par(%arr_btn_subnav[$count], $CONTROL_PAR_HEIGHT,$BTN_SUBNAV_HEIGHT)



  {SET: WALLPAPERS}
    declare @wp_init
      declare @wp_about
      declare @wp_fx
      @wp_init := "bg_main"
      @wp_about := "bg_about"
      @wp_fx := "bg_fx"

      set_control_par_str($INST_WALLPAPER_ID,$CONTROL_PAR_PICTURE,@wp_init)
    declare %arr_wp[2]
  
    {wp fx}
    $count := 0
    declare ui_label $lbl_wp_fx(1, 1)
    %arr_wp[$count] := get_ui_id($lbl_wp_fx)
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_PICTURE,"bg_fx")
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_TEXT,"")
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_Y,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_X,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_WIDTH,632)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_HEIGHT,540)
    read_persistent_var($btn_nav_fx)
    if(get_control_par(%arr_btn_nav_main[1],$CONTROL_PAR_VALUE) # 1)
      set_control_par(%arr_wp[$count], $CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    end if

    {wp about}
    $count := 1
    declare ui_label $lbl_wp_about(1, 1)
    %arr_wp[$count] := get_ui_id($lbl_wp_about)
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_PICTURE,"bg_about")
    set_control_par_str(%arr_wp[$count],$CONTROL_PAR_TEXT,"")
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_Y,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_POS_X,0)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_WIDTH,632)
    set_control_par(%arr_wp[$count], $CONTROL_PAR_HEIGHT,540)
    read_persistent_var($btn_nav_about)
    if(get_control_par(%arr_btn_nav_main[2],$CONTROL_PAR_VALUE) # 1)
      set_control_par(%arr_wp[$count], $CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    end if

  {SET: FX Controls}		
    {constants fx controls}
    declare $UNIT_FX_WIDHT := 80
    declare $KNOB_FX_WIDHT := 36
    declare $KNOB_FX_HEIGHT := 36
    declare $KNOB_FX_SPACER := 12
    declare $KNOB_FX_POS_Y := 200

    declare $knob_center
    $knob_center := ($UNIT_FX_WIDHT - $KNOB_FX_WIDHT)/2 {calucaltion to center align the knob unit based on the label width}
    
    declare $number_of_knobs {the amnount of knobs inside the knobs block eg. lopass filter has 2 knobs}
    declare $knob_block_center {variable to indent the whole knobs block so that it is centered depending on how many knobs are inside the unit (total width)}

    {SET : LOPASS FX CONTROLS}
      declare %arr_fx_knob_lopass[2]
      declare %arr_fx_lbl_lopass[2]
      declare %arr_fx_lbl_lopass_val[2]
      $number_of_knobs := 2 {two knobs for the lopass fx}
      $knob_block_center := (632 - ($UNIT_FX_WIDHT + $KNOB_FX_SPACER) * $number_of_knobs)/2 {math to get the indent pixels to center the block.}
      
      {CUTOFF UNIT}
        $count := 0
        {--knob}
        declare ui_slider $knob_lopass_cutoff(0, 1000000)
        %arr_fx_knob_lopass[$count] := get_ui_id($knob_lopass_cutoff)
        set_control_par_str(%arr_fx_knob_lopass[$count], $CONTROL_PAR_PICTURE,"knob_fx")
        set_control_par(%arr_fx_knob_lopass[$count], $CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
        set_control_par(%arr_fx_knob_lopass[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count + $knob_center)
        set_control_par(%arr_fx_knob_lopass[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
        {--label top}
        declare ui_label $lbl_lopass_cutoff(1, 1)
        %arr_fx_lbl_lopass[$count] := get_ui_id($lbl_lopass_cutoff)
        set_control_par_str(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_PICTURE,"lbl_cutoff")
        set_control_par_str(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_TEXT,"")
        set_control_par(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
        set_control_par(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
        {--label bottom}
        declare ui_label $lbl_lopass_cutoff_val(1, 1)
        %arr_fx_lbl_lopass_val[$count] := get_ui_id($lbl_lopass_cutoff_val)
        set_control_par_str(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
        set_control_par_str(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_TEXT,"")
        set_control_par(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y+$KNOB_FX_HEIGHT+4)
        set_control_par(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

      {RESONANCE UNIT}
        $count := 1
        {--knob}
        declare ui_slider $knob_lopass_reso(0, 1000000)
        %arr_fx_knob_lopass[$count] := get_ui_id($knob_lopass_reso)
        set_control_par_str(%arr_fx_knob_lopass[$count],$CONTROL_PAR_PICTURE,"knob_fx")
        set_control_par(%arr_fx_knob_lopass[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
        set_control_par(%arr_fx_knob_lopass[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
        {--label top}
        declare ui_label $lbl_lopass_reso(1, 1)
        %arr_fx_lbl_lopass[$count] := get_ui_id($lbl_lopass_reso)
        set_control_par_str(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_PICTURE,"lbl_reso")
        set_control_par_str(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_TEXT,"")
        set_control_par(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
        set_control_par(%arr_fx_lbl_lopass[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
        {--label bottom}
        declare ui_label $lbl_lopass_reso_val(1, 1)
        %arr_fx_lbl_lopass_val[$count] := get_ui_id($lbl_lopass_reso_val)
        set_control_par_str(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
        set_control_par_str(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_TEXT,"")
        set_control_par(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
        set_control_par(%arr_fx_lbl_lopass_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)



    {SET : LOFI FX CONTROLS}
      declare %arr_fx_knob_lofi[4]
      declare %arr_fx_lbl_lofi[4]
      declare %arr_fx_lbl_lofi_val[4]
      $number_of_knobs := 4 {4 knobs for the lofi FX}
      $knob_block_center := (632 - ($UNIT_FX_WIDHT + $KNOB_FX_SPACER) * $number_of_knobs)/2 {calcualtes the spacer in pixels to center the knobs block}

      {BITS UNIT}
      {--knob}
      $count := 0
      declare ui_slider $knob_lofi_bits(0, 1000000)
      %arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_bits)
      set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
      {--label top}
      $count := 0
      declare ui_label $lbl_lofi_bits(1, 1)
      %arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_bits)
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_bits")
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
      {--label bottom}
      declare ui_label $lbl_lofi_bits_val(1, 1)
      %arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_bits_val)
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

      {SRATE UNIT}
      {--knob}
      $count := 1
      declare ui_slider $knob_lofi_srate(0, 1000000)
      %arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_srate)
      set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
      {--label top}
      $count := 1
      declare ui_label $lbl_lofi_srate(1, 1)
      %arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_srate)
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_srate")
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
      {--label bottom}
      declare ui_label $lbl_lofi_srate_val(1, 1)
      %arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_srate_val)
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)


      {NOISE}
      $count := 2
      {--knob}
      declare ui_slider $knob_lofi_noise(0, 1000000)
      %arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_noise)
      set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
      {--label top}
      declare ui_label $lbl_lofi_noise(1, 1)
      %arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_noise)
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_noise")
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
      {--label bottom}
      declare ui_label $lbl_lofi_noise_val(1, 1)
      %arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_noise_val)
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)

      {COLOR UNIT}
      $count := 3 {stands for the 4th unit}
      {--knob}		
      declare ui_slider $knob_lofi_color(0, 1000000)
      %arr_fx_knob_lofi[$count] := get_ui_id($knob_lofi_color)
      set_control_par_str(%arr_fx_knob_lofi[$count],$CONTROL_PAR_PICTURE,"knob_fx")
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT  + $KNOB_FX_SPACER)*$count + $knob_center)
      set_control_par(%arr_fx_knob_lofi[$count],$CONTROL_PAR_MOUSE_BEHAVIOUR, -400)
      {--label top}
      declare ui_label $lbl_lofi_color(1, 1)
      %arr_fx_lbl_lofi[$count] := get_ui_id($lbl_lofi_color)
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_PICTURE,"lbl_color")
      set_control_par_str(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y-24)
      set_control_par(%arr_fx_lbl_lofi[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)
      {--label bottom}
      declare ui_label $lbl_lofi_color_val(1, 1)
      %arr_fx_lbl_lofi_val[$count] := get_ui_id($lbl_lofi_color_val)
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_PICTURE,"lbl_value")
      set_control_par_str(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_TEXT,"")
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_Y, $KNOB_FX_POS_Y + $KNOB_FX_HEIGHT+4)
      set_control_par(%arr_fx_lbl_lofi_val[$count],$CONTROL_PAR_POS_X, $knob_block_center + ($UNIT_FX_WIDHT + $KNOB_FX_SPACER)*$count)


  {HIDE CONTROLS}
  if ($btn_nav_fx # 1)
    {subnav}
      $count:=0
      while($count < num_elements(%arr_btn_subnav))
        set_control_par(%arr_btn_subnav[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
        inc($count)
      end while
    {fx}
      {hide all lopass knobs}
      $count := 0
      while ($count < num_elements(%arr_fx_knob_lopass))
        set_control_par(%arr_fx_knob_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
      end while
      {hide all lopass top labels}
      $count := 0
      while ($count < num_elements(%arr_fx_lbl_lopass))
        set_control_par(%arr_fx_lbl_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
      end while
      {hide all lopass bottom labels}
      $count := 0
      while ($count < num_elements(%arr_fx_lbl_lopass_val))
        set_control_par(%arr_fx_lbl_lopass_val[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
      end while
      {hide all lofi knobs}
      $count := 0
      while ($count < num_elements(%arr_fx_knob_lofi))
        set_control_par(%arr_fx_knob_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
      end while
      {hide all lofi top labels}
      $count := 0
      while ($count < num_elements(%arr_fx_lbl_lofi))
        set_control_par(%arr_fx_lbl_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
      end while
      {hide all lofi bottom labels}
      $count := 0
      while ($count < num_elements(%arr_fx_lbl_lofi_val))
        set_control_par(%arr_fx_lbl_lofi_val[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
        inc($count)
      end while
  end if

{SET : HEADLINE}
  declare ui_label $headline(1, 1)
  set_control_par(get_ui_id($headline),$CONTROL_PAR_POS_X,0)
  set_control_par(get_ui_id($headline),$CONTROL_PAR_POS_Y,26)
  set_control_par_str(get_ui_id($headline),$CONTROL_PAR_PICTURE,"lbl_head")
  set_control_par(get_ui_id($headline),$CONTROL_PAR_WIDTH,632)
  set_control_par(get_ui_id($headline),$CONTROL_PAR_HEIGHT,44)
  set_control_par_str(get_ui_id($headline),$CONTROL_PAR_TEXT,"")
end on

function hide_all
  $btn_nav_main := 0
  $btn_nav_fx := 0
  $btn_nav_about := 0
  $btn_nav_lopass := 0
  $btn_nav_lofi := 0
  {wallpapers}
  $count := 0
  while ($count < num_elements(%arr_wp))
    set_control_par(%arr_wp[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    inc ($count)
  end while

  {subnav}
  $count:=0
  while($count < num_elements(%arr_btn_subnav))
    set_control_par(%arr_btn_subnav[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    inc($count)
  end while

  {fx controls}
  $count := 0
  while ($count < num_elements(%arr_fx_knob_lopass))
    set_control_par(%arr_fx_knob_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
    inc($count)
  end while

  $count := 0
  while ($count < num_elements(%arr_fx_lbl_lopass))
    set_control_par(%arr_fx_lbl_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
    inc($count)
  end while

  $count := 0
  while ($count < num_elements(%arr_fx_lbl_lopass_val))
    set_control_par(%arr_fx_lbl_lopass_val[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
    inc($count)
  end while

  $count := 0
  while ($count < num_elements(%arr_fx_knob_lofi))
    set_control_par(%arr_fx_knob_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
    inc($count)
  end while

  $count := 0
  while ($count < num_elements(%arr_fx_lbl_lofi))
    set_control_par(%arr_fx_lbl_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
    inc($count)
  end while

  $count := 0
  while ($count < num_elements(%arr_fx_lbl_lofi_val))
    set_control_par(%arr_fx_lbl_lofi_val[$count], $CONTROL_PAR_HIDE, $HIDE_WHOLE_CONTROL)
    inc($count)
  end while
end function

function show_main
  while ($count < num_elements(%arr_wp))
    set_control_par(%arr_wp[$count],$CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)
    inc ($count)
  end while
end function

function show_fx
  {SHOW WALLPAPER}
  set_control_par(%arr_wp[0],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
  {SHOW SUBNAV BUTTONS}
  $count:=0
  while($count < num_elements(%arr_btn_subnav))
    set_control_par(%arr_btn_subnav[$count],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
    inc($count)
  end while

  {SHOW LOPASS}
  if($btn_nav_lopass = 1)
    {--knob}
    $count := 0
    while ($count < num_elements(%arr_fx_knob_lopass))
      set_control_par(%arr_fx_knob_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
      inc($count)
    end while
    {--lbl top}
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lopass))
      set_control_par(%arr_fx_lbl_lopass[$count], $CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
      inc($count)
    end while
    {--lbl bottom}
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lopass_val))
      set_control_par(%arr_fx_lbl_lopass_val[$count], $CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
      inc($count)
    end while
  end if

  {SHOW LOFI}
  if($btn_nav_lofi = 1)
    {--knob}
    $count := 0
    while ($count < num_elements(%arr_fx_knob_lofi))
      set_control_par(%arr_fx_knob_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
      inc($count)
    end while
    {--lbl top}
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lofi))
      set_control_par(%arr_fx_lbl_lofi[$count], $CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
      inc($count)
    end while
    {--lbl bottom}
    $count := 0
    while ($count < num_elements(%arr_fx_lbl_lofi_val))
      set_control_par(%arr_fx_lbl_lofi_val[$count], $CONTROL_PAR_HIDE, $HIDE_PART_NOTHING)
      inc($count)
    end while	
  end if	
end function

function show_about
  {SHOW WALLPAPER}
  set_control_par(%arr_wp[1],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
end function

on ui_control($btn_nav_main)
  call hide_all
  call show_main
  $btn_nav_main := 1
end on

on ui_control($btn_nav_fx)
  call hide_all
  call show_fx
  $btn_nav_fx := 1
end on

on ui_control($btn_nav_about)
  call hide_all
  call show_about
  $btn_nav_about := 1
end on

on ui_control ($btn_nav_lofi)
  call hide_all
  $btn_nav_lofi := 1
  $btn_nav_fx := 1
  call show_fx
end on

on ui_control ($btn_nav_lopass)
  call hide_all
  $btn_nav_lopass := 1
  $btn_nav_fx := 1
  call show_fx
end on

How useful was this article?

We are sorry that this post was not useful for you!

Let us improve this post!

13 Responses to “Kontakt Scripting (KSP) :: Custom UI :: Complex User Interface with multiple Screens/Menus inside one Script Tab”

  1. Matt

    Hi there, I've been through the premium articles for this and macros but seeing as this doesn't use macros I can't figure out how to enable the required functions for each knob/slider. Any help would be appreciated Thanks, it's been a big help so far!

    • YummyBeats

      Thx! I'm not sure if I got this right. In case you want to make all knobs functional you can read this article If you just like to shorten your code and speed up your workflow with sublime 3 you can read this article Macros themselves can rather be considered as helper or code factories. If you have lots of repeating code structures you can use them to "print out" those structures again and again. Thereby you can modify the "printed code" a little for example by declaring variables with different names etc. This all is explained in the working with macros article (which you already read, I guess). I hope this still helps, although you said you got it already :) If you got any further questions just let me know.

      • Matthew

        Thanks, as I said I was being a bit slow, had made a simple error. What I'm trying to figure out now is how to add and AHDSR to the home page. I have the code appearing and no complaints from the script editor. The only problem is the AHDSR is constantly showing. I'm trying to have it show on the main home page, and disappear when I hit the FX or about buttons. Is there a simple way of doing that?

        • YummyBeats

          Actually it should hide like shown in the demo video. How about the included nki? This is already the easiest way I can imagine. However this tutorial is working directly without sublime 3 compiling so it seems to be more (complex) code then it would look like with sublime 3. I will send you a pm with some sublime 3 example code later on.

  2. Serge GORA

    Hello _ The effect commands are not assigned in this Script (Lo-fi and filter SV LP4). There are the control buttons but they do not affect the parameters of the concerned effects. The "on ui_control" part for these commands is absent. For the resonace commande (Filter), the CONTROL_PAR_MOUSE_BEHAVIOUR is forgotten . Best . _ Serge _

    • YummyBeats

      yes, sorry, this is only about the visual functionality to not bloat the article any further "In this first part we only set up the GUI or the Navigation." If you want control over the Kontakt engine, refer to this article: https://blog.yummybeats.com/ksp-kontakt-scripting/kontakt-scripting-ksp-sublime-3-how-to-work-with-macros-tutorial/ Thx for the hint, I will fix it. I hope you still were able to follow this article (since it is the same code for all knobs) [EDIT:] There will also be a separate article about the on ui_control

Trackbacks/Pingbacks

  1.  Kontakt Scripting (KSP) – CUSTOM SCRIPTS :: advanced round robin function | YummyBeats Blog

Leave a Reply

use <pre></pre> to wrap code blocks

use <code></code> to wrap small code snippets

Your email address will not be published. Required fields are marked *