Observables, Viewbuilder Elements And Rounding Etc


I really need help clarifying this;

See also previous post

Say I’m building a tool

I have a vb:slider to edit a value.
I have a vb:value to show the value.
I have a document with a variable/property to store/bind the value.

I want the vb:value to show the value of the slider rounded to an integer.
I would prefer to have the value stored in the document the same way, but this is not a demand.
When I save the document, the value is saved, when I load a document the value is loaded.

How do I solve this in a good way?

If i just bind the vb:slider and vb:value to the document observable I cannot modify (round/floor) the value because it causes feedback…
I can use tonumber for the vb:value (but not tostring), but when when i adjust the slider the value is not rounded as I had expected…

So, then I have the option not to bind the vb: elements to the document observable variabl, but create a function that observes it instead, and then the notifier for the vb;slider changes the value of the document variable, but then I have to access the vb:value from that function, and then it gets messy.


I believe this is the part of my code I tried to point you at when I lined to the tool. It will bind the slider to the valuebox in integers. It also gets binded to document def.lines

I have to admit I struggled most with this part so exactly how it all works is a little rusty. Hopefully it can point you in the right direction though.

 text = "Lines"  
 value = lines,  
 notifier = function(slider_value)  
 lines = math.floor(slider_value+0.5)  
 min = 0,  
 max = 32,  
 bind = def.lines  
 min = 0,  
 max = 32,  
 bind = def.lines,  
 tostring = function(value)  
 return ("%.0f"):format(tostring(value))  
 tonumber = function(str)   
 return tonumber(str)  

Ah, duh, vb:valuefield has unlike vb:value the tostring callback. I thought valuefield would be a field, like as in a editable textbox.

Superconfusing why vb:value even exists…

So I guess still the resulting document variable is saved with all the decimals, well then so be it.

IMO it would be waaaaay better if the slider would have a way to do any modification to the value


Am I not storing Lines, rather than slider_value, and thus it is only storing the integer (rounded up)?

It is. I can click on it, change it’s value and see the Slider follow it.

The valuer-field only has numeric values. The ToString and ToNumbers within the function are only for formatting the display results in the valuefield object. If you want to store the object as a string always use something similar like this: mystoredvaluestring = tostring(vb.views[‘yourobjectid’].value) and use vb.views[‘yourobjectid’].value = tonumber(mystoredvaluestring) to restore the value.

Hmm, let me just see if I got this right;

You are binding to def.lines. That is a renoise.Document.ObservableNumber, right?

bind = def.lines  

And then you change the variable lines, which is a global variable, right?

notifier = function(slider_value)  
 lines = math.floor(slider_value+0.5)  

So, then def.lines in the renoise.Document will be say 60.1231231, and lines will be 60, right? And then the valuefield is bound to def.lines, but it rounds in tostring so it displays 60 too.

But lines and def.lines has really nothing to do with eachother. When I save the document it will save the value of 60.1231231, right?

Not that it matters, just want to make sure that I’m not missing something…

Haha, never realized that, cool, I guess that goes for the rest of the ui.

You’re right lines is a variable used through the script, still a local variable in LUA talk though.

I guess you’re right that the whole number, with decimals, is stored in the document. As I said the binding confused me a little but I was happy to manage to sync the valbox and the slider correctly. That was my main aim and that was managed.

def is a document (table?) created with the below code early in my tool. I don’t have it saved and restored between sessions though, which is something I was going to look at later. But to use to bind the two fields together I seemed to have to use the observable document, rather than a normal table, unless I really wasn’t understanding things.

local def = renoise.Document.create("defaults"){  
 x = x,  
 x_min = 0,  
 x_max = 16,  
 lines = lines,  
 lines_min = 0,  
 lines_max = 32,