[Solved] Problem with "ViewBuilder" divided into two or more .

Please, help!!!

I need to divide the building code for " ViewBuilder" in two or more files, using " require" (or “module”?).

Currently I have this error, that appears after close and reopen the tool (floating window),for the second time:

The error:

'C:\Users\PC\AppData\Roaming\Renoise\V3.1.0\Scripts\Tools\XXX.YYY.v3.xrnx\' failed to execute in one of its menu entry functions.

Please contact the author (ulneiz) for assistance...

std::logic_error: 'ViewBuilder: trying to add a view which already was added, probably into a different parent view.'
stack traceback:
  [C]: in function '?'
  main.lua:3196: in function <main.lua:1688>

…this error appears with the Terminal closed.

In main.lua I have:

main.lua:

bla bla bla
...

require ("tools/tool_01")

...
bla bla bla
...

function show_dialog()

  vb = renoise.ViewBuilder()

  ...
  bla bla bla
  ...

 -- CONTENT FLOATING WINDOW --

  local content = vb:column {
  width = 660,  
  margin = 5,
 --menu-------------------------------------
  vb:horizontal_aligner { height = 5 },
  vb:column {
   style = 'group', --body
   margin = 10,
   vb:horizontal_aligner {
    mode = 'right',
    vb:column {
     vb:horizontal_aligner {
     margin = 5,
     vb:text {
      font = 'bold', --> normal, big, bold, italic, mono
      text = '1.- Select a Principal Option :'
     },   
    },
   },
  ...
  bla bla bla
  ...

},-------------------------------01
vb:column {
 visible = false,
   id = 'tlstab_03',
 style = 'body',
 width = 702,
 height = '100%',
 margin = 10,
   groups_control, --Add "tool_01" <---------LOOK HERE!----
}, 

  ...
  bla bla bla
  ...

This " groups_control" is another large piece of various " vb:"charged through of “require (“tools/tool_01”)”.

I have another " tool_01.lua" inside the folder “tools” with the following code:

tool_01.lua:

...
bla bla bla
...

--------------------------------------------------------------------------------
-- GUI TOOL 01
--------------------------------------------------------------------------------
vb = renoise.ViewBuilder()

groups_control = <---------LOOK HERE!----
vb:column {
 vb:horizontal_aligner {
  mode = 'center',
  vb:text { font = 'bold', text = 'GRC: Groups Control' },
  vb:text { font = 'normal', text = ' v1.0 ...Tool 03' },
 },
 vb:horizontal_aligner { height = 10 },
 ----
 vb:horizontal_aligner {
  mode = 'justify',
  vb:column { -- 01 right column
   vb:vertical_aligner {
    vb:horizontal_aligner {
         width = 108,
     vb:button {
          ...
          bla bla bla
          ...

When I close the floating window of the tool for the first time, it seems stored information in memory, and then reload does not allow the same floating window. It seems as if charged 2 times the same.

I also use this code to prevent open multiple floating windows of the same tool, but does not solve this error:

Code of “Prevent multiple floating windows”:

if dialog and dialog.visible then dialog:show() return end

Is it possible to avoid this error?I need to have the code of ViewBuilder in various files , because it is very long…

Danoise, Dblue…Any idea what’s going on here and how fix it???

Thanks!!!

Hi Raul,

you can split your code into as many files as you like, in itself this does not a cause problem like the one you describe.

Instead, it is probably a matter of asking the Viewbuilder API to create a view for an element which it has already created.

For example, when you want to display a dialog for the second time you shouldn’t need to build it again.

More specially, the error occurs when you assign an ID to a viewbuilder element which is already in use. Perhaps double-check if the names you have assigned are truly unique?

Hi Raul,

you can split your code into as many files as you like, in itself this does not a cause problem like the one you describe.

Instead, it is probably a matter of asking the Viewbuilder API to create a view for an element which it has already created.

For example, when you want to display a dialog for the second time you shouldn’t need to build it again.

More specially, the error occurs when you assign an ID to a viewbuilder element which is already in use. Perhaps double-check if the names you have assigned are truly unique?

Danoise, thank you very much for the help!

I suspected about ids,but it seems weird because I used new names per “id”. I’ll check exhaustively.Then I comment if it is resolved…


I have more questions:

  1. How to create keyboard command to return to the tool floating window, from Renoise (control everything from the keyboard).
  2. How to create keyboard command to invoke the tool floating window (related to the above).
  3. How to paint a specific color text as the title of the tool floating window, or specific color.
  4. A code to jump between groups, using two buttons, forward, backward.

I’m about to finish a very big tool, related colors and overall control of tracks and groups, and aditional extras…But I need to solve these final details.

It would be nice to receive a little help…

If you’re using unique names, then it’s probably because you’re recreating an already visible view.

if dialog and dialog.visible then dialog:show() return end

While this might seem sufficient, you probably need to take it a step further and check for the existence of the dialog content as well.

if not dialog or not dialog.visible then
  -- create, or re-create if hidden
  if not dialog_content then 
    dialog_content = create_dialog() -- some function that returns a viewbuilder View
  end
  dialog = renoise.app():show_custom_dialog(
    dialog_title, dialog_content,dialog_keyhandler)
else 
  -- bring existing/visible dialog to front
  dialog:show()
end

This is the approach I’m using for my own Viewbuilder library, vLib.

I have more questions:

  1. How to create keyboard command to return to the tool floating window, from Renoise (control everything from the keyboard).
  2. How to create keyboard command to invoke the tool floating window (related to the above).
  3. How to paint a specific color text as the title of the tool floating window, or specific color.
  4. A code to jump between groups, using two buttons, forward, backward.

1+2. The dialog keyhandler does, as the name suggests, only provide shortcuts for the dialog, and only while the dialog has focus. For ‘normal’ keybindings, seehttps://github.com/renoise/xrnx/blob/master/Documentation/Renoise.ScriptingTool.API.lua#L119 (or for real-life examples, basically any tool which exposes some keybindings)

  1. You can’t change the style of a dialog title :frowning:

  2. Do you mean groups in the pattern editor? It’s not too hard, check forrenoise.Track.TRACK_TYPE_GROUPwhen iterating through tracks

Thanks for the additional information…

I checked and revised the IDs and all are different, both in “main.lua” like in my archive in folder “\tools\tool_01.lua”.It seems a different problem. It may be related to what you says.I have tried to enter the following code:

While this might seem sufficient, you probably need to take it a step further and check for the existence of the dialog content as well.

if not dialog or not dialog.visible then
-- create, or re-create if hidden
if not dialog_content then 
dialog_content = create_dialog() -- some function that returns a viewbuilder View
end
dialog = renoise.app():show_custom_dialog(
dialog_title, dialog_content,dialog_keyhandler)
else 
-- bring existing/visible dialog to front
dialog:show()
end

But it gives me error.I have my code as:

function show_dialog()

 -- Prevents duplicate of the floating window ( when reaching this, the dialog never was created before or was closed )
 
  if dialog and dialog.visible then dialog:show() return end

 ---------------------------------------------------------------
  if not dialog or not dialog.visible then
   -- create, or re-create if hidden
   if not dialog_content then
    dialog_content = create_dialog() -- some function that returns a viewbuilder View
   end
   dialog = renoise.app():show_custom_dialog(
    dialog_title, dialog_content,dialog_keyhandler)
  else
   -- bring existing/visible dialog to front
   dialog:show()
  end
 ---------------------------------------------------------------

 vb = renoise.ViewBuilder()

  ...
  bla bla bla
  ...

 -- CONTENT FLOATING WINDOW ---------------------
 local content = vb:column {
  --style = 'panel',
  width = 660,  
  margin = 5,
   --menu
  vb:horizontal_aligner { height = 5 },
  vb:column {

    ...
    bla bla bla
    ...
    
    }

  dialog = renoise.app():show_custom_dialog ( ' '.. tool_name .. ' v' .. tool_version , content , keyhandler )

end -- function show_dialog()

-- Reload the script whenever this file is saved. Additionally, execute the attached function.
_AUTO_RELOAD_DEBUG = function() show_dialog() end

-- MENU ENTRIES ---------------------

renoise.tool():add_menu_entry {
 name = 'Main Menu:Tools:'..tool_name..'...',
 invoke = show_dialog 
}

renoise.tool():add_menu_entry {
 name = 'Pattern Editor:'..tool_name..'...',
 invoke = show_dialog
}

-- KEY BINDING ---------------------

renoise.tool():add_keybinding {
 name = 'Global:Tools:' ..tool_name..'...',
 invoke = show_dialog
}

Return error here : dialog_content = create_dialog()

create_dialog() ???

I can not find the solution to fix. It is a very annoying error!

create_dialog() ???

This was just pseudocode - not intended for copy-paste. You need to supply your own function there :slight_smile:

if not dialog or not dialog.visible

This is not enough, the only way you can reliably detect that a previously shown dialog has been closed is by checking for the existence of the content. This is also why you need to keep a reference to dialog_content

Read my post again - the whole logic for your show_dialog function is contained in that little snippet, the rest are implementation details. Try organizing your code around that?

This was just pseudocode - not intended for copy-paste. You need to supply your own function there :slight_smile:

Of course. I tried to modify the code and adjust. But I can not.

Do you have any downloadable toolthat uses this code to take as an example and study?xCleaner or other?

Do you have any downloadable toolthat uses this code to take as an example and study?xCleaner or other?

Better still, your example code, slightly modified. Check how the logic is based on the code I shared with you.

-- variables...

local dialog = nil
local dialog_content = nil
local dialog_title = "Hello World"
local dialog_keyhandler = function()
  -- your keyhandler code... 
end
local vb = renoise.ViewBuilder()

-----------------------------------------------------------

function create_dialog()
  return vb:column {
    -- your dialog content
  }
end

-----------------------------------------------------------

function show_dialog()
  if not dialog or not dialog.visible then
    -- create, or re-create if hidden
    if not dialog_content then 
      dialog_content = create_dialog() -- run only once
    end
    dialog = renoise.app():show_custom_dialog(
      dialog_title, dialog_content,dialog_keyhandler)
  else
    -- bring existing/visible dialog to front
    dialog:show()
  end
end

A function exist to force reload this tool before start???

I’m fighting with this error. It seems absurd that extract some of the code of ViewBuilder in another xxx.lua, generate a error.

Can not be cut into pieces the “vb” unless “patch code” is added…

If I press " Reload all tools", the tool works perfectly, the first time.If I close the tool, you should close completely.The second time and subsequent fails.

I’m reordering the code, to see if I can solve this error.But I’m getting other errors in the process. :unsure:

Incredible!! I just fix, simply reordering the code!!! ^^ ^^ :slight_smile:

I was playing with more than 3000 lines, optimizing and improving the code.

Danoise, thank you very much for the great help!!!

Now it works fine. This is beginning to be serious :dribble: