VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_gui_basics / filebrowser / juce_FileChooserDialogBox.cpp
blob814c73ad3a98d35fc6b9d561b29b842120be385b
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
23 ==============================================================================
26 namespace juce
29 class FileChooserDialogBox::ContentComponent : public Component
31 public:
32 ContentComponent (const String& name, const String& desc, FileBrowserComponent& chooser)
33 : Component (name),
34 chooserComponent (chooser),
35 okButton (chooser.getActionVerb()),
36 cancelButton (TRANS ("Cancel")),
37 newFolderButton (TRANS ("New Folder")),
38 instructions (desc)
40 addAndMakeVisible (chooserComponent);
42 addAndMakeVisible (okButton);
43 okButton.addShortcut (KeyPress (KeyPress::returnKey));
45 addAndMakeVisible (cancelButton);
46 cancelButton.addShortcut (KeyPress (KeyPress::escapeKey));
48 addChildComponent (newFolderButton);
50 setInterceptsMouseClicks (false, true);
53 void paint (Graphics& g) override
55 text.draw (g, getLocalBounds().reduced (6)
56 .removeFromTop ((int) text.getHeight()).toFloat());
59 void resized() override
61 const int buttonHeight = 26;
63 auto area = getLocalBounds();
65 text.createLayout (getLookAndFeel().createFileChooserHeaderText (getName(), instructions),
66 (float) getWidth() - 12.0f);
68 area.removeFromTop (roundToInt (text.getHeight()) + 10);
70 chooserComponent.setBounds (area.removeFromTop (area.getHeight() - buttonHeight - 20));
71 auto buttonArea = area.reduced (16, 10);
73 okButton.changeWidthToFitText (buttonHeight);
74 okButton.setBounds (buttonArea.removeFromRight (okButton.getWidth() + 16));
76 buttonArea.removeFromRight (16);
78 cancelButton.changeWidthToFitText (buttonHeight);
79 cancelButton.setBounds (buttonArea.removeFromRight (cancelButton.getWidth()));
81 newFolderButton.changeWidthToFitText (buttonHeight);
82 newFolderButton.setBounds (buttonArea.removeFromLeft (newFolderButton.getWidth()));
85 FileBrowserComponent& chooserComponent;
86 TextButton okButton, cancelButton, newFolderButton;
87 String instructions;
88 TextLayout text;
91 //==============================================================================
92 FileChooserDialogBox::FileChooserDialogBox (const String& name,
93 const String& instructions,
94 FileBrowserComponent& chooserComponent,
95 bool shouldWarn,
96 Colour backgroundColour,
97 Component* parentComp)
98 : ResizableWindow (name, backgroundColour, parentComp == nullptr),
99 warnAboutOverwritingExistingFiles (shouldWarn)
101 content = new ContentComponent (name, instructions, chooserComponent);
102 setContentOwned (content, false);
104 setResizable (true, true);
105 setResizeLimits (300, 300, 1200, 1000);
107 content->okButton.onClick = [this] { okButtonPressed(); };
108 content->cancelButton.onClick = [this] { closeButtonPressed(); };
109 content->newFolderButton.onClick = [this] { createNewFolder(); };
111 content->chooserComponent.addListener (this);
113 FileChooserDialogBox::selectionChanged();
115 if (parentComp != nullptr)
116 parentComp->addAndMakeVisible (this);
117 else
118 setAlwaysOnTop (juce_areThereAnyAlwaysOnTopWindows());
121 FileChooserDialogBox::~FileChooserDialogBox()
123 content->chooserComponent.removeListener (this);
126 //==============================================================================
127 #if JUCE_MODAL_LOOPS_PERMITTED
128 bool FileChooserDialogBox::show (int w, int h)
130 return showAt (-1, -1, w, h);
133 bool FileChooserDialogBox::showAt (int x, int y, int w, int h)
135 if (w <= 0) w = getDefaultWidth();
136 if (h <= 0) h = 500;
138 if (x < 0 || y < 0)
139 centreWithSize (w, h);
140 else
141 setBounds (x, y, w, h);
143 const bool ok = (runModalLoop() != 0);
144 setVisible (false);
145 return ok;
147 #endif
149 void FileChooserDialogBox::centreWithDefaultSize (Component* componentToCentreAround)
151 centreAroundComponent (componentToCentreAround, getDefaultWidth(), 500);
154 int FileChooserDialogBox::getDefaultWidth() const
156 if (auto* previewComp = content->chooserComponent.getPreviewComponent())
157 return 400 + previewComp->getWidth();
159 return 600;
162 //==============================================================================
163 void FileChooserDialogBox::closeButtonPressed()
165 setVisible (false);
168 void FileChooserDialogBox::selectionChanged()
170 content->okButton.setEnabled (content->chooserComponent.currentFileIsValid());
172 content->newFolderButton.setVisible (content->chooserComponent.isSaveMode()
173 && content->chooserComponent.getRoot().isDirectory());
176 void FileChooserDialogBox::fileDoubleClicked (const File&)
178 selectionChanged();
179 content->okButton.triggerClick();
182 void FileChooserDialogBox::fileClicked (const File&, const MouseEvent&) {}
183 void FileChooserDialogBox::browserRootChanged (const File&) {}
185 void FileChooserDialogBox::okToOverwriteFileCallback (int result, FileChooserDialogBox* box)
187 if (result != 0 && box != nullptr)
188 box->exitModalState (1);
191 void FileChooserDialogBox::okButtonPressed()
193 if (warnAboutOverwritingExistingFiles
194 && content->chooserComponent.isSaveMode()
195 && content->chooserComponent.getSelectedFile(0).exists())
197 AlertWindow::showOkCancelBox (MessageBoxIconType::WarningIcon,
198 TRANS("File already exists"),
199 TRANS("There's already a file called: FLNM")
200 .replace ("FLNM", content->chooserComponent.getSelectedFile(0).getFullPathName())
201 + "\n\n"
202 + TRANS("Are you sure you want to overwrite it?"),
203 TRANS("Overwrite"),
204 TRANS("Cancel"),
205 this,
206 ModalCallbackFunction::forComponent (okToOverwriteFileCallback, this));
208 else
210 exitModalState (1);
214 void FileChooserDialogBox::createNewFolderCallback (int result, FileChooserDialogBox* box,
215 Component::SafePointer<AlertWindow> alert)
217 if (result != 0 && alert != nullptr && box != nullptr)
219 alert->setVisible (false);
220 box->createNewFolderConfirmed (alert->getTextEditorContents ("Folder Name"));
224 void FileChooserDialogBox::createNewFolder()
226 auto parent = content->chooserComponent.getRoot();
228 if (parent.isDirectory())
230 auto* aw = new AlertWindow (TRANS("New Folder"),
231 TRANS("Please enter the name for the folder"),
232 MessageBoxIconType::NoIcon, this);
234 aw->addTextEditor ("Folder Name", String(), String(), false);
235 aw->addButton (TRANS("Create Folder"), 1, KeyPress (KeyPress::returnKey));
236 aw->addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey));
238 aw->enterModalState (true,
239 ModalCallbackFunction::forComponent (createNewFolderCallback, this,
240 Component::SafePointer<AlertWindow> (aw)),
241 true);
245 void FileChooserDialogBox::createNewFolderConfirmed (const String& nameFromDialog)
247 auto name = File::createLegalFileName (nameFromDialog);
249 if (! name.isEmpty())
251 auto parent = content->chooserComponent.getRoot();
253 if (! parent.getChildFile (name).createDirectory())
254 AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
255 TRANS ("New Folder"),
256 TRANS ("Couldn't create the folder!"));
258 content->chooserComponent.refresh();
262 } // namespace juce