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

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.

@Raul, collaborating with other coders would be great in principle but for me making a tool has always been needs led so I think having a strong idea or concept that people can get behind would be a necessary trigger for this to happen… this was certainly what created the momentum behind the CDP tool.

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

Exact!

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.

This is beyond my comprehension: “The difference is that this will start the idle notifier and thus, only have one outcome”.

"and perhaps it happens a wee bit too soon?"It may be this.It’s like I loaded it before, not after.But I do not quite understand.

I have tried different combinations of code (with trial and error, to understand), but they all work the same or similar except one:causes a crash beast, which seems to be caused by an infinite loop perhaps?

The issue is that I can not always keep the window above, if I do not close it once, an reopen.It is a bit of a nuisance, which confuses the use of the tool.

I have tried different combinations of code (with trial and error, to understand)

As this whole “pop-under” issue comes down to timing, it’s crucial to delay things with an idle observer.

Did you try removing the new_document notifier? Like I said, the idle observer should be enough.

As this whole “pop-under” issue comes down to timing, it’s crucial to delay things with an idle observer.

Did you try removing the new_document notifier? Like I said, the idle observer should be enough.

Fuck, that’s right! ^^ ^^ ^^ ^^I did not realize I was repeating 2 times the same thing, the new_document notifier with “prefs.autostart.value”. Perfect!

I put this topic as solved! Thank you for this!