Function as an argument

So I’m looking for a way to do the following:
I’d like to define a function to (in this case) create a button (or multiple).
Therefore I created a function where I pass in (scene, UI target, options)
In the options I’d like to supply optional arguments like name, dimensions, positioning, but also an action a more extensive function for example.

This generates the button itself

// >>> ButtonCreator
let CreateButton = function (scene, ui = undefined, options) {
    if (!ui) { let UImain = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI('UImain', true); ui = UImain; }; // create if doesn't exists
    let theme_col_btn_bg = '#DADADA';


    let name = typeof options.name !== 'undefined' ? options.name : 'DefaultButton';
    let top = typeof options.top !== 'undefined' ? options.top : 10;
    let right = typeof options.right !== 'undefined' ? options.right : 10;
    let bottom = typeof options.bottom !== 'undefined' ? options.bottom : 10;
    let left = typeof options.left !== 'undefined' ? options.left : 10;
    let width = typeof options.width !== 'undefined' ? options.width : 115;
    let height = typeof options.height !== 'undefined' ? options.height : 40;

    let verticalAlignment = typeof options.verticalAlignment !== 'undefined' ? options.verticalAlignment : 0;
    let horizontalAlignment = typeof options.horizontalAlignment !== 'undefined' ? options.horizontalAlignment : 0;

    let background = typeof options.background !== 'undefined' ? options.background : (typeof theme_col_btn_bg !== 'undefined' ? theme_col_btn_bg : '#7D8F7D');
    let thickness = typeof options.thickness !== 'undefined' ? options.thickness : 0.2;
    let action = typeof options.action !== 'undefined' ? options.action : "function () { Log('hello ' + name); }"; // not working yet to pass function through options...
    Log(action);

    let btn = BABYLON.GUI.Button.CreateSimpleButton(name, name);
    if (top != 'x') { btn.top = top + "px"; }
    if (right != 'x') { btn.right = right + "px"; }
    if (bottom != 'x') { btn.bottom = bottom + "px"; }
    if (left != 'x') { btn.left = left + "px"; }
    btn.width = width + "px";
    btn.height = height + "px";
    btn.verticalAlignment = verticalAlignment;
    btn.horizontalAlignment = horizontalAlignment;
    btn.background = background;
    btn.thickness = thickness;
    if (!action == '') {
        btn.onPointerClickObservable.add(eval(action)); // not working yet
        Log('was func');
        // do something
    }

    ui.addControl(btn);
}

This will create multiple buttons based on a dict list.

// >>> ButtonCreator
let GenBtnCol = function (scene, list) {
    let i = 0
    for (const [key, value] of Object.entries(list)) {
        let btn_h = 35;
        let space_v = i == 0 ? btn_h + 10 : 5;
        // Log(space_v);
        CreateButton(scene, undefined, {
            name: key,
            top: ((i) * (btn_h + space_v)) + btn_h + 20,
            right: 'x',
            bottom: 'x',
            height: btn_h,
            left: '10',
            action: value,
        });
        i++;
    }
}

This one creates the buttons based on the dict as second argument.
The key will be the name of the button, as second arg I’d like to add a function which can be added to the button by: “btn.onPointerClickObservable.add”

    GenBtnCol(scene, {
        'Top': '',
        'Focus': '',
        'Overview': '',
        'Lights': action_functionHere,
    });

This is an example of the function I’d like to add to the button

MeshLoader(scene, {
    path: '../../../../resources/models/BlenderExportTest_00/',
    filename: fn,
});

I like to define my settings and parameters in a dict, and generate my objects based on that so that I have the maximum flexibility, and also minimize the code in the createScene function which makes it more readable and allows for quick testing and adjustments.

Thanks!

You can simply pas a function as an argument of another function to do extra work as a callback:

2 Likes

Thanks for the tip.
However I can’t get this to work, I’ve tested it in a PG
It seems that the issue here is that the function isn’t attached to the button…

Thank you
Pieter

here you go , this is just a quick hack with minimal changes to your code to make it work for you :

There is obviously much more not done here , scope is not considered , arguments of API method callback not used or passed along etc…

1 Like

Hi @shaderbytes

Thanks for the help, I’ll try it out and see If I can manage to get this done with your hack.
In the future I might get back here, because I imagine there is a lot of potential to assign a number of different functions each to a specific object or button with their custom attributes.

Thanks again!

1 Like