ViewBuilder is inheritable

Just wanted to share a find that I didn’t know about until now.

The renoise.ViewBuilder class actually seems to be inheritable. This means that you can ‘expand’ ViewBuilder with your own “views” (like GUI tricks … or a ‘canvas’…) in a way that retains a close syntax to the original ViewBuilder.

Example:

Click to view contents
class 'NewBuilder' (renoise.ViewBuilder)
function NewBuilder:__init()
 renoise.ViewBuilder.__init(self)
end

function NewBuilder:fancy_slider(args)
 if args.uglymode then
 args.width = 100
 args.height = 100
 args.uglymode = nil
 end
 return self:slider(args)
end
function demo()
 local vb = NewBuilder()
 local content = vb:row {
 vb:fancy_slider { uglymode = true },
 vb:slider { }
 }
 renoise.app():show_custom_dialog("VB inheritance demo", content)
end
demo()

If you need to store additional values behind the scenes, this can’t (and should not) be done directly in the NewBuilder object. You would probably want expand it with your own sub-classes for more complex stuff.

I’m not sure if this is 100% compatible with the vb syntax when it comes the views table (using id:s), but anyhow it seems to be a cool way of using the same class for everything GUI related :slight_smile:

Wow, cool discovery.

I wouldn’t have expected that, since ViewBuilder is “userdata” (binding to the C++ implementation).

It could be major improvement over my vLib syntax, which requires you to initialize your components and then hand over a reference in the viewbuilder constructor table.

Definitely going to see if it’s feasible for my larger tools.

I’ve experimented a bit more. The main drawback is that, if you expand this with your own “sub-classes”, you have to do something like this to use them:

local my_dialogue = vb:row {
 vb:labeled_slider {
 label = "Panning" }.content
}

Note the “.content” call there. But I guess that’s acceptable.

PS. I haven’t checked if controls and views classes are inheritable, but I believe not.

Wow, cool discovery.

I wouldn’t have expected that, since ViewBuilder is “userdata” (binding to the C++ implementation).

Well, I’m not sure if it’s 100% true inheritance - maybe more of a feature/bug. You can add methods, but not properties. Still, it could be a nice way to simplify the syntax a bit for vLib, yes.

The sub-classes you make will be views rather than controls, of course and unfortunately. One thing that won’t work is something like “vb.views.custom_slider_object.width = 100”, since it will likely refer to some container rack that you’ve set up, rather than directly to your fancy class.

I find it unnecessary or even bad practice to use ID’s anyway. It’s always been a tell that my code isn’t optimally structured :slight_smile:

PS. Maybe there’s a small chance that the .content call above can be avoided by using some clever trick with classic classes instead of luabind? I feel that they’re potentially more flexible, but won’t investigate further…