What's new

How to skin menus [SOLVED]

Fredeke

Senior Member
Hi again everyone.

I just started my first skinned script, so I might have a lot of questions for the next few weeks... Here's the first one ;)

I'm having a hard time determining which UI elements are skinnable (I mean, for which kind can I provide a custom picture to replace its generic look)

( - Already solved: I wanted to skin knobs, and since they were not skinnable, I had to emulate them with knob-skinned sliders, and that works fine. )

( - I also wanted to skin buttons, and since they are skinnable and there's plenty info on how to do this, I achieved it easily. )

- But, are menus skinnable ? If so, I'd like to see an example of code for this.

- How about labels ? (Example welcome too)

- If menus and/or labels are not skinnable, which class of element can I emulate them with ? (Like, buttons with changing picture, for example ?) - and how to do that ? (Here I don't necessarily need the code, but at least the principle in plain English)

Thank you all in advance.
 
A menu can have a graphic, but only for it's "closed" state. When it's open it looks the same as you see it now.
A label can have a graphic.
 
Last edited:
Actually ui_menus do use frames 1, 3 and 5 of the regular 6-frame button graphic. It's just often covered by what pops up so you don't see it.
 
@polypx : well that's better than nothing anyway, and maybe sufficient for me not to bother with a workaround...

@EvilDragon : I am much interested in what you're saying, but I'm not really getting it. Could you elaborate please ? ( I know what a 6-frame button graphic is, but that's about it)
 
Actually ui_menus do use frames 1, 3 and 5 of the regular 6-frame button graphic. It's just often covered by what pops up so you don't see it.

Ah right, I noticed the rollover before, but never the mouse down. ;) In any case, in terms of customisation, what I meant was you can't customize the popup once it's "popped up". You can't even set those fonts.
 
Ok, so I'm trying to do as you suggest... And here's already my next question:

Since the menu's pop-up cannot be customized, I've got to populate it with add_menu_item(), right ?
Then how do I prevent the text of the selected entry from showing on top of my custom picture ?

(in short... Which $CONTROL_PAR do I need to _HIDE ? ;) )
 
@P.N. : Dirty, funny and efficient solution :-D I just followed your advice and it works. Is it really the proper way however ?
 
I mourn my customized pop-ups, but I'll probably stick to your way because a workaround would add complexity to an already extensive script. I'll first implement your advices and see how it looks.

One thing I still don't get (and I believe EvilDragon tried to explain) : how would you change the menu's graphic according to the selected entry ?
 
At least for Kontakt 5. Maybe K6 will have a dedicated command for this in the future...

I read they added the $CONTROL_PAR_TEXTPOS_Y for value_edits, which is very welcome, so.. who knows?

Cheers.
 
One thing I still don't get (and I believe EvilDragon tried to explain) : how would you change the menu's graphic according to the selected entry ?

Evil Dragon was talking about the image states for the menu graphic element.

What you need is a label, with picture states that are updated based on the selected entry.

You place it under the menu (it will be under by default). Make your menu graphics transparent (maybe just add picture state 5 for mouse over) and that's it.
 
Ok I almost got it.

What do you mean by "updating the picture states" ? To what command do you refer ? Do you mean changing the picture file ? (And why is it easier to do with labels than menus ?)
 
Right.
Now N.I.'s manual is pretty laconic about $CONTROL_PAR_PICTURE_STATE. All it says is : "the picture state of the control for tables, value edits and labels."
... So, what is a picture state ? And what values can I give it ? (Anything to do with 1 to 6, maybe ?)
 
@P.N. : Yes, please ! And later is fine, since I've got to go for now.
Good evening (or morning, or something) :)
 
Now N.I.'s manual is pretty laconic about $CONTROL_PAR_PICTURE_STATE. All it says is : "the picture state of the control for tables, value edits and labels."
... So, what is a picture state ? And what values can I give it ? (Anything to do with 1 to 6, maybe ?)
For some reason, they explain this in the Developers Guide (which dates back to Kontakt 4), but I don't think it's in the regular KSP manual. So if you don't have this already, here is the documentation from the Developers' Guide:

5.5 Preparing Image Files

5.5.1 Accompanying Text File


Each image must be accompanied by a text (.txt) file of the same name containing important information on how KONTAKT should read this image. If a text file is not provided, any image file in the user picture folder will have a default one generated. If the image file is in the factory folder a text file will not be generated, but the image will be read by KONTAKT as if the values were set to default.

Here is an example of the content of one of these text files:
Has Alpha Channel: yes
Number of Animations: 6
Horizontal Animation: no
Vertical Resizable: no
Horizontal Resizable: yes
Fixed Top: 0
Fixed Bottom: 0
Fixed Left: 0
Fixed Right: 17

The list explained:

 Has Alpha Channel: (yes or no) tells KONTAKT whether or not the image file contains a transparent (alpha) layer. If in doubt, set this to “yes”, as this will cause no problems either way.

 Number of animations: sets the number of frames in the image. KONTAKT then equally divides the image using this number.

 Horizontal Animation: (yes or no) designates in what direction the image should be split.

 Vertical Resizable: (yes or no) if set to yes, it is possible to adjust the height of the image file in KONTAKT using the $CONTROL_PAR_HEIGHT constant in the set_control_par command.

 Horizontal Resizable: (yes or no) if set to yes, it is possible to adjust the width of the image file in KONTAKT using the using the $CONTROL_PAR_WIDTH constant.

 Fixed Top/Bottom/Left/Right: if you wish to be able to resize an image, but keep a certain area around the edge intact, simply set the number of pixels in the desired area. In the above example, the image is able to be resized horizontally, but the 17 pixels on the right side of the image will not be stretched.

