# Scroll Bar



## jesusginard (Feb 6, 2017)

Hey there, 

I've been searching in the forum but I haven't found anything about this. 
I want to have dynamic drop down list that the user is able to select individual items and tweak some parameters based on the selection, and even delete and add items. I tried to do that using a ui_menu but it has to have a fixed list declared on init. 
I think I'll have to do it myself with custom graphics and buttons arranged vertically, but I'll need a scroll bar. Is that also something I'll have to do myself with a slider or is there something already usable in KSP?

Thanks!


----------



## Lindon (Feb 6, 2017)

Slider all the way. When I last did this it turned out to be not so complex to do .


----------



## d.healey (Feb 6, 2017)

I've done something like this in Kontakt before. As far as I'm aware you can't do a smooth scrolling because you'd need to have a control inside a control that moves out of the visible bounds of the outer control - like walking past a window. You instead have to hide and show buttons and have a row by row type of scrolling. I've actually just been working on this today in HISE http://178.62.82.76:4567/topic/128/scrolling-controls-vertically - (which can also do smooth scrolling).






Here's the code from my project - this is specifically for some key switch related controls but hopefully it will give you some help. You will need a global offset variable which is incremented or decremented based on if you want to scroll up or down. Also your controls need to have their IDs stored in an array and you'll need to specify their Y position and offsets in the scroll function - or somewhere global that the scroll function can access. In the code below this is the 28*. The Y position is need because as you scroll you shift the controls up or down and hide or show rows that should or shouldn't be displayed depending on the scroll offset.


```
{/**
* The effect of this function is to produce a page scroll feature by hiding all of the KS controls and then displaying a selection
* of them based on the value of the global variable $ks_scroll. $ks_scroll offsets the number of controls to display at a time.
*/}
taskfunc scroll_ks_controls()

    {Make sure ks_scroll is not larger than the number of KS}
    if ($ks_scroll > num_elements(Ks.keys)-4)
        $ks_scroll := num_elements(Ks.keys)-4
    end if

    {Hide all the ks controls}
    for $i := 0 to num_elements(%ui_ks_buttons)-1
        %ui_ks_buttons[$i] -> HIDE := $HIDE_WHOLE_CONTROL
        %ui_ks_vals[$i] -> HIDE := $HIDE_WHOLE_CONTROL     
    end for
 
    {Show a maximum of 4 controls at a time}
    for $i := ks_scroll to ks_scroll+3
     
        if ($i < num_elements(%ui_ks_buttons))
            %ui_ks_buttons[$i] -> POS_Y := 8+(28*($i-ks_scroll))
            %ui_ks_vals[$i] -> POS_Y := 15+(28*($i-ks_scroll))

            %ui_ks_buttons[$i] -> HIDE := $HIDE_PART_NOTHING
            %ui_ks_vals[$i] -> HIDE := $HIDE_PART_NOTHING
            %ui_ks_vals[$i] -> HIDE := $HIDE_PART_BG
        end if

    end for

end taskfunc
```

Here are the on control callbacks I used. I have two buttons, btnNext and btnPrev to scroll up and down the list

```
on ui_control(btn_prev)
        if (ks_scroll > 0)
            ks_scroll := ks_scroll - 1
            xfm.scroll_ks_controls()
        end if
        btn_ks_prev := OFF
    end on

    on ui_control(btn_next)
        if (ks_scroll < num_elements(%ui_ks_buttons)-4)
            ks_scroll := ks_scroll + 1
            xfm.scroll_ks_controls()
        end if
        btn_ks_next := OFF
    end on
```

Lindon posted while I was typing  @Lindon can you do smooth scrolling?


----------



## EvilDragon (Feb 6, 2017)

d.healey said:


> As far as I'm aware you can't do a smooth scrolling



Sure you can, it's just a bit trickier. Some libraries are also doing that (Output Signal patch browser, for example).


----------



