# OK... a chellenge!!! :-)))))... with BUTTONS... wheeeee...



## Thonex (Nov 19, 2010)

Hi Guys,

I know there has got to be an elegant way to do this with the least number of lines of code possible.

Basically, What I'd like to do is take these 8 simple buttons (switches actually) and make them so that you can only have 1 active at a time. In other words, each button (when pressed) must in turn make sure all other buttons are not active... and only the most recent button pressed is "white" (on).

All you veterans out there probably know of a way to do this in 1 line of code using bit shift and mod zero :lol: 

Seriously... any col tricks to do this elegantly?

Below is some starter code:

Thanks for any help.

Cheers,

Andrew K


```
on init
declare ui_switch $Test_Button_Preset_1
declare ui_switch $Test_Button_Preset_2
declare ui_switch $Test_Button_Preset_3
declare ui_switch $Test_Button_Preset_4
declare ui_switch $Test_Button_Preset_5
declare ui_switch $Test_Button_Preset_6
declare ui_switch $Test_Button_Preset_7
declare ui_switch $Test_Button_Preset_8

set_control_par (get_ui_id(Test_Button_Preset_1),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_2),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_3),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_4),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_5),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_6),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_7),$CONTROL_PAR_WIDTH,30)
set_control_par (get_ui_id(Test_Button_Preset_8),$CONTROL_PAR_WIDTH,30)

set_control_par (get_ui_id($Test_Button_Preset_1),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_2),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_3),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_4),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_5),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_6),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_7),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par (get_ui_id($Test_Button_Preset_8),$CONTROL_PAR_TEXT_ALIGNMENT,1)

move_control_px($Test_Button_Preset_1,450,2)
move_control_px($Test_Button_Preset_2,480,2)
move_control_px($Test_Button_Preset_3,510,2)
move_control_px($Test_Button_Preset_4,540,2)
move_control_px($Test_Button_Preset_5,450,20)
move_control_px($Test_Button_Preset_6,480,20)
move_control_px($Test_Button_Preset_7,510,20)
move_control_px($Test_Button_Preset_8,540,20)

set_text ($Test_Button_Preset_1, "1")
set_text ($Test_Button_Preset_2, "2")
set_text ($Test_Button_Preset_3, "3")
set_text ($Test_Button_Preset_4, "4")
set_text ($Test_Button_Preset_5, "5")
set_text ($Test_Button_Preset_6, "6")
set_text ($Test_Button_Preset_7, "7")
set_text ($Test_Button_Preset_8, "8")

end on

on ui_control ($Test_Button_Preset_1)
    
end on
on ui_control ($Test_Button_Preset_2)
    
end on
on ui_control ($Test_Button_Preset_3)
  
end on
on ui_control ($Test_Button_Preset_4)
    
end on
on ui_control ($Test_Button_Preset_5)
   
end on
on ui_control ($Test_Button_Preset_6)
   
end on
on ui_control ($Test_Button_Preset_7)
   
end on
on ui_control ($Test_Button_Preset_8)
   
end on
```


----------



## gregjazz (Nov 19, 2010)

After declaring all the controls, store their IDs in an array. Then you can do stuff like this:

Sets controls 1-8 to have the text "1" through "8":


```
for temp := 1 to 8
  set_control_par_str(id[temp],$CONTROL_PAR_TEXT,temp)
end for
```

Sets controls 1-8 to center alignment:


```
for temp := 1 to 8
  set_control_par(id[temp],$CONTROL_PAR_TEXT_ALIGNMENT,1)
end for
```

Also, use the "set_control_par" functions as often as possible, rather than the "set_text" and "move_control", etc. functions.

Whenever possible, also use macros. For example:


```
on init
  declare id[500]
  declare running_total

  declare_switch(1)
  declare_switch(2)
  declare_switch(3)
  declare_switch(4)
  declare_switch(5)
  declare_switch(6)
  declare_switch(7)
  declare_switch(8)
end on

macro declare_switch(#var#)
  declare ui_switch $Test_Button_Preset_#var#
  id[running_total] := get_ui_id($Test_Button_Preset_#var#)
  inc(running_total)
end macro
```


----------



## Mike Greene (Nov 19, 2010)

This isn't especially elegant, and possibly as long as what you already considered "the long way," but maybe it's helpful:

on init
declare $newbutton {Will be 1 to 8, depending on which switch is pressed}
declare $oldbutton := 0 {Also 1 to 8, but starts at 0, since no button is yet pressed}
end on

on ui_control ($Test_Button_Preset_1)
Blah, blah, blah . . . 
$newbutton := 1

