# NI Slider Emulation



## Big Bob (Mar 22, 2011)

Hi Everyone,

You may know that the ui_slider component has no native support for displaying its value so a while back, in another thread http://www.vi-control.net/forum/viewtopic.php?t=20028 I brought up this topic to see if anyone had a good slider implementation that emulated NI's slider behavior. 

If you look at the way NI's sliders work, you will see that they display their value only when you click down on your mouse. When you release the mouse, the display vanishes. While you hold the mouse down and drag the slider handle, the slider's value is displayed in a little 'cartoon-like' caption that is centered over the slider's handle and moves as you drag the handle. Since the ksp currently provides no direct means for a script to detect the mouse state when it is over a control, all we have available is the callback trigger itself. So emulating NI's slider behavior is rather tricky with the limited tools that we currently have in K4.2. In the above thread I challenged someone to come up with a close emulation. Mario (Evil Dragon) quickly responded with something that behaves somewhat similarly but his implementation is based on timed caption display rather than staying on until the mouse is released.

Near the end of my posts to that thread, I said I would continue to work on a closer emulation as a back-burner project and that I would post whatever I came up with. My time for working on this has been divided between lots of other things but I have concocted a fairly reasonable emulation. It does still have one way you can somewhat trip it up but it's kind of minor. If you release your mouse too quickly after dragging the slider, it can leave the caption hanging on. However, this is kind of an unnatural use since usually one doesn't release the mouse until one has reached the desired setting long enough to be able to read it. Moreover, whenever the slider is tripped up this way, it recovers very gracefully by just wiggling the slider afterward (or just waiting until the next time you want to change its value).

I may or may not be able to correct this one last problem (but probably not until we get a mouse state function) however, I think the current form of this component might still be generally useful to someone. The implementation provides for an optional label above or below the slider as well as the option to specify a ratio for display of the slider's value. In other words, you can specify min, max, and ratio just like you do for a knob or value edit box so that the slider's value will be displayed as a decimal fraction. I'm attaching a default instrument .nki with a 10-slider display that you can load and play with if you like. To get the correct appearance of the floating caption, you will need to put the two files in the Test folder inside of your K4 pictures folder.

In the attached .zip file, I've also included the source code in KScript format. If you want to paste that script you will of course first have to F5 it in Nils' editor.

If anyone comes up with an even better implemenation of the NI slider, I hope they will share it with us.

Rejoice,

Bob

EDIT: Whoops! I forgot to remove the pragma directive line. If anyone wants to use the KS source, just delete the pragma directive after on init (or edit it to save the compiled code to where you do your in process stuff). Sorry I missed this :oops:


----------



## kotori (Mar 23, 2011)

Hi Bob,



> If you release your mouse too quickly after dragging the slider, it can leave the caption hanging on. However, this is kind of an unnatural use since usually one doesn't release the mouse until one has reached the desired setting long enough to be able to read it.


I am just curious - did you consider the case where a user automates a slider using a MIDI controller? I wonder if not in that case what you describe as unnatural use would be the most common case, i.e. that a certain CC level is not repeated twice.

Cheers,
Nils


----------



## paoling (Jun 18, 2011)

Hi BB, I can't run your patch, Kontakt gives me an error and I can't understand how to run the txt code. Kontakt gives me another error and NILS Editor won't compile it neither.

This is my little rendition of something similar. It is a fadeout label script, just 
http://www.box.net/shared/m9smuf45pb

I realized it using PGS and kontakt font colors, infact it works on a white background.
With some modifications it could be adapted to act like the kontakt one: adding move_control in relation to slider position, and layering a kind of background for the text.
(as you'll see I'm not a master of optimized code 

on init
make_perfview
set_ui_height_px(100)

pgs_create_key(PAUSA,1)
pgs_set_key_val(PAUSA,0,0)
declare ui_label $casa (2,1)
set_text ($casa,"")
hide_part($casa,$HIDE_PART_BG)
move_control_px($casa,60,50)
declare ui_slider $rotella (0,100) 
$rotella := 0 
declare $id
$id := get_ui_id($rotella) 
set_control_par($id,$CONTROL_PAR_MOUSE_BEHAVIOUR,2000) 
set_control_par($id,$CONTROL_PAR_DEFAULT_VALUE,0)

{declare ui_knob $rotella (0,100, 1)}
message("")

set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 18)
declare %index[9]
declare %index_revert[9]
declare $i
declare $o
$o:=0
declare $switch_animation
declare $rotellavecchio
end on

on ui_control($rotella)
set_text ($casa,"Value= "&$rotella)
set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 12)
$o:=0
if (pgs_get_key_val(PAUSA,0)=0)
{if ($switch_animation=0)}
pgs_set_key_val(PAUSA,0,1)


{if ($switch_animation=0)}
{if ($i=9)
$i:=0
end if
%index[$i]:= $rotella
inc($i)}

{end if}
end if

end on
on pgs_changed
if (pgs_get_key_val(PAUSA,0)=1)
while ($o<1000)
wait(1000)
inc($o)
end while

{$switch_animation:=1}
{$o:=0}
set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 12)
$o:=0
while ($o<2000)
wait(100)
inc($o)
end while

set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 15)
$o:=0
while ($o<1000)
wait(100)
inc($o)
end while
set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 14)
$o:=0
while ($o<1000)
wait(100)
inc($o)
end while
set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 13)
$o:=0
while ($o<1000)
wait(100)
inc($o)
end while
{set_control_par(get_ui_id($casa), $CONTROL_PAR_FONT_TYPE, 18)
wait(100000)}
set_text ($casa,"")
{pgs_set_key_val(PAUSA,0,0)
exit}
{$switch_animation:=0}
{end while}