## d.healey (Feb 6, 2017)

EvilDragon said:


> Sure you can, it's just a bit trickier. Some libraries are also doing that (Output Signal patch browser, for example).


Cool!


----------



## szcz (Feb 6, 2017)

Ui_menu has fixed number of entries, yes. But then you can change menu item string, value and visibility (hide/show items), so just declare many items and hide unused dynamically.


----------



## EvilDragon (Feb 6, 2017)

That's not really a scrollbar then, is it?


----------



## Lindon (Feb 7, 2017)

EvilDragon said:


> Sure you can, it's just a bit trickier. Some libraries are also doing that (Output Signal patch browser, for example).


Yep, done exactly that myself, not actually that tricky..


----------



## EvilDragon (Feb 7, 2017)

Not THAT tricky, yeah, but trickier than prev-next page based system.


----------



## jesusginard (Feb 7, 2017)

Thank you for your responses, guys.
I've come up with this, the slider controls the position of the other elements and they hide when a certain threshold is reached.


```
on init 
    message("")
    set_ui_height_px(540)
    declare i
    declare position

    // Our scroll
    declare ui_slider scroll(0, 250)
    scroll -> pos_x := 100
    scroll -> pos_y := 80
    scroll -> mouse_behaviour := -400

    declare const offset := 20

    // Static element -> threshold that the other elements should not pass (Gandalf?)
    declare ui_label stop(1, 1)
    set_text(stop, "STOP")
    stop -> pos_x := 100
    stop -> pos_y := 320

    // Predefined X and Y positions
    declare const label_x := 100
    declare const label_y := 100

    // Scrolling element 1
    declare ui_label label(1, 1)
    label -> pos_x := label_x 
    label -> pos_y := label_y 

    // Scrolling element 2
    declare ui_label label2(1,1)
    label2 -> pos_x := label_x
    label2 -> pos_y := label_y + offset

    // Scrolling element 3
    declare ui_label label3(1, 1)
    label3 -> pos_x := label_x 
    label3 -> pos_y := label_y + offset * 2

    // Scrolling element 4
    declare ui_label label4(1,1)
    label4 -> pos_x := label_x
    label4 -> pos_y := label_y + offset * 3

    // Threshold
    declare const max_y := 300

    declare ui_ids[4] := (-1)
    ui_ids[0] := get_ui_id(label)
    ui_ids[1] := get_ui_id(label2)
    ui_ids[2] := get_ui_id(label3)
    ui_ids[3] := get_ui_id(label4)
end on

on ui_control(scroll)
    for i := 0 to num_elements(ui_ids) - 1

        // Scrolling
        position := label_y + scroll + offset * i
        ui_ids[i] -> pos_y := position

        // Check bounds
        if(position > max_y)
            ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
        else 
            ui_ids[i] -> hide := HIDE_PART_NOTHING
        end if
    end for
end on
```


----------



## jesusginard (Feb 8, 2017)

New version of the script that hides elements on both sides when a certain threshold is reached.