It is important to note that KONTAKT is currently very sensitive about text file line break encoding. In our experience, the safest software to use is Notepad on Windows. This is unfortunately also true for scripts that link to external text files.

Please take note that wallpapers also need a text file although the text file’s parameters will be ignored.

5.5.2 Animations

Image files to be used in KONTAKT must be saved as *.png files. In order for KONTAKT to treat the image correctly, it must be provided in as stack of animations. So if you want one knob with 100 states, you need to build a very long image with all of these states in a row or column. KONTAKT will read the file top to bottom or left to right, depending on the setting of the .txt file. So your lowest value for a knob should be at the top or left and the highest at the bottom or right.

5.5.3 Switches and Dropdowns

Switches and Dropdowns should always have six animations, in a set order:

State
  1. 1 Off
  2. 2 On
  3. 3 Off, mouse down
  4. 4 On, mouse down
  5. 5 Off, mouse over
  6. 6 On, mouse over
The following script will illustrate the different states of a switch.

► First, copy the image and text files “switch_state_example” to the KONTAKT 4 user pictures folder. Then copy and paste the following script into a new KONTAKT instrument:

on init
make_perfview
declare ui_switch $switch_states
set_control_par_str(get_ui_id($switch_states),$CONTROL_PAR_TEXT,"")
set_control_par_str(get_ui_id($switch_states),$CONTROL_PAR_PICTURE,...
"switch_state_example")
end on

This will produce a single button that changes color depending on its state:

State
1 Off Black
2 On Red
3 Off, mouse down Orange
4 On, mouse down Yellow
5 Off, mouse over Purple
6 On, mouse over Green

Image files must always have six animations, even if you only plan to use the basic on/off. In this case, just triplicate the two on/off animations to bring the total up to six.
 
Here's an nki with 2 possible scenarious:

The first would be the typical menu, with fixed mouse over image: Fixed Mouse Over Images.png

The second would update the menu mouse over image with something that matches the labels:
Dynamic Mouse Over Images.png

Since i tried to include both scenarious in one nki, some of the code may be confusing.
Let me know.
You could use string arrays for the dynamic menu images, but it wasn't necessary in this case as the images are numbered according to the menu values.

You could ditch the menu image completely if it's not something you need.
In that case, simply leave the menu images transparent.

Cheers.

EDIT: Forgot to include the code:

Code:
on init
    {General}
    set_ui_height_px(278)
    set_ui_color(994948fh)
    make_perfview
    
    {Positions}
    declare $pos_x := 227
    declare $pos_y := 50
    declare $offset := 3
    
    {Menu}
    declare ui_menu $menu
    set_control_par_str(get_ui_id($menu),$CONTROL_PAR_PICTURE,"menu_outline")
    set_control_par(get_ui_id($menu),$CONTROL_PAR_TEXTPOS_Y,200)
    move_control_px($menu,$pos_x,$pos_y)
    make_persistent($menu)
    
    {Menu Entries}
    add_menu_item($menu,"SQUARE",0)
    add_menu_item($menu,"CIRCLE",1)
    add_menu_item($menu,"TRIANGLE",2)
    
    {Menu Label}
    declare ui_label $menu_entries_label(1,1)
    set_control_par_str(get_ui_id($menu_entries_label),$CONTROL_PAR_TEXT,"")
    set_control_par_str(get_ui_id($menu_entries_label),$CONTROL_PAR_PICTURE,"menu_entries_label")
    move_control_px($menu_entries_label,$pos_x+$offset,$pos_y+$offset)
    
    {Option}
    declare ui_button $option
    set_control_par(get_ui_id($option),$CONTROL_PAR_WIDTH,181)
    set_control_par_str(get_ui_id($option),$CONTROL_PAR_TEXT,"")
    set_control_par(get_ui_id($option),$CONTROL_PAR_TEXT_ALIGNMENT,1)
    move_control_px($option,$pos_x+$offset,$pos_y-30)
    make_persistent($option)
    
    declare !option_text[2]
    !option_text[0] := "FIXED MENU MOUSE OVER IMAGE"
    !option_text[1] := "DYNAMIC MENU MOUSE OVER IMAGE"
    
end on

function menu_update
    set_control_par(get_ui_id($menu_entries_label),$CONTROL_PAR_PICTURE_STATE,$menu)
    
    if($option = 0)
        set_control_par_str(get_ui_id($menu),$CONTROL_PAR_PICTURE,"menu_outline")
    else
        set_control_par_str(get_ui_id($menu),$CONTROL_PAR_PICTURE,"menu_outline" & "_" & $menu)
    end if
    
    set_control_par_str(get_ui_id($option),$CONTROL_PAR_TEXT,!option_text[$option])

end function

on persistence_changed
    call menu_update
end on

on ui_control($menu)
    call menu_update
end on

on ui_control($option)
    call menu_update
end on
 

Attachments

  • Menu Example.rar
    40 KB · Views: 90
Top Bottom