on ui_control ($Test_Button_Preset_2)
Blah, blah, blah . . . 
$newbutton := 2

on ui_control ($Test_Button_Preset_3)
Blah, blah, blah . . . 
$newbutton := 3

etc.

select($oldbutton) {Now we turn off the old button}
case 1
$Test_Button_Preset_1 := 0
case 2
$Test_Button_Preset_2 := 0
case 3
$Test_Button_Preset_3 := 0
case 4
$Test_Button_Preset_4 := 0
case 5
$Test_Button_Preset_5 := 0
case 6
$Test_Button_Preset_6 := 0
case 7
$Test_Button_Preset_7 := 0
case 8
$Test_Button_Preset_8 := 0

$oldbutton := $newbutton


----------



## Thonex (Nov 19, 2010)

Hey... THanks guys!!

@ Greg... nice!!! All those tips will definitely help reduce lines of code for the on init. 

@ Mike... Yeah... the old/new trick is cool. That's about how I would have approached it. I was wondering if there was an elegant way with _getui_id or set_par commands or similar.

Thanks guys!!!

Cheers,

Andrew K


----------



## kotori (Nov 20, 2010)

Oh, forgot to add:



Thonex @ Sat Nov 20 said:


> All you veterans out there probably know of a way to do this in 1 line of code using bit shift and mod zero :lol:


Instead of i / 4 in the code posted above you can of course use sh_right(i, 2) + i mod 0. The script would still not be a one-liner, but at least there would be some bit shift and mod zero in it :wink:


----------



## EvilDragon (Nov 20, 2010)

Greg's method has always worked for me. Basically the recipe is:

1. Always use arrays to store ID of similar groups of controls

2. For loops save the day!

3. Use math to position the controls while in a loop.

4. Get to love set_control_par and all its commands!

5. Get to ABSOLUTELY LOVE functions and macros in KScript!


----------



## andreasOL (Nov 20, 2010)

kotori @ Sat 20 Nov said:


> ...
> 
> Or an alternative even shorter version using some arithmetic for determining the IDs:
> 
> ...



Hi!

Just double reading that...

Is that somewhere specified by NI that ui element declare consecutively get consecutive ids?

Interesting...and helpful if reliable.

Best,
Andreas


----------



## EvilDragon (Nov 20, 2010)

It's not specified anywhere IIRC. But it seems to be true.


----------



## andreasOL (Nov 20, 2010)

Thanks, EvilDragon...much appreciated!


----------



## kotori (Nov 20, 2010)

Control IDs are incrementally assigned, but only to the same type of control as far as I remember (meaning that if you declare two buttons after each other the IDs will be consecutive, but if you declare two buttons and then a menu the menu ID will probably not be incrementally assigned relative to the button IDs.


----------



## EvilDragon (Nov 20, 2010)

Nope, Nils, check my script. 

Then try to put Label1 before Knob1, 2, 3, and put Label 2 after Knob 3, see what happens. They are all absolutely incrementally assigned, no matter the type of control. Really, this stuff should be in the devguide, or even the main KSP reference...


----------



## gregjazz (Nov 20, 2010)

Sorry, I tried posting this earlier, but the VI forum went down for maintenance.

Yes, the GUI ID numbers are consistently incremental in order of which ui elements are defined. These numbers start at 32768. The instrument icon's GUI ID is 16385, by the way.


----------



## Thonex (Nov 20, 2010)

Hey guys,

Thanks for posting these examples. 

The more way I see you guys do this... the more it sinks in. :lol: 

Cheers,

Andrew K


----------



## gregjazz (Nov 20, 2010)

Just write, rewrite, write... until you get your code as efficient as possible, using as few lines of code to achieve the desired result. Seriously, if your code starts getting messy and out of hand, start it again from scratch. Or at least go and revamp each section of code until it's neat again. Or better yet, just write it neatly in the first place.


----------



## andreasOL (Nov 21, 2010)

gregjazz @ Sun 21 Nov said:


> Sorry, I tried posting this earlier, but the VI forum went down for maintenance.
> 
> Yes, the GUI ID numbers are consistently incremental in order of which ui elements are defined. These numbers start at 32768. The instrument icon's GUI ID is 16385, by the way.



Yes, 32768 = 2^15, a pretty normal number for a computer  

I also wished NI would put this in the spec. At the moment - strictly speaking - this is an implementation detail whereas a program should be written against a specified interface only, i.e. the "api doc". Implementation may change without notice from version to version.

Maybe using this knowledge for a group of similar ui controls only is probably the safest, because for mixed ui type it's not bringing much code enhancement anyway.

- Andreas


----------

