Functions in user data of ComboBox's items array cannot be called

In the console window’s terminal, enter the following:

studio.ui.showModelessDialog( {
    windowTitle: "Hello world",
    widgetType: studio.ui.widgetType.Layout,
    layout: studio.ui.layoutType.VBoxLayout,
    contentsMargins: { left: 0, top: 0, right: 0, bottom: 0 },
    items: [
        {
            widgetId: "mSoundTypes",
            widgetType: studio.ui.widgetType.ComboBox,
            items: [
                { text: "SingleSound", userData: 9 },
                { text: "MultiSound", userData: function() { return 3; } }
            ],
            currentIndex: 0,
            onCurrentIndexChanged: function() {
                console.log(this.currentText());
                console.log(this.currentUserData());
                console.log(this.currentUserData()());
            }
        }
    ]
} )

If desired this is the same code, but as one line: studio.ui.showModelessDialog( { windowTitle: "Hello world", widgetType: studio.ui.widgetType.Layout, layout: studio.ui.layoutType.VBoxLayout, contentsMargins: { left: 0, top: 0, right: 0, bottom: 0 }, items: [ { widgetId: "mSoundTypes", widgetType: studio.ui.widgetType.ComboBox, items: [ { text: "SingleSound", userData: 9 }, { text: "MultiSound", userData: function() { return 3; } } ], currentIndex: 0, onCurrentIndexChanged: function() { console.log(this.currentText()); console.log(this.currentUserData()); console.log(this.currentUserData()()); } } ] } )

Next, select each option in the dropdown.
Observe that the first option correctly prints SingleSound, prints 9, and then errors with 9 not being a function.
Observe that the second option correctly prints MultiSound, but then incorrectly prints [ object Object ], and then errors with object not being a function.

Note that this is in contrast to entering the following into the terminal:

myObject = { foo: 0, bar: "hello", buzz: function() { return 7; } }

After which, each of the following work fine and give the expected result:

  • myObject.foo prints 0
  • myObject.bar prints hello
  • myObject.buzz prints function () { return 7; }
  • myObject.buzz() prints 7

The existing behavior greatly limits the usability of the dropdowns. Nevertheless, there are workarounds, so I don’t think this is a high priority issue. It is also fairly niche I think, since there are so few questions about the scripting API’s custom UI on the forums.

One such workaround is to use each element as an index into an array of functions stored elsewhere or as a value to match against in a switch statement.

Another workaround is to construct the function later such as below:

studio.ui.showModelessDialog( {
    windowTitle: "Hello world",
    widgetType: studio.ui.widgetType.Layout,
    layout: studio.ui.layoutType.VBoxLayout,
    contentsMargins: { left: 0, top: 0, right: 0, bottom: 0 },
    items: [
        {
            widgetId: "mSoundTypes",
            widgetType: studio.ui.widgetType.ComboBox,
            items: [
                { text: "SingleSound", userData: 9 },
                { text: "MultiSound", userData: "return parameterValue * 2" }
            ],
            currentIndex: 0,
            onCurrentIndexChanged: function() {
                console.log(this.currentText());
                console.log(this.currentUserData());
                var foo = new Function("parameterValue", this.currentUserData());
                console.log(foo(3));
            }
        }
    ]
} )

Although it does not work to construct the function in place as below:

studio.ui.showModelessDialog( {
    windowTitle: "Hello world",
    widgetType: studio.ui.widgetType.Layout,
    layout: studio.ui.layoutType.VBoxLayout,
    contentsMargins: { left: 0, top: 0, right: 0, bottom: 0 },
    items: [
        {
            widgetId: "mSoundTypes",
            widgetType: studio.ui.widgetType.ComboBox,
            items: [
                { text: "SingleSound", userData: 9 },
                { text: "MultiSound", userData: new Function("parameterValue", "return parameterValue * 2") }
            ],
            currentIndex: 0,
            onCurrentIndexChanged: function() {
                console.log(this.currentText());
                console.log(this.currentUserData());
                console.log(this.currentUserData()(3));
            }
        }
    ]
} )

Anyway, it would be nice if the UI system supported functions the same way they are supported for object literals.

This is definitely a bug, thank you for bringing this to our attention. We’ve raised a bug report and will take a look into it for a future release.

1 Like