Yeah, I haven't made doc's yet, because I haven't finished the extension. I want to add textboxes, scroll bars and stuff like that.
You are doing everything correctly as far as I can see. Callback is just a script that is called. When you left click the button, the script should be executed. It should also pass arguments to it identifying the event, button id and so on. I haven't found a better way to do this, as don't support Lambda functions or the like. The extension is far more advanced in the branch here:
https://github.com/enigma-dev/enigma-dev/tree/GL3.3NormalMatrixI am saying that, because I can make you an example, but it will only work in that branch, as many things have changed. For example, in the callback function you can actually specify the event (right now it can be pressed, released or hover). Or the windows can be resized.
I have attached a simple example. It shows how many elements work, including toggles, buttons, windows, groups, sliders, styles, skins and callbacks.
I would appreciate feedback on how to progress with it. Originally I took Unity3D as reference, but because of the way EGL/GML works I was quite limited. For example, I cannot create one function window_add_element which adds buttons, toggles, other windows etc. I have to create a function for every element type. Callbacks calling scripts is also the only way I know how they could work. But as everything is calculated in _draw function, then the callback calls the script inside that object as well. So if you want a button to do something for another object, you have to do "with (obj_){}" inside the callback. None of this is particularly ugly, as that is how GM done it for years, so most people got used to it. But I personally want this to be prettier.
Another thing I want to do is allow "texture" to be set as image or as content. So you can have the regular button style, but the content is not text, but another image. I want this so I could add surfaces as backgrounds. Right now you have _set_sprite, which uses a sprite. If I want to use backgrounds, I will need to add _set_background, for surfaces _set_surface. It multiplies the number of functions for no good reason. I could add _set_texture which would replace all of the functions, but then you would have to call _set_texture(sprite_get_texture(spr_button, 0)) which is not pretty again. And sprites can be animated, which is not possible with textures without you incrementing the second argument explicitly.
Here is screenshot for the example:

I put an ugly ass ghost image in the background to check transparency. I should probably replace it.