```
on init 
	message("")
    set_ui_height_px(540)
    declare i
    declare position

    // Our scroll
    declare ui_slider scroll(0, 400)
    scroll := 200
    scroll -> pos_x := 100
    scroll -> pos_y := 80
    scroll -> mouse_behaviour := -400

    declare const offset := 20

    // Static element -> threshold that the other elements should not pass (Gandalf?)
    declare ui_label stop(1, 1)
    set_text(stop, "STOP")
    stop -> pos_x := 100
    stop -> pos_y := 320

    // Predefined X and Y positions
    declare const label_x := 100
    declare const label_y := 400

    // Scrolling element 1
    declare ui_label label(1, 1)
    label -> pos_x := label_x 
    label -> pos_y := label_y 

    // Scrolling element 2
    declare ui_label label2(1,1)
    label2 -> pos_x := label_x
    label2 -> pos_y := label_y + offset

    // Scrolling element 3
    declare ui_label label3(1, 1)
    label3 -> pos_x := label_x 
    label3 -> pos_y := label_y + offset * 2

    // Scrolling element 4
    declare ui_label label4(1,1)
    label4 -> pos_x := label_x
    label4 -> pos_y := label_y + offset * 3

    // Threshold
    declare const min_y := 100
    declare const max_y := 300

    declare ui_ids[4] := (-1)
    ui_ids[0] := get_ui_id(label)
    ui_ids[1] := get_ui_id(label2)
    ui_ids[2] := get_ui_id(label3)
    ui_ids[3] := get_ui_id(label4)


    // Initialize positions and check bounds
    for i := 0 to num_elements(ui_ids) - 1
    	// Scrolling
    	position := label_y - scroll + offset * i
    	ui_ids[i] -> pos_y := position

    	// Check bounds
    	if(position < min_y or position > max_y)
    		ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
    	else 
    		ui_ids[i] -> hide := HIDE_PART_NOTHING
    	end if
    end for
end on

on ui_control(scroll)
    for i := 0 to num_elements(ui_ids) - 1

    	// Scrolling
    	position := label_y - scroll + offset * i
    	ui_ids[i] -> pos_y := position

    	// Check bounds
    	if(position < min_y or position > max_y)
    		ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
    	else 
    		ui_ids[i] -> hide := HIDE_PART_NOTHING
    	end if
    end for
end on
```


----------



## Norbz (Feb 25, 2017)

Hey this is awesome just what I was looking for thank you!

Now how would I go about adding say 8 rows across if there was a matrix of scrollable buttons not just one row?


----------



## jesusginard (Feb 25, 2017)

Norbz said:


> Hey this is awesome just what I was looking for thank you!
> 
> Now how would I go about adding say 8 rows across if there was a matrix of scrollable buttons not just one row?


The example script is the basis, you can do whatever you want starting from there. I haven't tried it yet but I would declare the matrix with the initial positions and update their position based on the scroll value. Once you have this basic script it's just a matter of adding more stuff.


----------



## Norbz (Feb 25, 2017)

Thank you~!

Yep, I'm in the midst of trying to expand on it. I'm learning KSP quickly but certain aspects still elude me. Managed to switch out the current scrollable labels with 120 switches, declared positions, however everything is still offset by 20 so trying to figure that part out (rows are showing but not aligned)..

Meaning it should be

| | | |

but it's
__ |
___ |
____ |
_____ |

Trying to kinda duplicate what's happening x 8 and have all scrolling but am not getting anywhere just yet.


----------



## EvilDragon (Feb 25, 2017)

You're possibly incrementing the X position in a while loop, then?


----------



## Norbz (Feb 25, 2017)

Hi ED.

Nope, just manually declared 120 switches, to show up as a matrix of 8 switches x 15 rows. The 'mask' if you will, is showing 40 at a time.

So

||||||||
||||||||
||||||||
||||||||
||||||||

I have them sitting horizontally, but not sure how to vertically offset each horizontal group just yet, so naturally it shows up as:

|
|
|

then once it reaches the next row horizontally it just keeps going on the y axis
|
|
__ |
__ |
__ |

I'm trying to change the code to offset the next row but still spaghetti .


----------



## EvilDragon (Feb 25, 2017)

You might find the modulo operation useful for what you want to do.


----------



## Norbz (Feb 25, 2017)

So for instance, here are my first 10 switches (this is for sublime..)

let's say I want the first 5 to be at the x axis = 10,
and the second row to be x axis = 87.
So they sit beside each other as two rows horizontally
(there are more rows/columns but I'm just trying to understand this so let's use two for now)


