Cabbage Logo
Back to Cabbage Site

Save load path button

I have a question regarding file paths by filebutton.

In Live, I’m getting file paths as expected, on MacOS this is within plugins’ “Contents” folder. image

In Reaper, the file path is “correct” the first time I load the plugin, next time I open Reaper, the path changes to my drive, no longer pointing to the plugins’ “Contents”.

I’d like to have filebutton point (default path) to plugin’s contents folder.
Are there some Reaper settings or Cabbage use that I could tweak, or is it a bug?

Example (empty plugin + widgets):

filebutton bounds(178, 54, 60, 20) channel("IO_Browse") mode("file")  text("BROWSE", "BROWSE")
filebutton bounds(82, 54, 60, 20) channel("IO_SaveAs") mode("save")  text("SAVE AS", "SAVE AS")

Sorry, I’m away on holidays at the moment, but the populate identifier takes an optional parameter that sets the location to browse to each time the button is triggered. That any good?

I tried with populate(".txt", "./", 1) or 0. No change, I might be doing something wrong?
Enjoy your holiday!

When I do this:

filebutton bounds(178, 54, 60, 20) channel("IO_Browse") mode("file")  text("BROWSE", "BROWSE"), populate("*", ".", 1)
filebutton bounds(82, 54, 60, 20) channel("IO_SaveAs") mode("save")  text("SAVE AS", "SAVE AS"), populate("*", ".", 1)

Both file browser dialogues open at the same location every time :thinking:

Thanks for checking. Have you tried with a plugin in Reaper?
Could it be some Reaper setting that changes the path after the Reaper project is reloaded?

Given that this was the only host you reported having an issue with, it’s the only one I actually tested.

But hang on, are you talking about when a session is saved and then reopened? Sorry, I missed that point, I thought you simply meant when the plugin is reopened. Leave it with me. I think I have an idea about what’s happening…

Yes.

The problem was that the last file path was getting saved in the session data. I just triggered a new build with a fix for this. If you use populate() and set the ignoreLastDir flag to 1, the paths won’t be saved or recalled. I’ve tested it here and it seems to work fine. Again, I’m testing with this basic code:

filebutton bounds(178, 54, 60, 20) channel("IO_Browse") mode("file")  text("BROWSE", "BROWSE"), populate("*", ".", 1)
filebutton bounds(82, 54, 60, 20) channel("IO_SaveAs") mode("save")  text("SAVE AS", "SAVE AS"), populate("*", ".", 1)

Thanks! But strange, I tested with “#20210831.9 session saving now respects ignoreLastDir for filebuttons” with the same simple code as you and Reaper sessions still default to the root directory (as in screen-shots above) after I save, close and reopen the session.

I just tested that build here and it works fine? Or perhaps I’m missing something. Here’s how it works for me:

Are you seeing different behaviour?

If I follow your video it behaves the same here. But try quitting Reaper. When I reopen Reaper and load the session then I get the buggy behaviour. :thinking:

On it…

I think I have this fixed now. Reaper was changing the current directory. It should work now. Try it out and let me know.

Excellent, thank you! Your fix works. I have another little issue that seems related, but I won’t manage to provide an example at the moment.

I use a non-latched button as a trigger to load a file with a default name located in the plugin directory (next to the csd file). This file gets loaded correctly in Live but not in Reaper. I suppose a wrong file path gets registered there and consequently crashes the plugin in Reaper. I’ll try to provide an example, or perhaps this description already rings a bell?

How are you setting the default file? And are you using a filebutton or a regular button? An example would be simplest I think…

Sorry, I don’t manage to put together a simple example at the moment, but I’m using a non-latched normal button and then something like this, where SDefaultPresetName is set to “preset.txt”:

if trigger(cabbageGetValue:k("IO_Save"), .5, 0) == 1 then
    ftsavek SDefaultPresetName, k(1), 1, iTable
endif

Do you give it a path? If not then you are at the mercy of of the host as to what the current working directory is. You can use ‘CSD_PATH’ to get the path to the .csd file, and then create an absolute path form that :thinking:

I see. This is very useful info, thanks! I assumed it would auto set path to the directory containing scd. It seem Live somehow handles that. Is there some documentation on usage of “CSD_PATH” that you can point me to?

It’s just a reserved channel.

SPathToCsd chnget "CSD_PATH"

It might work fine in Live, until load another plugin that changes the current dir, thus breaking yours. That’s why it’s important to use absolute paths where you can. Most Cabbage widgets convert from relative to absolute, but if you working on the Csound side you will need to make sure you do the same.

I’ve been an actual user of my plugins for a few weeks and now I am back :slight_smile:

I can get the path mostly working, but there seems to be a bug with long paths, which causes a plugin crash. I don’t know whether this is due to Csound or Cabbage. Below is an example.
Please see the comment at the end of path (OK / not OK). The problem is related to
SFile strcpy SPathToCsd in connection with SFile cabbageGetValue "IO_SaveAs". If I don’t get the value, no problem. I hope this gives a clue what might be wrong or maybe I just need a different approach and perhaps not reuse the string?

Btw. Is there a more claver way of doing the commented block (which also causes crash when the csd has too long path)? Is there a way to detect the system file separator ("/", “”)?

<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue"), pluginId("def1")
filebutton bounds(10, 10, 70, 20) channel("IO_SaveAs") mode("save")  text("SAVE AS", "SAVE AS") ; corners(3) colour:0(200, 80, 0, 180) colour:1(255, 255, 0, 255) fontColour:0(255, 255, 0, 255) fontColour:1(160, 0, 0, 255)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
ksmps = 32

instr 1

/*
SPathToCsd chnget "CSD_PATH"
if chnget:i("WINDOWS") == 1 then
    SPathToCsd strcat SPathToCsd, "\preset.txt"
else
    SPathToCsd strcat SPathToCsd, "/preset.txt"
endif
*/

;SPathToCsd strcpy "/Users/Samo/Documents/test/0001/0002/0003/0004/0005/0006/0007/0008/0009/0010/0011/0012/0013/0014/0015/0016/0017/0018/0019/preset.txt"; not OK
SPathToCsd strcpy "/Users/Samo/Documents/test/0001/0002/0003/0004/0005/0006/0007/0008/0009/0010/0011/0012/0013/0014/0015/0016/0017/0018/preset.txt"; OK
SFile cabbageGetValue "IO_SaveAs"

SFile strcpy SPathToCsd
kFileValid init filevalid(SPathToCsd)

;printk 1, kFileValid
prints SPathToCsd, 1
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i 1 0 -1;[60*60*24*7]
</CsScore>
</CsoundSynthesizer>