Add normal button in a dialog that opens a dialog to select a folder
-
I need a button to open a dialog so the user can select a folder, and the button returns the path.
I know I can usec4d.CUSTOMGUI_FILENAME
but I don't want an edit text box, but just the button. A normal button.
I can add a button with thisself.AddButton(1000, c4d.BFH_SCALEFIT, initw=200, inith=20, name='Select Folder')
but I don't know how to select a directory on click.
According to the documentation, I can use the pluginid CUSTOMGUI_BUTTONAnd that is what I was trying, but it doesn't work:
bc = c4d.BaseContainer() bc[c4d.FILENAME_DIRECTORY] = True self.AddCustomGui(1000, c4d.CUSTOMGUI_BUTTON, name="Select Folder", flags=c4d.BFH_SCALEFIT, minw=200, minh=200, customdata=bc)
Is it possible to add a normal button on a gui dialog so that I can pick a folder from there?
-
Hello @danielsian,
Thank you for reaching out to us. I am not quite sure that I understand your question correctly, but:
- c4d.storage.LoadDialog opens the OS-native load-file dialog. With the flag
FILESELECT_DIRECTORY
you can make it so that the dialog behaves as directory selection dialog instead of a file selection dialog. - When you have added a button to a
GeDialog
, you would have to listen viaGeDialog.Command
for the button being clicked to add any logic to the event. The gedialog_modal_r13.py example demonstrates this, although it adds aAddDlgGroup
instead of aAddButton
, but the principle is the same. - You can technically also implement interactions directly via
GeDialog.Message
, listening forBFM_ACTION
but that is more of an advanced technique. - A
CUSTOMGUI_BUTTON
gadget is just another type of UI element. Interactions are implemented in the same way as for other gadgets via.Command
. Bitmap buttons have two bitmap states for their on/off state, can be tinted, and can also act as toggle buttons. They are the basis for the icons found in the palettes of Cinema 4D. - You can add a dedicated UI for selecting files or directories to a dialog with the data type
Filename
(which is represented asstr
in Python) and its associated GUICUSTOMGUI_FILENAME
. Find here and example.
Cheers,
Ferdinand - c4d.storage.LoadDialog opens the OS-native load-file dialog. With the flag
-
Thank you, @ferdinand, as always, very kind and helpful. You nailed it.
From your last example, when the button "Run" is pressed, the multiline edit text prints a list with the files from the given directory, and that is read-only.
Is there any way to have the same thing but with the ability to select some of the printed filenames from the list rather than only read them?I know this is probably another question not directly related to the main query, but I'm just taking advantage of the fact that you provided a very nice example that happens to be another problem I'm trying to solve.
I wonder if I could achieve what I've just described by using an InExcludeData list, with the files listed there? If so, could you suggest another example?
-
Hello,
@danielsian said in Add normal button in a dialog that opens a dialog to select a folder:
I wonder if I could achieve what I've just described by using an InExcludeData list, with the files listed there? If so, could you suggest another example?
I am not quite sure I understand how you mean that? An
InExcludeData
referencesGeListNode
instances, so you cannot drag files into it. Or how do you mean that? I know that we have some specialized UIs which list multiple files/and or directories, but they are (a) notInExcludeData
and its associated UI, and (b) also not part of the public API AFAIK. E.g., the plugin path field:On top of that, what you see here is not a dialog but a description, i.e., it is a whole other UI concept. If you want something like this, i.e., what is commonly known as a list box, you would have to implement it yourself for dialogs. Primarily because the cycle concept of Cinema 4D (which is closest to the concept of a list box) is always of type
long
. So, other than in theListBox
of Windows/WPF/WinForms, acycle
stores a selectedint
value and not a selected index (and whatever data you decided to store in theListBox
, usually astring
).When you want to have multiple file paths, I would simply add two buttons ("Add" and "Remove") and then dynamically rebuild the UI with the number of
Filename
UIs you need. I showed once here how to build a simple dynamic dialog UI.Cheers,
Ferdinand -
Thanks again for clarifying my question, @ferdinand
By reading your reply and watching the example you provided, I think a TreeView could be a good way to try.Instead of printing a list of filenames in a multiline edit text, it could instead feed a TreeView with the given folder being the parent and all files with subfolders as children, and so I could select the ones I need in order to perform another operation with those selected filenames.
Let me know please if this is something possible.
Cheers -
Hey @danielsian,
Yes, a tree view could be another solution, another one could be a
GeUserArea
. I deliberately did not mention both options since they are more complex. EspeciallyTreeViewFunctions
, the underlying interface for tree views, tends to be overwhelming for newcomers. I would recommend the dynamic UI workflow hinted at above, as this will result in the least amount of code. But it will of course not be as beautiful as something truly custom.Cheers,
Ferdinand