# Get_ui_id using a string



## nosfoe (Oct 14, 2013)

Hi everyone, 
I found some interesting behavior of get_ui_id: I tried to use a string to get the UI id of control elements, and interestingly that doesn't create an error but also it doesn't really work. The code below should return the same UI ID in the message bar twice, but it returns two different ones. The one using the string variable seems to return the ID of the last ui control that was created (thus the wrong ID). 
I am aware of the limitations of using strings in kontact script, but usually you get an error when you try to do something that's not possible... 
Any thoughts about this anyone? 



```
on init   
    declare ui_knob $articulation (0,10,1)
    declare @temp_string
    @temp_string := "$articulation"    
    message (@temp_string & "  -  "  & get_ui_id($articulation) & "  -  "  & get_ui_id(@temp_string))    
end on
```


----------



## d.healey (Oct 14, 2013)

This gives me an error in Kontakt 4.2.


----------



## nosfoe (Oct 14, 2013)

> This gives me an error in Kontakt 4.2.


I'm in Kontakt 5.2, that probably explains the difference..


----------



## polypx (Oct 14, 2013)

I don't see why that code should return the same UI ID. Assigning the "$articulation" text string to @temp_string won't assign it a new UI ID... UI IDs aren't variables, they're assigned by Kontakt itself.

If you do this, you'll see the UI ID assigned as a text string:

on init 
declare ui_knob $articulation (0,10,1)
declare @temp_string
@temp_string := get_ui_id($articulation) 
message (@temp_string & " - " & get_ui_id($articulation)) 
end on


----------



## nosfoe (Oct 14, 2013)

I'm not trying to assign a new ui id or anything, and of course ui id's are not variables. What I tried to do was replacing the variable name ("$articulation" in this case) with a text string and I would expect to get either an error because that's not allowed or exactly the same ui id as with get_ui_id($articulation). In this case I get a DIFFERENT ui id, which seems weird.


----------



## polypx (Oct 14, 2013)

Ok, well just to clarify a couple things: 

You cannot change / replace a variable's name, you can only change the string/value of it using := "$articulation". This has no affect on the ID of the element itself.

Kontakt won't assign the same ID to two different elements, and you can't change the IDs to make two the same.

You CAN hold the ID of an element in a string variable (or an integer variable), which is what my code snippet above does.

Maybe it's not clear exactly what you're trying to do?

cheers, Dan

PS You're not getting an error because you're not doing anything illegal within KSP. You're simply not getting the behaviour you expected.


----------



## Big Bob (Oct 14, 2013)

I hope I'm not walking into a hornet's nest here but maybe this will help?

Here's the way I remember this:

You can ask Kontakt for the ui_id of things other than controls. For example, you can ask for the id of ordinary variables or strings, etc. The KSP obligingly assigns a value but you really can't do anything with it.

For example,

*on init*
``*declare* $x
````$x := 1
``*declare* $xid
````$xid := get_ui_id($x)
``message(get_control_par($xid,$CONTROL_PAR_VALUE))
*end* on



If you run the above script, I think the status line will show 0, even though you might expect it to show 1. However, if you change the variable x to a switch like this:

*on init*
``*declare* ui_switch $x
````$x := 1
``*declare* $xid
````$xid := get_ui_id($x)
``message(get_control_par($xid,$CONTROL_PAR_VALUE))
*end* on

Running this script will report 1 on the status line.

So, while you can assign IDs to non-control items, you can't use these IDs to read/write to the items whose IDs you obtain. Perhaps it would be better if the KSP flagged such attempts to get an id for non-control items but, maybe someday, NI plans to allow indirect access to oridinary variables and such :roll: 

Rejoice,

Bob


----------



## nosfoe (Oct 15, 2013)

Thanks for the reply Bob, interesting to know that you can ask for IDs of variables!

Dan, I'm not trying to make two IDs the same or change the name of a variable. It seems I need to be more clear, so here's a new explaination. 
The central part is exchanging the UI control name in the get_ui_id-command for a string that contains that same name. So I tried to turn something like this, which of course works and will show you the 4 different IDs of the 4 knobs...


```
on init   
    message("") 
    declare ui_knob $knob0 (0,10,1)
    declare ui_knob $knob1 (0,10,1)
    declare ui_knob $knob2 (0,10,1)
    declare ui_knob $knob3 (0,10,1)    
    
    declare %ui_id_array[100]
    %ui_id_array[0] := get_ui_id($knob0)
    %ui_id_array[1] := get_ui_id($knob1)
    %ui_id_array[2] := get_ui_id($knob2)
    %ui_id_array[3] := get_ui_id($knob3)   
    
    declare ui_label $viewer (1,5)
    set_text($viewer, "UI IDs")   
    add_text_line ($viewer, %ui_id_array[0])
    add_text_line ($viewer, %ui_id_array[1])
    add_text_line ($viewer, %ui_id_array[2])
    add_text_line ($viewer, %ui_id_array[3])
end on
```

.... into something like this which doesn't work, since it is not allowed as it gives me an error:


```
on init   
    message("")
    declare ui_knob $knob0 (0,10,1)
    declare ui_knob $knob1 (0,10,1)
    declare ui_knob $knob2 (0,10,1)
    declare ui_knob $knob3 (0,10,1)   
    
    declare !ui_names_array[100]
    !ui_names_array[0] := "$knob0"
    !ui_names_array[1] := "$knob1"
    !ui_names_array[2] := "$knob2"
    !ui_names_array[3] := "$knob3"   
    
    declare %ui_id_array[100]
    declare $a := 0
    
    while ($a < 4)
        %ui_id_array[$a] := get_ui_id(!ui_names_array[$a])
        inc($a)
    end while        
end on
```

