Plug'n Script Custom KUIML Buttons Not Rendering

Official support for: bluecataudio.com
Post Reply New Topic
RELATED
PRODUCTS

Post

Hi, I'm new to Plug'n Script and have been working on building a custom GUI for a DSP script. I've made a lot of progress, but I've hit a final wall and I'm hoping someone with more experience can spot what I'm doing wrong.

I'm trying to create a simple interface with a knob, a switch, a clip light, and several buttons that modify a parameter.

My DSP script (.cxx) works perfectly as far as I can currently tell, and the custom GUI (.kuiml) file is being loaded. Some components render correctly (the knob, text labels, and the LED), but my buttons are invisible. Only their text labels appear, with no background or interactivity.

I am running Reaper (latest version), Windows 11, and Plug'n Script VST3 (latest version)

I have confirmed the following:

1) The .cxx and .kuiml files have the exact same name and are in the same folder.
2) The KUIML root element is <SKIN>.
3) All component tags are UPPERCASE and attributes are lowercase.
4) Parameters are correctly referenced using the custom_paramX and custom_out_paramX convention.
5) The PNS_... components for the knob and LED are working, but the buttons I've built inside a <TEMPLATE> are not.

My kuiml file is pasted here:

Code: Select all

<SKIN>
  <TEMPLATE id="TPL_TEXT_BUTTON" text="undefined" onclick="">
    <LAYER_STACK width="100%" height="22" h_align="center" v_align="center">
      <PANEL border="true" background_color="#555555" width="100%" height="100%"/>
      <INVISIBLE_ACTION_BUTTON onclick="$onclick$" cursor="system::hand" width="100%" height="100%"/>
      <TEXT value="$text$" text_align="centered" transparent="true"/>
    </LAYER_STACK>
  </TEMPLATE>

  <PANEL>
    <COLUMN spacing="5">
      <TEXT value="Gain" font_size="16" font_style="bold" text_align="centered"/>
      <TEXT value="Shift-click buttons to subtract gain" font_size="10" text_align="centered"/>
      <ROW margin="10" padding="5" spacing="20" align="center">

        <PNS_BLUE_FLAT_KNOB param_id="custom_param0" show_value="true" height="120" text_input_enabled="true"
              ondblclick="PARAMS['custom_param0'].value = PARAMS['custom_param0'].default_value;"/>
        
        <COLUMN spacing="5" width="80">
          <TPL_TEXT_BUTTON text="+/- 24 dB"  onclick="if(KEY_MODIFIERS.shift) { PARAMS['custom_param0'].value = max(PARAMS['custom_param0'].min, PARAMS['custom_param0'].value - 24); } else { PARAMS['custom_param0'].value = min(PARAMS['custom_param0'].max, PARAMS['custom_param0'].value + 24); }"/>
          <TPL_TEXT_BUTTON text="+/- 12 dB"  onclick="if(KEY_MODIFIERS.shift) { PARAMS['custom_param0'].value = max(PARAMS['custom_param0'].min, PARAMS['custom_param0'].value - 12); } else { PARAMS['custom_param0'].value = min(PARAMS['custom_param0'].max, PARAMS['custom_param0'].value + 12); }"/>
          <TPL_TEXT_BUTTON text="+/- 6 dB"   onclick="if(KEY_MODIFIERS.shift) { PARAMS['custom_param0'].value = max(PARAMS['custom_param0'].min, PARAMS['custom_param0'].value - 6); } else { PARAMS['custom_param0'].value = min(PARAMS['custom_param0'].max, PARAMS['custom_param0'].value + 6); }"/>
          <TPL_TEXT_BUTTON text="+/- 3 dB"   onclick="if(KEY_MODIFIERS.shift) { PARAMS['custom_param0'].value = max(PARAMS['custom_param0'].min, PARAMS['custom_param0'].value - 3); } else { PARAMS['custom_param0'].value = min(PARAMS['custom_param0'].max, PARAMS['custom_param0'].value + 3); }"/>
          <TPL_TEXT_BUTTON text="+/- 1.5 dB" onclick="if(KEY_MODIFIERS.shift) { PARAMS['custom_param0'].value = max(PARAMS['custom_param0'].min, PARAMS['custom_param0'].value - 1.5); } else { PARAMS['custom_param0'].value = min(PARAMS['custom_param0'].max, PARAMS['custom_param0'].value + 1.5); }"/>
        </COLUMN>

        <COLUMN spacing="5" align="center" padding="10">
          <TPL_TEXT_BUTTON text="Limiter" width="60" onclick="PARAMS['custom_param1'].value = 1-PARAMS['custom_param1'].value;"/>
          <PARAM_TEXT param_id="custom_param1" content="{text_value}" font_weight="bold"/>
          <PANEL border="true" width="50" v_margin="10">
            <COLUMN align="center">
              <TEXT value="Clip"/>
              <PNS_RED_LED param_id="custom_out_param0"/>
            </COLUMN>
          </PANEL>
        </COLUMN>
        
      </ROW>
    </COLUMN>
  </PANEL>
</SKIN>
My main question is: what is wrong with my <TEMPLATE> or <LAYER_STACK> structure that would cause the <PANEL> and <INVISIBLE_ACTION_BUTTON> components to be ignored, while the <TEXT> element renders correctly?

Thank you so much for your time and for this amazing plug-in! Any advice would be greatly appreciated.

Post

Hi,

What is the PANEL element? Is it a custom element that you have defined earlier?

Post

Another thing I noticed is
<INVISIBLE_ACTION_BUTTON onclick="$onclick$" />
but there's no "onclick" attribute for INVISIBLE_ACTION_BUTTON, only action_id
also "ondblclick" at PNS_BLUE_FLAT_KNOB - do you implement it yourself somehow?

Just in case, if you use ChatGPT or something for generating KUIML - don't, it does stupid absurd stuff, as I've noticed.
Here are some articles on KUIML:
https://pns.letimix.com/kuiml/

Post

ilyaorlov wrote: Sat Aug 23, 2025 11:17 am Another thing I noticed is
<INVISIBLE_ACTION_BUTTON onclick="$onclick$" />
but there's no "onclick" attribute for INVISIBLE_ACTION_BUTTON, only action_id
also "ondblclick" at PNS_BLUE_FLAT_KNOB - do you implement it yourself somehow?

Just in case, if you use ChatGPT or something for generating KUIML - don't, it does stupid absurd stuff, as I've noticed.
Here are some articles on KUIML:
https://pns.letimix.com/kuiml/
ChatGPT is definitely not a good solution to write code for you!

Post Reply

Return to “Blue Cat Audio”