end if
pgs_set_key_val(PAUSA,0,0)
end on


----------



## Big Bob (Jun 18, 2011)

> Hi BB, I can't run your patch, Kontakt gives me an error and I can't understand how to run the txt code. Kontakt gives me another error and NILS Editor won't compile it neither.



I don't know what happened to the .nki but I just uploaded the file tree again, so if you want to try again, re download it. As far as the KSE source code that still seems to compile OK here with KSE V1.4.7. You need to have the .nki alongside the Test folder to get the graphics to work correctly but other than that, I don't know why you can't compile the .txt file in Nils' editor. As I said above, the .nki was somehow mangled, so try the new one if you wish.

I tried your little animation which is kind of nice for a timed display. Of course, as I mentioned in the original thread, I was hoping to get the same behavior as NI does with their sliders. Specifically, to display the caption only while the mouse is down (over it) but indefinately while it is. The moving caption part of it is easily done, it's the mouse-down part that's elusive without some additional KSP support to detect mouse down. Until NI adds such additional support, I think either a timed display of the value or a permanent display is probably the best we can do reliably.

Rejoice,

Bob


----------



## Lukas K (Jul 11, 2015)

Hi,

I'm just wondering if there is an easier solution to get this done in the current version of Kontakt.

Thanks!


----------



## willbedford (Jul 11, 2015)

Hi Bob,
Usually I'm able to read a script and understand basically how it all works, but this time I'm baffled.
How are you detecting that the user's mouse is held down, when they're not moving the slider? From what I understand, the UICB is only called when the value of the slider actually changes.
I've been staring at this script for almost an hour, hoping to find the answer, but I'm stuck.
Any hints pointing me in the right direction would be much appreciated.


----------



## EvilDragon (Jul 11, 2015)

UICB is called even if the slider value is not changed. Even if you just click on it, it will generate two callbacks - one on mouse down, and one on mouse up.


Easily checked by doing this:


```
on ui_control (slider)
    message(NI_CALLBACK_ID)
end on
```


----------



## willbedford (Jul 11, 2015)

Thanks, Mario. I was aware that it triggered a callback on mouse down, but not mouse up. That could come in handy


----------



## EvilDragon (Jul 11, 2015)

The important thing to know is that you cannot really find out when it was mouse down and when mouse up. Try mouse down, hold it, drag mouse around, mouse up. All you get is callback IDs, but as far as KSP is concerned, they are all the one and the same. This is not JavaScript so that you can do stuff onMouseHover, onMouseDown, etc.


----------



## willbedford (Jul 11, 2015)

Yeah, I'm aware of that. I understand how Bob has done it now - by flipping the 'active' variable if the value is the same as the last CB. The missing link was knowing that a CB is triggered on mouse up.


----------



## Lukas K (Jul 19, 2015)

I'm trying to use this method to create a slider to control the velocity/CC to volume modulation intensity. I'm almost there, but I realized that the GUI value differs from the actual modulator intesity value.

My ui_slider range is (0,1000000), shown as (0% - 100%). If I set the slider to 500000 (50%), the actual modulator intesity is set to 25%.

Am I missing something? Thanks for any help!

Lukas


----------



## EvilDragon (Jul 19, 2015)

That's how the actual modulation slider works on the modulator itself. I linearize it with this array:


Then use a slider that has a range (0,1000) and reads from this array, then applies it to the relevant engine parameter ($ENGINE_PAR_MOD_TARGET_INTENSITY).


----------



## Lukas K (Jul 19, 2015)

Thanks a lot!

It works great now


----------



## Big Bob (Jul 19, 2015)

I'll just mention that if you are using the KSP Math Library, there is a ready-made converter named *ModInt_to_ep* that can be used for this. The converter works with both INTMOD_INTENSITY or TARGET_INTENSITY.

Rejoice,

Bob


----------



## Lukas K (Jul 19, 2015)

Thanks Bob, I haven't used your KSP Math Library yet, but thanks for the tip


----------



## tomaslobosk (Aug 2, 2015)

EvilDragon said:


> That's how the actual modulation slider works on the modulator itself. I linearize it with this array:
> 
> 
> Then use a slider that has a range (0,1000) and reads from this array, then applies it to the relevant engine parameter ($ENGINE_PAR_MOD_TARGET_INTENSITY).




Gotcha!
One question, where did you get these values?, What kind of function makes these values exactly?


----------



## tomaslobosk (Aug 2, 2015)

Big Bob said:


> I'll just mention that if you are using the KSP Math Library, there is a ready-made converter named *ModInt_to_ep* that can be used for this. The converter works with both INTMOD_INTENSITY or TARGET_INTENSITY.
> 
> Rejoice,
> 
> Bob


Amazing, you always have the right answer


----------



## EvilDragon (Aug 2, 2015)

TomiLobosK said:


> Gotcha!
> One question, where did you get these values?, What kind of function makes these values exactly?



I used the math library to make the array. Makes compiling of the script faster if you just use exactly the data that you need, without importing the whole library.


----------



## tomaslobosk (Aug 3, 2015)

EvilDragon said:


> I used the math library to make the array. Makes compiling of the script faster if you just use exactly the data that you need, without importing the whole library.



It makes sense, thanks!


----------