```
on init
    message("")
    set_ui_height_px(426)
    declare i
    declare position
    make_perfview

    // Our scroll
    declare ui_slider scroll(74, 200)
    scroll := 50
    scroll -> pos_x := 10
    scroll -> pos_y := 290
    scroll -> mouse_behaviour := -400

    declare const offset := 18

    // Static element -> threshold that the other elements should not pass (Gandalf?)
    declare ui_label stop(1, 1)
    set_text(stop, "STOP")
    stop -> pos_x := 10
    stop -> pos_y := 410

    // Predefined X and Y positions
    declare const label_x := 10
    declare const label_y := 410
    // Scrolling element 1
    declare ui_label label(1, 1)
    label -> pos_x := label_x
    label -> pos_y := label_y


    {0-4}

declare ui_switch $group1
    set_control_par_str(get_ui_id($group1),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group1),  $CONTROL_PAR_TEXT, "1. xxx")
    set_control_par(get_ui_id($group1),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group1,10,334)
    set_control_par(get_ui_id($group1 ), $CONTROL_PAR_AUTOMATION_ID,1)

declare ui_switch $group2
    set_control_par_str(get_ui_id($group2),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group2),  $CONTROL_PAR_TEXT, "2. xxx")
    set_control_par(get_ui_id($group2),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group2,10,352)
    set_control_par(get_ui_id($group2 ), $CONTROL_PAR_AUTOMATION_ID,2)


declare ui_switch $group3
    set_control_par_str(get_ui_id($group3),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group3),  $CONTROL_PAR_TEXT, "3. xxx")
    set_control_par(get_ui_id($group3),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group3,10,370)
    set_control_par(get_ui_id($group3 ), $CONTROL_PAR_AUTOMATION_ID,3)


declare ui_switch $group4
    set_control_par_str(get_ui_id($group4),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group4),  $CONTROL_PAR_TEXT, "4. xxx")
    set_control_par(get_ui_id($group4),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group4,10,388)
    set_control_par(get_ui_id($group4 ), $CONTROL_PAR_AUTOMATION_ID,4)

declare ui_switch $group5
    set_control_par_str(get_ui_id($group5),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group5),  $CONTROL_PAR_TEXT, "5. xxx")
    set_control_par(get_ui_id($group5),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group5,10,406)
    set_control_par(get_ui_id($group5 ), $CONTROL_PAR_AUTOMATION_ID,5)

    {5-9}

declare ui_switch $group6
    set_control_par_str(get_ui_id($group6),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group6),  $CONTROL_PAR_TEXT, "6. xxx")
    set_control_par(get_ui_id($group6),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group6,87,334)
        set_control_par(get_ui_id($group6 ), $CONTROL_PAR_AUTOMATION_ID,6)

declare ui_switch $group7
    set_control_par_str(get_ui_id($group7),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group7),  $CONTROL_PAR_TEXT, "7. xxx")
    set_control_par(get_ui_id($group7),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group7,87,352)
        set_control_par(get_ui_id($group7 ), $CONTROL_PAR_AUTOMATION_ID,7)

declare ui_switch $group8
    set_control_par_str(get_ui_id($group8),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group8),  $CONTROL_PAR_TEXT, "8. xxx")
    set_control_par(get_ui_id($group8),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group8,87,370)
        set_control_par(get_ui_id($group8 ), $CONTROL_PAR_AUTOMATION_ID,8)


declare ui_switch $group9
    set_control_par_str(get_ui_id($group9),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group9),  $CONTROL_PAR_TEXT, "9. xxx")
    set_control_par(get_ui_id($group9),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group9,87,388)
        set_control_par(get_ui_id($group9), $CONTROL_PAR_AUTOMATION_ID,9)


declare ui_switch $group10
    set_control_par_str(get_ui_id($group10),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group10),  $CONTROL_PAR_TEXT, "10. xxx")
    set_control_par(get_ui_id($group10),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group10,87,406)
    set_control_par(get_ui_id($group10), $CONTROL_PAR_AUTOMATION_ID,10)

// Threshold
    declare const min_y := 330
    declare const max_y := 414

    declare ui_ids[9] := (-1)
    ui_ids[0] := get_ui_id($group1)
    ui_ids[1] := get_ui_id($group2)
    ui_ids[2] := get_ui_id($group3)
    ui_ids[3] := get_ui_id($group4)
    ui_ids[4] := get_ui_id($group5)

    ui_ids[5] := get_ui_id($group6)
    ui_ids[6] := get_ui_id($group7)
    ui_ids[7] := get_ui_id($group8)
    ui_ids[8] := get_ui_id($group9)
    ui_ids[9] := get_ui_id($group10)
```

