[Solved] Help: slider to navigate tracks. Problems notifier and? _obse

Thanks 4Tey, but the problem was to work the slider also. Actually, your modified xrnx is like a step back, before adding the lines to make the slider work. I have returned to the original xrnx and followed the instructions of joule.

Yes Raul, you took my ‘step back’ and followed the instructions of Joule. And did it work? Nope. Why? Why do you think I took a step back? Do you think it will work when Danoise presents his example scrollable table? It might. In the context of Danoise code that is. You will just blissfully copy Danoise code and try and place it into your GT16 code. Why do this? Because it is easy, it is faster. What’s the problem with this approach? Well over time you get the situation you have now with the current state of your code. Most of your code Raul is built from copy/pasting, without fully understanding the underlying principles of basic lua programming and how it interacts with Renoise. It is remarkable it works at all really.

You see Raul Danoise and Joule are speaking to you as though you already have a fair experience of programming. Sure they will show you (advanced) examples and so forth, which you then take and try to apply to your own tool. But this approach isn’t too good in the long run. You are trying to write too complicated a tool for your own ability. Danoise and Joule are just giving you examples that are too advanced. Even I can’t understand some of the examples these coders are posting! (And I think it is safe to say I’m a more advanced programmer than you are Raul.)

My best advice: Only you Raul can learn how to program. You’ve got to simplify everything. Here is my philosophy that I’ve followed for the past god knows how many years now…

Only program what you understand

Hi 4Tey.I tell you a little what has happened here. I’m trying to create my own tool (add more things for new version), and learning by the way, also.Almost 90% of the code I need is already built, missing some details, and many have.So far, I understand most of the code, but I had a pending issue: make interacting a slider with Renoise.For this slider to work, my initial code must have a particular order.When you have modified the file, you have just returned to the starting point, “one step back”.

My tool already worked 100% before (without errors), but without using the slider.The slider did not work and that’s why I asked int the forum.I saw a Joule tool, which had something similar (joule.no0b.Transporter.xrnx).I tried to look at the code, and of course, I try to understand it.In it uses several lines = nil, which have to do with the load of viewbuilder, that is a little confusing.

Now I’m at a new point.The slider works, and I know why it works.What I want is use various lua archives for different pieces of the GUI (viewbuilder), which is as it was initially, because the tool is long.

On the subject of Danoise of scrollable table,it is an issue that has nothing to see here, comes from another topic pending.Nothing to see.

Thank you for your advice. Maybe it will surprise you. But I’m learning a lot so far.I assure you that if the tool works, it’s because I understand it.If something I do not understand, usually it does not work.If you think the tool is a copy and paste of pieces, you are wrong. If I have specific doubts, I will continue to ask; with a little guidance, I get it working.Have you learned by a example?Sometimes a simple example is enough.For example, comment #7, just what was needed.

Just a reflection. Sometimes you can see the code you do not understand. When you verify that it works and you manipulate it, you understand it, and that code has not been programmed by you.

You can try to program things that you initially do not understand. You have learned them on the fly.

Thank you for the advice!It is a pleasure to learn from the experts.

Yeah, it’s good to also provoke oneself by trying out things that you don’t understand 100%. Then trial and error, to understand it a bit further. Then make your own implementation to solidify/verify your understanding. That’s why I try to help by giving examples rather than “the exact code”. (And it’s unavoidable that you later discover, looking back at old code, that you didn’t quite understand things the way you thought you did.)

On this topic… it would be cool if there was a short video tutorial about Renoise scripting. Some natural steps how a total programming no0b (me) would learn scripting. Chapters could be something like 1) variables, 2) scopes, 3) functions - passing and returning values, 4) tables and iteration, 5) observables, 6) preferences, 7) gui building, 8) classes.

Yeah, it’s good to also provoke oneself by trying out things that you don’t understand 100%. Then trial and error, to understand it a bit further. Then make your own implementation to solidify/verify your understanding. That’s why I try to help by giving examples rather than “the exact code”. (And it’s unavoidable that you later discover, looking back at old code, that you didn’t quite understand things the way you thought you did.)

