the createHeadSprite script reveals some problems with GUI scripting

  • found here:

    Christoph, please write scripts with portability and usability in mind. Here is your script rewritten for a wider range of use with arbitrary variables removed:

    inline function addContinuousKnob(name, x, y, json)
        local widget = Content.addPanel(name, x, y);
        Content.setPropertiesFromJSON(name, json);
        widget.loadImage(widget.get("filmstripImage"), "filmstrip");
            var index = parseInt(this.getValue()*this.get("numStrips"));
            g.drawImage("filmstrip", [0, 0, this.getWidth()*this.get("scaleFactor"), this.getHeight()*this.get("scaleFactor")], 0, index * this.get("height"));
        // This is the sensitivity of the rotation = 300;
        // Save the down value as reference for all drag deltas = 0.0;
                // Store the current value for reference when dragging
       = this.getValue();
                // Use both axis to allow diagonal drag behaviour
                var delta = event.dragX + -1.0 * event.dragY;
                // normalize the delta using the given sensitivity
                var deltaNormalized = delta /;
                // Calculate the new value and truncate it to 0...1
                var newValue = + deltaNormalized;
                newValue = newValue - Math.floor(newValue);
                // Update the panel
            if (event.doubleClick)
        return widget;

    example json:

    HeadKnob1_json = {
      "width": 263,
      "height": 356,
      "defaultValue": 0.5,
      "filmstripImage": "{PROJECT_FOLDER}3D/head1.png",
      "numStrips": 100,
      "allowCallbacks": "Clicks, Hover & Dragging",
      "scaleFactor": .5

    example usage

    const var HeadKnob1 = addContinuousKnob("HeadKnob1", 0, 0, HeadKnob1_json); 

    This lacks all the convenience of creating a standard slider with the right-click "Add new Slider" menu.

    Honestly, I wouldn't bother with this graphics code stuff, it's a pain. You should add more properties, more flexibility to the built-in slider. You said you don't want to clutter the... I dunno what you don't want to clutter... I think HISE still lacks fundamental knob types and options.

  • Well, the built in Slider would not support continuous movement without rewriting the whole JUCE class, so this is really a job for the ScriptPanel. I am aware that this example is very specific and not portable (eg. the six state button is more likely to be used as template for other projects).

    What do you find painful when using custom UIs? You'll have to create them once by actually typing the factory method, but then duplicating / moving should work just like with the rest of the widgets (and these two operations are the most often used ones).

    And with clutter I meant the amount of properties that sit there and force the user to scroll around in the property list. I'd say that 99,999% of all Sliders will not need a continuousValue feature - apart from a rotating head it's still pretty difficult to think of another user case 🙂 I do add the font properties you were requesting though as this is more likely to be used.

    I also remember it was you that told me to be cautious what feature requests to implement stating REAPER as negative example for a application with a feature set that got out of control.

  • A big difference between feature requests with Reaper and HISE is that with HISE you can fork it and add your own features (or pay someone else to)... I wish Reaper was GPL 😞

  • Why doesn't this forum have a quote feature?

    "What do you find painful when using custom UIs"
    Everything that comes after code. Finding the position, resizing, getting image width/height, all of the specifics. That's part of why you have a UI editor... you can't use it with custom graphics. You could make it possible if you improved the way HISE edits JSONs. As you can see I set many parameters via JSON just like when using a built in UI slider.

    "I'd say that 99,999% of all Sliders will not need a continuousValue feature"
    Continuous knobs are a feature found on real-world hardware interfaces.

  • How do I make the continuous knob midi learnable?

  • Just set the "enableMidiLearn" property to true 🙂

  • How would I take that continous knob script and make that default true until someone adds enableMidiLearn as false?

  • inline function createHeadSprite(name, x, y)
        local widget = Content.addPanel(name, x, y);
        Content.setPropertiesFromJSON(name, {
          "width": 200,
          "height": 200,
          "enableMidiLearn": true, // <<== The magic happens here...
          "saveInPreset": true,
          "allowCallbacks": "Clicks, Hover & Dragging"

    or in your version:

    inline function addContinuousKnob(name, x, y, json)
        local widget = Content.addPanel(name, x, y);
        Content.setPropertiesFromJSON(name, json);
        widget.set("enableMidiLearn", true); // important to do this after the JSON restoring...

  • waaaat, why wouldn't that override the json? by doing widget.set("enableMidiLearn", true); after Content.setPropertiesFromJSON(name, json);

  • Oh, it looks like we need Content.addPropertiesFromJSON(name, json); otherwise you can't do default values. ADD rather than SET/overwrite

  • IIRC setPropertiesFromJSON() already just overwrites the properties that are passed in.

  • That means I can't put a default value. Please consider my earlier suggestion. Content.addProperties

    edit: or maybe there's a way to combine two jsons before going to setProperties?

  • Please tell me you are going to do something to allow default values. I don't have time to learn the C++ API right now and so I'd like to create a library of GUI widgets in javascript.

  • Is there a way to combine JSONs?

    Edit: No that wouldn't work, that would overwrite copy JSON properties unless something could be done about that to allow the 1st or last of the properties to be used.

  • I think the functionality is already there:

    const var Button = Content.addButton("Button", 10, 10);
    Content.setPropertiesFromJSON("Button", {
      "enabled": false	
    Content.setPropertiesFromJSON("Button", {
      "width": 160,
      "height": 30

    This button will still be disabled because the second JSON doesn't overwrite the enabled property. This should allow you to set default values that won't be overwritten unless you explicitely add them in the JSON object.

  • ok great, works!

  • I tried doing "enableMidiLearn": "true" (with and without quotes on true) in the json but it didn't allow the continuous knob to be midi learnable, maybe because I don't have a right click callback setup? I wouldn't know how to set that up for midi learn.

Log in to reply