Then, on the callbacks it's currently:


```
// Initialize positions and check bounds
    for i := 0 to num_elements(ui_ids) - 1
        // Scrolling
        position := label_y - scroll + offset * i
        ui_ids[i] -> pos_y := position

        // Check bounds
        if(position < min_y or position > max_y)
            ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
        else
            ui_ids[i] -> hide := HIDE_PART_NOTHING
        end if
    end for
end on

on ui_control(scroll)
    for i := 0 to num_elements(ui_ids) - 1

        // Scrolling
        position := label_y - scroll + offset * i
        ui_ids[i] -> pos_y := position

        // Check bounds
        if(position < min_y or position > max_y)
            ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
        else
            ui_ids[i] -> hide := HIDE_PART_NOTHING
        end if
    end for
end on
```

Which calls all the switches and lines them up vertically. So I assume we need to grab the second set, and treat them differently, with their own id's? Which then I assume we'd need x 8 of those, one for each row? Am I thinking correctly before I try to unpuzzle this?


----------



## EvilDragon (Feb 25, 2017)

I usually have all UI controls in just one UI ID array, then use offsets to get to what I want to work with...

So, in your case, I would use the same ui_ids array, but point at a specific area where the second row/column is, and do the same pos_y and hide thing on them.


----------



## Norbz (Feb 25, 2017)

Yes, however for this instance it's still going to push every single element 18 pxl's downward vertically. I think we need to separate them into groups. Or I'm not reading what you wrote correctly.

**Is there a way to remove the offsets here and just rely on the default positioning of the switches and scroll those?


----------



## EvilDragon (Feb 25, 2017)

Use modulo operation if you can. Let's say you have 2 columns of 10 elements each, then you need to "mod 10" the Y position increment, like this:

UI_ID_ -> y := baseline + (y_offset * (i mod 10))
_
This will restart the y position for the 11th-20th item in the list.


----------



## Norbz (Feb 25, 2017)

Thanks ED,

So on the previous code I have two columns of five, where would that line go? Or how would I adjust it to work with this current setup (I want to understand this first).

Also why doesn't this below work, out of curiosity, in theory it looks like it should? I've duplicated needed declares and separated the second column into its own ui_id group.