So far, so good. The interesting part is that if you directly use a string variable inside get_ui_id it DOES work, at least sort of. There is no error, but the IDs you get are not the correct ones, since it is four times the exact same one, and also appears to be none of the existing knobs IDs:


```
on init   
    message("")
    declare ui_knob $knob0 (0,10,1)
    declare ui_knob $knob1 (0,10,1)
    declare ui_knob $knob2 (0,10,1)
    declare ui_knob $knob3 (0,10,1)   
    
    declare !ui_names_array[100]
    !ui_names_array[0] := "$knob0"
    !ui_names_array[1] := "$knob1"
    !ui_names_array[2] := "$knob2"
    !ui_names_array[3] := "$knob3"   
    
    declare %ui_id_array[100]
    declare $a := 0
    declare @temp_string
    declare ui_label $viewer (1,5)
    set_text($viewer, "UI IDs")
    
    while ($a < 4)
        @temp_string := !ui_names_array[$a]
        %ui_id_array[$a] := get_ui_id(@temp_string)    
         add_text_line ($viewer, %ui_id_array[$a])
        inc($a)        
    end while       
end on
```

That was what puzzled me, so I wanted to share that. I mostly want to automate processes as much as possible, that's why I tried this. And for a moment I thought it would work because it returned an ID, without reporting an error. It would have made my life easier if it worked. 
I hope I'm being clear this time.


----------



## polypx (Oct 15, 2013)

```
while ($a < 4)
        @temp_string := !ui_names_array[$a]
        %ui_id_array[$a] := get_ui_id(@temp_string)   
         add_text_line ($viewer, %ui_id_array[$a])
        inc($a)       
    end while
```

When you pass the name of an element from the array to the @temp_string here, you are ONLY passing the name of that element. Nothing more.

You can't get_ui_id the NAME to find the actual UI_ID of the element itself. The name is simply a text string at that point, no longer related to the element.

The only way to store the IDs of the elements is to get_ui_id on the element directly.

ie %ui_id_array[$a] := get_ui_id($knob_1) 

It's late here, but I will come back to this tomorrow.

cheers
Dan


----------



## nosfoe (Oct 16, 2013)

polypx @ 16th October 2013 said:


> The only way to store the IDs of the elements is to get_ui_id on the element directly.



Exactly, that was my conclusion after trying the second code snippet in my post above. And so my point was: in the third code snippet it DOES seem to work, although it shouldn't! Isn't that weird?

It gives the wrong result of course: get_ui_id(@temp_string) appears to return the UI ID of the last created ui element, at least it looks exactly like an ID and it has a higher number than the knobs IDs.


----------



## nosfoe (Oct 16, 2013)

okay, I suddenly get it! Bob pointed out the right direction... get_ui_id(@temp_string) returns the ui id of the variable @temp_string (you CAN ask for that, as Bob pointed out). That's why it works and doesn't create an error! Duh! 
Sorry if that was obvious and was exactly what you were talking about 
cheers!


----------



## mk282 (Oct 16, 2013)

Why would you want to do it like that, anyways?

All you need to know is that UI IDs start from 32768, and are assigned incrementally in order UI controls are created. So, the conundrum you wrote above can basically be condensed to:


```
on init
    declare const $NUM_CONTROLS := 4

    declare $i

    declare ui_knob $knob0 (0,10,1)
    declare ui_knob $knob1 (0,10,1)
    declare ui_knob $knob2 (0,10,1)
    declare ui_knob $knob3 (0,10,1)   
   
    declare %ID[$NUM_CONTROLS)

    while ($i < $NUM_CONTROLS)
        %ID[$i] := 32768 + $i
        inc($i)
    end while

    message("")
end on
```

You don't even need to use get_ui_id() :D


----------



## Big Bob (Oct 16, 2013)

There are several kinds of things that will break the simple sequential ordering of ids. These can usually be avoided but you have to aware of them. Also please note that the example posted doesn't start assigning ids at 32768 but rather 32769 because of the presence of declare $i. If you move that declare after the knobs it will work but perhaps a safer way would be to use get_ui_id($knob0) instead of 32768.

To illustrate some other things that can mess you up, consider the following. 

*on init* 
````*declare* *on init 
````declare const $NUM_CONTROLS := 4 

````declare $i 

````declare ui_knob $knob0 (0,10,1) 
````declare ui_knob $knob1 (0,10,1) 
{ declare $xyz }
````declare ui_knob $knob2 (0,10,1) 
````declare ui_knob $knob3 (0,10,1)````
`````
````declare %ID[$NUM_CONTROLS] 

````while ($i < $NUM_CONTROLS) 
````````%ID[$i] := get_ui_id($knob0) + $i 
````````inc($i) 
{ $i := get_ui_id($xyz) }
````message(%ID[2] & ", " & get_ui_id($knob2))
end on


If you run this script as is, ID[2] will contain the id of knob2. Now, uncomment the line with declare $xyz and note that the presence of this in the middle of the knob decalrations doesn't break things. However, if you also uncomment the 2nd last line, the scheme breaks. Note that what breaks it in this case is simply trying to ask for the id of xyz (which is the kind of thing nosfoe was experimenting with).

Moreover, we have no assurance that this orderly sequential assignment will be maintained in the future by NI. So, in summary, you can often take advantage of Mario's technique but travel with extreme caution :roll: 

Rejoice,

Bob*


----------



## mk282 (Oct 16, 2013)

Right, I forgot to move the declare $i lower. Whoops! :D


And - nothing will change about this sequential ID assignment, I'm pretty much 100% certain of it.


----------



## nosfoe (Oct 17, 2013)

Hi mk282,
thanks for the suggestion, it's an interesting alternative indeed. I guess it is a question of taste if one wants to take the risk Bob pointed out or go for the efficiency of less code.


----------