Exact! Beyond the critics or the method of learning employed of any user, what a novice person values most is that people help him, in any field.Here I believe that two things happen,summarized in one sentence.You can know 100% of the lua code, but if you do not know the Renoise enabled API for scriping, you can not create a tool.This opens a field of lagoons.The example is very basic. Some lines of code required, is not available in the official documentation of Renoise. You can look at the forums or the code of the tools already built to find a solution.There are things that can be built, some not, and this creates doubts even the most expert person.Imagine for a newbie.

As long as we help each other, everything will work.

On the other hand, a recent reaction that made me laugh in the forum (you know there’s a lot of criticism for Renoise’s slow development).One user said: “we will learn all the lua code and we will create tools; and all done!” As if it were that easy.People want to write music, not write code.People who write code is by passion rather than by necessity.

That’s why there are a lot of “tools”, which basically are two buttons with two functions. No passion. Is not easy, and you need to invest time, time you do not use to compose music.Then a newbie enters the forum, and wants to create a tool, and even if he has the oficial documentation, he will have a lot of obstacles, Even some internal bug of Renoise, also,in addition to some criticism from other users.

On this topic… it would be cool if there was a short video tutorial about Renoise scripting. Some natural steps how a total programming no0b (me) would learn scripting. Chapters could be something like 1) variables, 2) scopes, 3) functions - passing and returning values, 4) tables and iteration, 5) observables, 6) preferences, 7) gui building, 8) classes.

This would be great, but who would?Who gets time for this?

To an extent, I can understand 4Tey… there are so many concepts that have taken me years to fully absorb. Patience you must have…

The way I see it, learning programming has two stages: first of all, learning to express ideas in code (in this case, lua). And secondly, learning how to apply it to something concrete - such as the Renoise API. In many ways, the first step is the most exciting as it enables you to_think_in code. The second is mostly a question of memorizing things. But essential of course, once you need to actually get something_done._

But of course, you don’t have to learn things in any specific order. It just helps to get some of the fundamentals right to begin with.

And while it would be nice with some learning resources, the idea of a Renoise scripting tutorial that cover "everything"´ - I think that’s too much ground to cover. I would simply focus on what makes the Renoise API_different_from vanilla lua. This would be cool, because you could learn to express yourself using the multitude of great tutorials that are already out there. And, once things start to settle, go deeper by studying each of the things that are specific to Renoise.

there are a lot of “tools”, which basically are two buttons with two functions

Well, some of my most essential tools have no buttons at all. Just a single keyboard shortcut or a menu entry.

Surely the quality of a tool is measured on it’s usefulness and not how many buttons it has :slight_smile:

But as the complexity of a tool grows, some of the things I mentioned (language fundamentals) becomes essential. Basically, you need to refactor, restructure things. And this is hard if things are assembled ad-hoc. Just maybe, the example I’m about to provide will be of use - it’s using classes, which I find are uniquely suited for building a large (and re-usable) codebase.

To an extent, I can understand 4Tey… there are so many concepts that have taken me years to fully absorb. Patience you must have…

I get the feeling that 4Teybothered a bit, because I did not explain myself well.I had my code at a point A.I asked to change something.I modified the code at a point B, following the signs of joule (I knew I was close to the solution).But something was still missing.I shared the tool at point B. 4Tey took the tool and modified it, returning to point A by chance.Then I told him that he had “stepped back”. :unsure:

My English is not perfect, and these are forums, all written.Any nonsense can be interpreted wrongly.Sometimes it is enough to put an icon for someone to take offense.

Well, some of my most essential tools have no buttons at all. Just a single keyboard shortcut or a menu entry.

Surely the quality of a tool is measured on it’s usefulness and not how many buttons it has

I mean there are many tools of this style, simple, without the need to invest much time in building them, because people are not for these things.You are just the opposite example :slight_smile:

But as the complexity of a tool grows, some of the things I mentioned (language fundamentals) becomes essential. Basically, you need to refactor, restructure things…

Right now I’m at this point, reshaping the code. But not by doing things wrong.I know I’m on the right track with the code, because it works perfectly when I fix it.

Following with the thread, I will put a history of what happens to me:

  1. Point A. Code with GUI (Viewbuilder) chopped in 11 parts, 1 main and 10 pieces (for tool modules) using “require” (10 requires).I want this structure to be able to manipulate the “tool modules” independently.
  2. Point B. Insert a “slider” (or several) that interacts correctly with Renoise.This step, forces me to include the GUI inside a function, destroying any viewbuilder invoked from require.
  3. Point C (actually). Problem to keep chunks of the GUI out of the function that wraps the main GUI, because Renoise interprets that there are several viewbuilders, the error (ViewBuilder: trying to add a view which already was added, probably into a different parent view).

A scheme:

Main.lua —>> general function that wraps the “main GUI” (apparently it is necessary to make the slider) —>> various requires (tools/tool_xx.lua) with “children GUI” (pieces of the GUI):

7134 scheme-pieces-gui-errors.png

Is it necessary for the entire GUI to be within the “general function”? Is there a way to separate it?

EDIT : Forget this!!! I have decided to do without the slider.Because of the slider, I can not split the GUI and because of this, each tool module does not preserve the window settings when opening and closing the main tool while it is being used when composing.I can build another window with sliders. But I wanted a single window for everything. It’s too complicated.In this way, I can keep the above scheme (without the general function).

EDIT : I am trying to include the Autostart checkbox in my tool.The checkbox is already working (saved correctly in the file preferences.xml).But I encounter this problem…

And other problem:https://forum.renoise.com/t/lua-dialog-behind-renoise-window-after-startup/41738

:ph34r:

This was bothering me for days.I thought it was due to something wrong in my code.but it’s not like that.

I have taken the Danoise demo tool as an example to apply a solution.

Use the line: "waiting_to_show_dialog = prefs.autostart.value"Following the clue in the code I come to this:

if self.waiting_to_show_dialog then
  renoise.tool().app_idle_observable:add_notifier(self,self.idle_notifier_waiting)
end

The code use “renoise.tool().app_idle_observable” to force the dialog up the window of Renoise.

I use the code to show the dialog:

--------------------------------------------------------------------------------
-- SHOW_DIALOG
--------------------------------------------------------------------------------
function show_dialog()
  if dialog and dialog.visible then dialog:show() return end -- Prevents duplicate of the floating window ( when reaching this, the dialog never was created before or was closed ) 
  dialog = renoise.app():show_custom_dialog ( ' '.. tool_name .. ' v' .. tool_version .. ' by: ulneiz' , content , keyhandler )
  renoise.app():show_status('GT16-Colors is charged... Enjoy the colors and control!')
end
renoise.tool().app_idle_observable:add_notifier(??????????????) <-------Is it possible to place the code (a function?) here to overlap the window of tool?

--autostart
renoise.tool().app_new_document_observable:add_notifier( function()
  if prefs.autostart.value then
    show_dialog()
  end   
end )

Renoise.tool (). App_idle_observable: add_notifier (???)

Is there any simple function to achieve this?

Yes, the tool example I provided is working because I’ve gone ahead and implemented the workaround in the vDialog itself.
(achieved by passing “waiting_to_show_dialog = true” when creating the instance)

For your code to work you will need to implement this yourself

  1. Make sure your tool receives notifications from app_idle_observable
  2. Add some variable that is set to true when your tool was supposed to display it’s UI
  3. Inside the idle loop, check if you tool was supposed to show - if so, show it and then reset the variable
    (or detach the idle loop completely if you’re really concerned about wasting CPU cycles).

Let’s just (because we’re sort-of dealing with vLib anyway) see how it’s done there:

The vDialog constructor has the following statement

if self.waiting_to_show_dialog then
    renoise.tool().app_idle_observable:add_notifier(self,self.idle_notifier_waiting)
  end

And the idle notifications are handled by this method:

function vDialog:idle_notifier_waiting()
  TRACE("vDialog:idle_notifier_waiting()")

  local idle_obs = renoise.tool().app_idle_observable
  local remove_notifier = false

  if self.waiting_to_show_dialog 
    and renoise.song() 
  then
    self.waiting_to_show_dialog = false
    self:show() 
    remove_notifier = true
  end  

  if remove_notifier and idle_obs:has_notifier(self,vDialog.idle_notifier_waiting) then
    idle_obs:remove_notifier(self,vDialog.idle_notifier_waiting)
  end

end

You don’t have to use classes, of course.

The “vDialog:” in front is what associates a function with a class. It’s then called a “method”

Same with “waiting_to_show_dialog”, the “self.” in front tells lua it is a property of the class.