```
on init
    message("")
    set_ui_height_px(426)
    declare i
    declare i2
    declare position
    make_perfview

    // Our scroll
    declare ui_slider scroll(74, 200)
    scroll := 50
    scroll -> pos_x := 10
    scroll -> pos_y := 290
    scroll -> mouse_behaviour := -400

    declare const offset := 18

    // Static element -> threshold that the other elements should not pass (Gandalf?)
    declare ui_label stop(1, 1)
    set_text(stop, "STOP")
    stop -> pos_x := 10
    stop -> pos_y := 410

    // Predefined X and Y positions
    declare const label_x := 10
    declare const label_y := 410

    // Scrolling element 1
    declare ui_label label(1, 1)
    label -> pos_x := label_x
    label -> pos_y := label_y


    {0-4}

declare ui_switch $group1
    set_control_par_str(get_ui_id($group1),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group1),  $CONTROL_PAR_TEXT, "1. xxx")
    set_control_par(get_ui_id($group1),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group1,10,334)
    set_control_par(get_ui_id($group1 ), $CONTROL_PAR_AUTOMATION_ID,1)

declare ui_switch $group2
    set_control_par_str(get_ui_id($group2),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group2),  $CONTROL_PAR_TEXT, "2. xxx")
    set_control_par(get_ui_id($group2),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group2,10,352)
    set_control_par(get_ui_id($group2 ), $CONTROL_PAR_AUTOMATION_ID,2)


declare ui_switch $group3
    set_control_par_str(get_ui_id($group3),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group3),  $CONTROL_PAR_TEXT, "3. xxx")
    set_control_par(get_ui_id($group3),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group3,10,370)
    set_control_par(get_ui_id($group3 ), $CONTROL_PAR_AUTOMATION_ID,3)


declare ui_switch $group4
    set_control_par_str(get_ui_id($group4),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group4),  $CONTROL_PAR_TEXT, "4. xxx")
    set_control_par(get_ui_id($group4),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group4,10,388)
    set_control_par(get_ui_id($group4 ), $CONTROL_PAR_AUTOMATION_ID,4)

declare ui_switch $group5
    set_control_par_str(get_ui_id($group5),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group5),  $CONTROL_PAR_TEXT, "5. xxx")
    set_control_par(get_ui_id($group5),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group5,10,406)
    set_control_par(get_ui_id($group5 ), $CONTROL_PAR_AUTOMATION_ID,5)

    {5-9}

declare ui_switch $group6
    set_control_par_str(get_ui_id($group6),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group6),  $CONTROL_PAR_TEXT, "6. xxx")
    set_control_par(get_ui_id($group6),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group6,87,334)
        set_control_par(get_ui_id($group6 ), $CONTROL_PAR_AUTOMATION_ID,6)

declare ui_switch $group7
    set_control_par_str(get_ui_id($group7),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group7),  $CONTROL_PAR_TEXT, "7. xxx")
    set_control_par(get_ui_id($group7),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group7,87,352)
        set_control_par(get_ui_id($group7 ), $CONTROL_PAR_AUTOMATION_ID,7)


declare ui_switch $group8
    set_control_par_str(get_ui_id($group8),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group8),  $CONTROL_PAR_TEXT, "8. xxx")
    set_control_par(get_ui_id($group8),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group8,87,370)
        set_control_par(get_ui_id($group8 ), $CONTROL_PAR_AUTOMATION_ID,8)


declare ui_switch $group9
    set_control_par_str(get_ui_id($group9),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group9),  $CONTROL_PAR_TEXT, "9. xxx")
    set_control_par(get_ui_id($group9),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group9,87,388)
        set_control_par(get_ui_id($group9), $CONTROL_PAR_AUTOMATION_ID,9)


declare ui_switch $group10
    set_control_par_str(get_ui_id($group10),  $CONTROL_PAR_PICTURE, "onoffpreset")
    set_control_par_str(get_ui_id($group10),  $CONTROL_PAR_TEXT, "10. xxx")
    set_control_par(get_ui_id($group10),$CONTROL_PAR_FONT_TYPE,11)
    move_control_px($group10,87,406)
    set_control_par(get_ui_id($group10), $CONTROL_PAR_AUTOMATION_ID,10)

    // Threshold
    declare const min_y := 330
    declare const max_y := 414

declare ui_ids[5] := (-1)
    ui_ids[0] := get_ui_id($group1)
    ui_ids[1] := get_ui_id($group2)
    ui_ids[2] := get_ui_id($group3)
    ui_ids[3] := get_ui_id($group4)
    ui_ids[4] := get_ui_id($group5)

declare ui_ids2[5] := (-1)
    ui_ids[5] := get_ui_id($group6)
    ui_ids[6] := get_ui_id($group7)
    ui_ids[7] := get_ui_id($group8)
    ui_ids[8] := get_ui_id($group9)
    ui_ids[9] := get_ui_id($group10)


// Initialize positions and check bounds
    for i := 0 to num_elements(ui_ids) - 1
        // Scrolling
        position := label_y - scroll + offset * i
        ui_ids[i] -> pos_y := position

        // Check bounds
        if(position < min_y or position > max_y)
            ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
        else
            ui_ids[i] -> hide := HIDE_PART_NOTHING
        end if
    end for

    for i2 := 5 to num_elements(ui_ids2) - 1
        // Scrolling
        position := label_y - scroll + offset * i2
        ui_ids2[i] -> pos_y := position

        // Check bounds
        if(position < min_y or position > max_y)
            ui_ids2[i2] -> hide := HIDE_WHOLE_CONTROL
        else
            ui_ids2[i2] -> hide := HIDE_PART_NOTHING
        end if
    end for


end on

on ui_control(scroll)
    for i := 0 to num_elements(ui_ids) - 1

        // Scrolling
        position := label_y - scroll + offset * i
        ui_ids[i] -> pos_y := position

        // Check bounds
        if(position < min_y or position > max_y)
            ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
        else
            ui_ids[i] -> hide := HIDE_PART_NOTHING
        end if
    end for

    for i2 := 5 to num_elements(ui_ids2) - 1

        // Scrolling
        position := label_y - scroll + offset * i2
        ui_ids2[i2] -> pos_y := position

        // Check bounds
        if(position < min_y or position > max_y)
            ui_ids2[i2] -> hide := HIDE_WHOLE_CONTROL
        else
            ui_ids2[i2] -> hide := HIDE_PART_NOTHING
        end if
    end for
end on
```


----------



## EvilDragon (Feb 25, 2017)

You didn't need to duplicate things at all - just produces unnecessarily longer code... Try this for scrolling slider's callback:


```
on ui_control(scroll)
   for i := 0 to num_elements(ui_ids) - 1
     // Scrolling
     position := label_y - scroll + (offset * (i mod 5))
     ui_ids[i] -> pos_y := position

     // Check bounds
     if(position < min_y or position > max_y)
       ui_ids[i] -> hide := HIDE_WHOLE_CONTROL
     else
       ui_ids[i] -> hide := HIDE_PART_NOTHING
     end if
   end for
end on
```


This implies having just one ui_ids array with all 10 controls defined.


----------



## Norbz (Feb 25, 2017)

Aha, I see.

However it only kicks in once you touch the scroll slider. Can't seem to add it to the init.


----------



## EvilDragon (Feb 25, 2017)

You can add it to the init as well.

No need to add 5, this covers both columns or any columns you might have, because modulo always wraps any number you feed it to the range from 0 to 4. So this multiplies the offset by 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, and so on, as i increases.


----------



## Norbz (Feb 25, 2017)

I erased the second question as you were typing, did my own trial/error. . Trying to add it to init but it's not accepting, is there a specific spot I need to put it under?


----------



## EvilDragon (Feb 25, 2017)

It needs to replace the two loops you have under "initialize positions and check bounds". Also make sure to remove ui_ids2 because it's not necessary.


----------



## Norbz (Feb 25, 2017)

All working 

Much love, again~!
Weeeeeeeeeeeeeeeeee


----------



## geronimo (Jul 25, 2017)

And concretely then out of curiosity, could we see the final Application of this Script ?


----------



## jesusginard (Jul 25, 2017)

From minute 6.00


----------



## JaggedAndRagged (Oct 2, 2017)

EvilDragon said:


> You didn't need to duplicate things at all - just produces unnecessarily longer code... Try this for scrolling slider's callback:
> 
> 
> ```
> ...



Sorry if this has been asked before;
But how come the above example does not have things like: "$", "%" and "->" doesnt work. Kontakt asks for ":="
What am i missing?
Thanks!!


----------



## Lindon (Oct 2, 2017)

native Kontakt editor text format vs sublime text plug-in format.


----------

