Cabbage Logo
Back to Cabbage Site

Triggering events (save/load) with filebutton in "save" and "file" modes

I’m trying to select a file name and save or load files on a single filebutton push - one button to save and one to load a file. Like the standard “Save As” or “Open” buttons.

I can use filebutton mode("save")... to select or type in a file name for saving and filebutton mode("file")... to select a file for loading. Then I can use chnget and changed or changed2 to trigger saving or loading events when the file names have changed. So this works fine when I try so save or load a file with a different name from the previous. But this method doesn’t work if I try to re-load or overwrite a file with the same name as previously obtained by chnget.

Of course, filebutton sends a string to the associated channel and not a 0/1 state as a button does, so just pushing filebutton can’t be used as a trigger. I though maybe a way around could be to change the file property of filebutton to some never used or empty string after changed has been triggered. That way changed would be ready to re-trigger when a “new name” is set.

However, it seems that I cannot do this:
chnset "file(\"any_name\")", "identchannel_name",
identchannel("identchannel_name") is used with filebutton mode("file")... or filebutton mode("save")...

In summary I have two questions:
(1) is there a way to use a single button to trigger loading/reloading OR saving/overwriting files
(2) is there a bug preventing to set file property of filebutton or am I doing something wrong?

I hope this description can be understood and I’ll be grateful for any ideas and lessons :slightly_smiling_face:

Cabbage: 2.3.38 on MacOS 10.12.6

I think I follow the problem here. Can you prepare a simple csd file just to make sure I get the problem? Thanks.

Thanks Rory!

I hope this will be sufficient to illustrate what I am doing:

form caption("Untitled") size(400, 300), colour(0, 0, 0), pluginid("def1")
filebutton bounds(30, 44, 60, 30) channel("IO_SaveAs")  identchannel("ID_SaveAs") mode("save")  text("SAVE AS", "SAVE AS") file("preset_test_save_load.txt") colour:0(140, 200, 30, 255) colour:1(255, 255, 0, 255)  corners(3) fontcolour:0(160, 0, 0, 255)
filebutton bounds(30, 82, 60, 30)  channel("IO_Browse") identchannel("ID_Browse") mode("file")  text("BROWSE", "BROWSE") file("preset_test_save_load.txt")  colour:0(100, 0, 0, 255) colour:1(255, 255, 0, 255)   fontcolour:1(160, 0, 0, 255) corners(3) fontcolour:1(160, 0, 0, 255) 
-n -d -m0d -+rtmidi=NULL

ksmps = 32
nchnls = 2
0dbfs = 1

instr 1

gS_SaveFileName chnget "IO_SaveAs" 
gS_LoadFileName chnget "IO_Browse" 

;printks gS_SaveFileName, 2
;printks gS_LoadFileName, 2

if changed2(gS_SaveFileName) == 1 then
    ;event	"i", "SaveAll", 0, 0 ; saving event
    ;printks "save name changed",0
    chnset "file(\"blank\")", "ID_SaveAs"

if changed2(gS_LoadFileName) == 1 then
   ; event	"i", "LoadAll", 0, 0 ; loading event 
   ;printks "load name changed",0
   chnset "file(\"blank\")", "ID_Browse"


;causes Csound to run for about 7000 years...
f0 z
;starts instrument 1 and runs it for a week
i 1 0 -1;[60*60*24*7] 

Yeah, this is more or less what I understood from your original post. It’s tricky one. I’ve updated the filebutton widget so that you can now set the file() using an ident channel, although I feel we are just kicking the can down the street!

You should probably use the filevalid opcode to check that the file is valid considering you will be passing bogus file names to the channel.

A new version is currently building. You can check it out here when it’s done:

:+1: Let me know.

Fantastic! I really appreciate your super fast responses!

There probably could be a more elegant solution to my saving/loading needs, perhaps based on some claver widget internals…
But for now I am happy with how the method with setting file names works for me :slightly_smiling_face:

Thanks also for the tip about using filevalid, but in my situation I prefer checking if the file is of correct type and this method gives me some opportunity to filter files:

filebutton channel("IO_SaveAs") identchannel("ID_SaveAs") mode("save")...

gS_SaveFileName chnget "IO_SaveAs" 
if changed(gS_SaveFileName) == 1 && strindexk(gS_SaveFileName, ".txt") > 0 then
        event	"i", "SaveAll", 0, 0     
        chnset "file(\"\")", "ID_SaveAs"

With this, the event is triggered only when I set a meaningful file name, i.e. *.txt in my case.

Best wishes,

This turns a rather ugly solution into an eloquent one :wink: I think this makes it pretty useable.