Remove all references to “self”

if waiting_to_show_dialog then

renoise.tool().app_idle_observable:add_notifier(idle_notifier_waiting)

end

And declare the function like this instead:

function idle_notifier_waiting()

…etc

The important thing is how it’s all connected together

  • When creating a vDialog (constructor), and “waiting_to_show_dialog” is true, a method is attached to the idle observer
  • Now… the method is continously polling, waiting for renoise.song() to become available. This usually happens right away, within a few milliseconds.
  • Once the song is there, the dialog will be shown. Immediately, the notifier is removed, freeing a (tiny bit) of CPU

EDIT : Forget this!!! I have decided to do without the slider.Because of the slider, I can not split the GUI and because of this, each tool module does not preserve the window settings when opening and closing the main tool while it is being used when composing.I can build another window with sliders. But I wanted a single window for everything. It’s too complicated.In this way, I can keep the above scheme (without the general function).

So you have gone back to having your ‘content’ gui build table fully global (rather than defined in the function gt16_content), along with the viewbulder vb like how you originally programmed the tool? You see Raul if you take a moment to think about this you can’t have ‘content’ gui table local in a function with your vb object global. You’ll get an error (as you have found) when the user opens your tool subsequent times. As now ‘content’ is trying to always initialise the global vb when it executes the gt16_content function. If you move your vb into a function (and reduce scope) you would have to completely readjust most of your code that uses vb (which is a lot and hence why I didn’t do it in my example) and start passing vb around as a parameter in functions that require vb (which to be honest is how I would write it.)

Why do you want your tool to autostart anyway? Surely it would be fine just bound to a key shortcut? Save you the hassle with notifiers :slight_smile:

Also two other things I noticed Raul:

Your ‘includes’:

require ("tools/tool_01")

would probably need to be changed to:

require ("Tools/tool_01")

for it to work under Linux (and I suspect MacOS) as they are case sensitive operating systems.

And don’t forget about the key handler function, this:

function keyhandler( key )

would need to be changed to something like:

function keyhandler( dlg,key )

otherwise your key handler will throw errors.

Yes, the tool example I provided is working because I’ve gone ahead and implemented the workaround in the vDialog itself.
(achieved by passing “waiting_to_show_dialog = true” when creating the instance)

For your code to work you will need to implement this yourself

Let’s just (because we’re sort-of dealing with vLib anyway) see how it’s done there:

The vDialog constructor has the following statement

if self.waiting_to_show_dialog then
renoise.tool().app_idle_observable:add_notifier(self,self.idle_notifier_waiting)
end

And the idle notifications are handled by this method:

function vDialog:idle_notifier_waiting()
TRACE("vDialog:idle_notifier_waiting()")

local idle_obs = renoise.tool().app_idle_observable
local remove_notifier = false

if self.waiting_to_show_dialog 
and renoise.song() 
then
self.waiting_to_show_dialog = false
self:show() 
remove_notifier = true
end  

if remove_notifier and idle_obs:has_notifier(self,vDialog.idle_notifier_waiting) then
idle_obs:remove_notifier(self,vDialog.idle_notifier_waiting)
end

end

You don’t have to use classes, of course.

The “vDialog:” in front is what associates a function with a class. It’s then called a “method”

Same with “waiting_to_show_dialog”, the “self.” in front tells lua it is a property of the class.

Remove all references to “self”

if waiting_to_show_dialog then

renoise.tool().app_idle_observable:add_notifier(idle_notifier_waiting)

end

And declare the function like this instead:

function idle_notifier_waiting()

…etc

The important thing is how it’s all connected together

  • When creating a vDialog (constructor), and “waiting_to_show_dialog” is true, a method is attached to the idle observer
  • Now… the method is continously polling, waiting for renoise.song() to become available. This usually happens right away, within a few milliseconds.
  • Once the song is there, the dialog will be shown. Immediately, the notifier is removed, freeing a (tiny bit) of CPU

Thanks! Work 90% with this:

--------------------------------------------------------------------------------
-- SHOW_DIALOG
--------------------------------------------------------------------------------
function show_dialog()
  if dialog and dialog.visible then dialog:show() return end -- Prevents duplicate of the floating window ( when reaching this, the dialog never was created before or was closed ) 
  dialog = renoise.app():show_custom_dialog ( ' '.. tool_name .. ' v' .. tool_version .. ' by: ulneiz' , content , keyhandler )
  renoise.app():show_status('GT16-Colors is charged... Enjoy the colors and control!')
end

waiting_to_show_dialog = prefs.autostart.value

function idle_notifier_waiting()
  local idle_obs = renoise.tool().app_idle_observable
  local remove_notifier = false

  if waiting_to_show_dialog 
    and renoise.song() 
  then
    waiting_to_show_dialog = false
    show_dialog() 
    remove_notifier = true
  end  

  if remove_notifier and idle_obs:has_notifier( idle_notifier_waiting ) then
    idle_obs:remove_notifier( idle_notifier_waiting )
  end
end

if waiting_to_show_dialog then
  renoise.tool().app_idle_observable:add_notifier(idle_notifier_waiting)
end

renoise.tool().app_new_document_observable:add_notifier (
  function()
    if prefs.autostart.value then
      show_dialog()
    end   
  end
)

The tool window now appears correctly above Renoise.However, something seems to be missing. When you click on the Renoise window, the renoise window superimposes the tool window.I close and re-open the tool and this no longer happens, the tool always remains above.It seems that something is missing to force the window to always be superimposed… :slight_smile:

What is missing?

If this works at 100%, I will create a new thread explaining all the steps, so that it is available in a clear way…Danoise, I’ve only seen your tools with this feature. It seems that nobody knows how to build it

So you have gone back to having your ‘content’ gui build table fully global (rather than defined in the function gt16_content), along with the viewbulder vb like how you originally programmed the tool? You see Raul if you take a moment to think about this you can’t have ‘content’ gui table local in a function with your vb object global. You’ll get an error (as you have found) when the user opens your tool subsequent times. As now ‘content’ is trying to always initialise the global vb when it executes the gt16_content function. If you move your vb into a function (and reduce scope) you would have to completely readjust most of your code that uses vb (which is a lot and hence why I didn’t do it in my example) and start passing vb around as a parameter in functions that require vb (which to be honest is how I would write it.)

Why do you want your tool to autostart anyway? Surely it would be fine just bound to a key shortcut? Save you the hassle with notifiers :slight_smile:

Also two other things I noticed Raul:

Your ‘includes’:

require ("tools/tool_01")

would probably need to be changed to:

require ("Tools/tool_01")

for it to work under Linux (and I suspect MacOS) as they are case sensitive operating systems.

And don’t forget about the key handler function, this:

function keyhandler( key )

would need to be changed to something like:

function keyhandler( dlg,key )

otherwise your key handler will throw errors.

Thanks for the advice!I will use all folders in lowercase.I quit “dialog” or “dlg”, to disable the keys because it was changing the modules of site.

There really is no problem for using the GUI in a single file.The problem is not to modify the code or change things, the problem is me, that I want to have separate modules. Using sliders (or similar elements) does not allow you to split the GUI into different files. For them,is necessary to invoke a new window.

The tool already has 90% of autostart (missing a detail) and can already be invoked by keyboard command.

4Tey, are you building any tool now?

Am I building a tool? Nah, I find that joule/danoise/ledger/afta8 have pretty much covered all the bases Raul :wink:

Just as a side thought: With all the talent of people mentioned above I often wonder why joule/danoise/afta8 etc don’t collaborate on a tool. I often imagine that collaborative coding is a skill in itself to coordinate :slight_smile:

Just as a side thought: With all the talent of people mentioned above I often wonder why joule/danoise/afta8 etc don’t collaborate on a tool. I often imagine that collaborative coding is a skill in itself to coordinate :slight_smile:

True. I complained about this on one occasion.When I seriously started building my first serious tool, I wondered why there are no collaborations between different experts.Each one goes by one side.

I also wonder why Danoise has no responsibility within Renoise’s team to improve it. He could be adding things and even fixing bugs, while taktik is in another isolated world.He seems to make only tools, while Renoise is stuck.And being honest, the renoise forum is maintained because it’s Danoise. But this would be a disaster.

Joule is also making its own tool “Chord tracker”.I guess he works at short times, slowly, in installments.I do not see much afta8 activity lately.Certainly very few people are trying to do things with Lua API.

