[SOLVED] LUA Crash with GUI buttons

this seems to cause a crash:

    local action_buttons = vb:horizontal_aligner {
        mode = "distribute",
        width = "100%",
        vb:button {
            text = "Load Device(s)",
            width = "40%",
            notifier = function()
                loadSelectedNativeDevices()
            end
        },
        vb:button {
            text = "Load Device(s) & Close",
            width = "60%",
            notifier = function()
                loadSelectedNativeDevices()
                if custom_dialog and custom_dialog.visible then
                    custom_dialog:close()
                end
            end
        },
        vb:button {
            text = "Cancel",
            width = "100%",
            notifier = function()
                if custom_dialog and custom_dialog.visible then
                    custom_dialog:close()
                end
            end
        }
    }

am using macOS Sonoma 14.4.1 and Renoise 3.4.3 (?) on Apple Silicon.

I’ve tried adding this into a custom dialog:

 renoise.app():show_custom_dialog("qwe", action_buttons)

But this doesn’t crash here. Do you’ve got a full tool as example where this is crashing?

1 Like

hi. this, when run from the menu entry, seems to crash. hope this helps @taktik

local function show_plugin_list_dialog()
    local vb = renoise.ViewBuilder()
    local checkboxes = {}

    -- Fetch native device information and sort it
    local track_index = renoise.song().selected_track_index
    local available_devices = renoise.song().tracks[track_index].available_devices
    local deviceReadableNames = {}
    for i, device_path in ipairs(available_devices) do
        if device_path:find("Native/") then
            local device_name = device_path:match("([^/]+)$")
            table.insert(deviceReadableNames, {name = device_name, path = device_path})
        end
    end

    -- Sort devices alphabetically by name
    table.sort(deviceReadableNames, function(a, b) return a.name < b.name end)

    -- Function to create the device list UI component, split into two columns
    local function create_scrollable_native_list()
        local left_column = vb:column {}
        local right_column = vb:column {}
        local num_devices = #deviceReadableNames
        local mid_point = math.ceil(num_devices / 2)

        for i, device in ipairs(deviceReadableNames) do
            local checkbox = vb:checkbox { value = false, id = "checkbox_native_" .. tostring(i) }
            checkboxes[#checkboxes + 1] = { checkbox = checkbox, path = device.path, name = device.name }
            local device_row = vb:row {
                checkbox,
                vb:text { text = device.name }
            }

            -- Distribute devices between the two columns
            if i <= mid_point then
                left_column:add_child(device_row)
            else
                right_column:add_child(device_row)
            end
        end

        return vb:horizontal_aligner {
            mode = "left",
            spacing = 10,
            left_column,
            right_column
        }
    end

    local custom_dialog -- Declare the dialog variable for later reference

    -- Function to handle loading the selected Native device
    local function loadSelectedNativeDevice()
        for _, cb_info in ipairs(checkboxes) do
            if cb_info.checkbox.value then
                local pluginPath = cb_info.path
                print("Loading Native Device:", pluginPath)
                loadnative(pluginPath) -- Use the actual function to load the device
                break
            end
        end
    end

    -- Define the action buttons and their behaviors
    local action_buttons = vb:horizontal_aligner {
        mode = "distribute",
        spacing = 10,
        vb:button {
            text = "Load Plugin",
            width = "100%",
            notifier = function()
                loadSelectedNativeDevice()
            end
        },
        vb:button {
            text = "Load Plugin & Close",
            width = "100%",
            notifier = function()
                loadSelectedNativeDevice()
                custom_dialog:close()
            end
        },
        vb:button {
            text = "Cancel",
            width = "100%",
            notifier = function()
                custom_dialog:close()
            end
        }
    }

    -- Prepare the dialog content
    local dialog_content = vb:column {
        margin = 10,
        spacing = 10,
        create_scrollable_native_list(),
        action_buttons
    }

    -- Show the dialog
    custom_dialog = renoise.app():show_custom_dialog("Load Native Device", dialog_content)
end

-- Add the menu entry to invoke the dialog
renoise.tool():add_menu_entry {
    name = "Main Menu:Tools:Paketti..:Show Native Devices",
    invoke = show_plugin_list_dialog
}

Thanks. I can replicate this now. This creates a dialog which is huge, which then causes some error in the OS.

I’ll fix that, so that a proper error is shown instead of crashing down.

The problem in the layout is the “action bar”: It uses a horizontal_aligner with 3 buttons where each button has a width of 100. 100 here means the horizontal_aligner’s width. So it’s growing endlessly. This actually also should have resulted into a error.

You can fix this by using a width of 100/3 percent for each button instead.

    -- Define the action buttons and their behaviors
    local button_width = (100/3).."%"
    local action_buttons = vb:horizontal_aligner {
        mode = "distribute",
        spacing = 10,
        vb:button {
            text = "Load Plugin",
            width = button_width,
            notifier = function()
                loadSelectedNativeDevice()
            end
        },
        vb:button {
            text = "Load Plugin & Close",
            width = button_width,
            notifier = function()
                loadSelectedNativeDevice()
                custom_dialog:close()
            end
        },
        vb:button {
            text = "Cancel",
            width = button_width,
            notifier = function()
                custom_dialog:close()
            end
        }
    }
1 Like

thanks @taktik ! unfortunately after the crash, i have ended up modifying the buttons, so what i was hoping to do was something like this:

[Load Device(s)] [Load Device(s) & Close]
[            Add as Shortcut            ]
[                  Cancel               ]

but I was not really able to figure it out, and chatgpt wasn’t able to help me either, unfortunately. (in fact, it concocted the crashy gui which i congratulated it for :slight_smile: )

This should do it:

    -- Define the action buttons and their behaviors
    local button_height = renoise.ViewBuilder.DEFAULT_DIALOG_BUTTON_HEIGHT
    local button_spacing = renoise.ViewBuilder.DEFAULT_DIALOG_SPACING
    local action_buttons = vb:column {
      uniform = true,
      width = "100%",
      vb:horizontal_aligner {
        vb:button {
            text = "Load Plugin",
            width = "50%",
            height = button_height,
            notifier = function()
                loadSelectedNativeDevice()
            end
        },
        vb:button {
            text = "Load Plugin & Close",
            width = "50%",
            height = button_height,
            notifier = function()
                loadSelectedNativeDevice()
                custom_dialog:close()
            end
        } 
      },
      vb:button {
          text = "Add as Shortcut",
          height = button_height,
          notifier = function()
              -- TODO
          end
      },
      vb:space{
         height = button_spacing,
      },
      vb:button {
          text = "Cancel",
          height = button_height,
          notifier = function()
              custom_dialog:close()
          end
      }
    }
2 Likes

fantastic! thanks!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.