It is also true that it is complicated to collaborate. Each person is from a different country.On the other hand, how is it possible that there is no serious news of Taktik?Does no nobody know him closely and can filter something?It is a very antisocial philosophy. What problem is there in informing the forums?

One day he answered a user by telling him that he was working on something that had nothing to do with Renoise / Redux, and the people applauded him.The world upside down.

Anyway, LUA is fun. :clownstep:

Is there any particular idea that would benefit from a team of scripters atm?

Renoise 4.0

Is there any particular idea that would benefit from a team of scripters atm?

Yeps Joule, my MiniRoll program that isn’t even started and probably never finish :smiley:

But seriously what I mean is it isn’t the end result necessarily of the script (the script itself could be very simple), it is the process of writing a basic script and how people see algorithms and structure the solution to a particular problem :slight_smile:

I also wonder why Danoise has no responsibility within Renoise’s team to improve it. He could be adding things and even fixing bugs, while taktik is in another isolated world.He seems to make only tools, while Renoise is stuck.And being honest, the renoise forum is maintained because it’s Danoise. But this would be a disaster.

Joule is also making its own tool “Chord tracker”.I guess he works at short times, slowly, in installments.I do not see much afta8 activity lately.Certainly very few people are trying to do things with Lua API.

It is also true that it is complicated to collaborate. Each person is from a different country.On the other hand, how is it possible that there is no serious news of Taktik?Does no nobody know him closely and can filter something?It is a very antisocial philosophy. What problem is there in informing the forums?

I am involved - I already have been dabbling with some of the API, implementing a little feature here and there. So you could call me “one of the developers” :slight_smile:

But first and foremost, I see it as my job description to support people who have questions regarding the API. I get a lot of PMs with questions regarding XY and Z.

As for collaborations, I think we have that covered. It’s called the forum!

For example, the awesome CDP tool is the result of djeroek proposing it, and afta8 picking up the challenge :slight_smile:

Also, I’m happy to see some people pick up the cLib/vLib/xLib libraries, at least to extract a bit of code or get inspired in some way. I would call this a kind of collaboration too.

Anyone feeling like adding a few additional unit-tests? :badteeth:

@Danoise,

I can’t find a forum thread for cLib! Wanted to make a feature request (or two).

@Danoise,

I can’t find a forum thread for cLib! Wanted to make a feature request (or two).

OK, I’ll create a topic for it.

Edit: done

This thread is gone! :slight_smile:

@Danose. I believe that 4Tey means to collaborate as a team, approving a project and working together on the code, type the CDP tool.For example, create a miniroll like the one proposed by 4Tey.I’ve noticed, the more I know about the available API(not just the LUA code itself), is possible to create really impressive tools.Things that I thought were not possible before.

However, teamwork should be disinterested, as it is not perceived economically.I mean that in the team, some will work more than others, and this really should not matter. But the important thing is the end result: the tool.

But all this is complicated, precisely because each one has different knowledge, different levels.Collaborating or helping in the forum is like another topic.I, for my part, am very happy.I am solving a lot of things thanks to the help in the forums.I go forward, I do not get stuck.For any newbie, the worst thing that can happen is to get stuck, not to advance.If this happens, building the code can be a horror, resulting in abandonment of the project or a poorly constructed tool.

Danoise, returning to the thread, can you take a look at this? : comment #20I think it’s missing some detail to operate at 100% (the window tool does not always stay on top).Solving this, I would put this topic as solved.

The tool window now appears correctly above Renoise.However, something seems to be missing. When you click on the Renoise window, the renoise window superimposes the tool window.I close and re-open the tool and this no longer happens, the tool always remains above.It seems that something is missing to force the window to always be superimposed… :slight_smile:

What is missing?

You mean that the dialog is launched on startup, appears on top, but once you click Renoise it disappears?

Well, my guess is that it could’ve happened as a result of you having 2 “competing” methods for launching the window.

  1. First, you’re doing the idle notifier thing which will invoke “show_dialog”. And this really should be enough.
  2. But then you’re also listening for “new document”. This will also trigger “show_dialog”, and perhaps it happens a wee bit too soon?

And indeed, in the example tool I shared with you, I’m also listening for the new document.

The difference is that this will start the idle notifier and thus, only have one outcome.