| @@ -57,7 +57,7 @@ public: | |||||
| area.removeFromTop (10); | area.removeFromTop (10); | ||||
| area.reduce (5, 5); | area.reduce (5, 5); | ||||
| Rectangle<int> topArea (area.removeFromTop (34)); | |||||
| auto topArea = area.removeFromTop (34); | |||||
| topArea.removeFromLeft (110); | topArea.removeFromLeft (110); | ||||
| bitSize.setBounds (topArea.removeFromLeft (topArea.getWidth() / 2).reduced (5)); | bitSize.setBounds (topArea.removeFromLeft (topArea.getWidth() / 2).reduced (5)); | ||||
| generateRSAButton.setBounds (topArea.reduced (5)); | generateRSAButton.setBounds (topArea.reduced (5)); | ||||
| @@ -123,8 +123,7 @@ private: | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| class HashesComponent : public Component, | |||||
| private TextEditor::Listener | |||||
| class HashesComponent : public Component | |||||
| { | { | ||||
| public: | public: | ||||
| HashesComponent() | HashesComponent() | ||||
| @@ -137,7 +136,17 @@ public: | |||||
| hashEntryBox.setReturnKeyStartsNewLine (true); | hashEntryBox.setReturnKeyStartsNewLine (true); | ||||
| hashEntryBox.setText ("Type some text in this box and the resulting MD5, SHA and Whirlpool hashes will update below"); | hashEntryBox.setText ("Type some text in this box and the resulting MD5, SHA and Whirlpool hashes will update below"); | ||||
| hashEntryBox.addListener (this); | |||||
| auto updateHashes = [this]() | |||||
| { | |||||
| auto text = hashEntryBox.getText(); | |||||
| updateMD5Result (text.toUTF8()); | |||||
| updateSHA256Result (text.toUTF8()); | |||||
| updateWhirlpoolResult (text.toUTF8()); | |||||
| }; | |||||
| hashEntryBox.onTextChange = updateHashes; | |||||
| hashEntryBox.onReturnKey = updateHashes; | |||||
| hashLabel1.setText ("Text to Hash:", dontSendNotification); | hashLabel1.setText ("Text to Hash:", dontSendNotification); | ||||
| hashLabel2.setText ("MD5 Result:", dontSendNotification); | hashLabel2.setText ("MD5 Result:", dontSendNotification); | ||||
| @@ -156,14 +165,6 @@ public: | |||||
| updateHashes(); | updateHashes(); | ||||
| } | } | ||||
| void updateHashes() | |||||
| { | |||||
| String text = hashEntryBox.getText(); | |||||
| updateMD5Result (text.toUTF8()); | |||||
| updateSHA256Result (text.toUTF8()); | |||||
| updateWhirlpoolResult (text.toUTF8()); | |||||
| } | |||||
| void updateMD5Result (CharPointer_UTF8 text) | void updateMD5Result (CharPointer_UTF8 text) | ||||
| { | { | ||||
| md5Result.setText (MD5 (text).toHexString(), dontSendNotification); | md5Result.setText (MD5 (text).toHexString(), dontSendNotification); | ||||
| @@ -181,7 +182,7 @@ public: | |||||
| void resized() override | void resized() override | ||||
| { | { | ||||
| Rectangle<int> area (getLocalBounds()); | |||||
| auto area = getLocalBounds(); | |||||
| hashGroup.setBounds (area); | hashGroup.setBounds (area); | ||||
| area.removeFromLeft (120); | area.removeFromLeft (120); | ||||
| area.removeFromTop (10); | area.removeFromTop (10); | ||||
| @@ -198,11 +199,6 @@ private: | |||||
| Label md5Result, shaResult, whirlpoolResult; | Label md5Result, shaResult, whirlpoolResult; | ||||
| Label hashLabel1, hashLabel2, hashLabel3, hashLabel4; | Label hashLabel1, hashLabel2, hashLabel3, hashLabel4; | ||||
| void textEditorTextChanged (TextEditor&) override { updateHashes(); } | |||||
| void textEditorReturnKeyPressed (TextEditor&) override { updateHashes(); } | |||||
| void textEditorEscapeKeyPressed (TextEditor&) override { updateHashes(); } | |||||
| void textEditorFocusLost (TextEditor&) override { updateHashes(); } | |||||
| void lookAndFeelChanged() override | void lookAndFeelChanged() override | ||||
| { | { | ||||
| hashGroup.setColour (GroupComponent::outlineColourId, | hashGroup.setColour (GroupComponent::outlineColourId, | ||||
| @@ -29,27 +29,26 @@ | |||||
| // these classes are C++11-only | // these classes are C++11-only | ||||
| #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS | #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS | ||||
| struct DemoFlexPanel : public juce::Component, | |||||
| private juce::TextEditor::Listener | |||||
| struct DemoFlexPanel : public juce::Component | |||||
| { | { | ||||
| DemoFlexPanel (juce::Colour col, FlexItem& item) : flexItem (item), colour (col) | DemoFlexPanel (juce::Colour col, FlexItem& item) : flexItem (item), colour (col) | ||||
| { | { | ||||
| int x = 70; | int x = 70; | ||||
| int y = 3; | int y = 3; | ||||
| setupTextEditor (flexOrderEditor, { x, y, 20, 18 }, "0"); | |||||
| setupTextEditor (flexOrderEditor, { x, y, 20, 18 }, "0", [this]() { flexItem.order = (int) flexOrderEditor.getText().getFloatValue(); }); | |||||
| addLabel ("order", flexOrderEditor); | addLabel ("order", flexOrderEditor); | ||||
| y += 20; | y += 20; | ||||
| setupTextEditor (flexGrowEditor, { x, y, 20, 18 }, "0"); | |||||
| setupTextEditor (flexGrowEditor, { x, y, 20, 18 }, "0", [this]() { flexItem.flexGrow = flexGrowEditor.getText().getFloatValue(); }); | |||||
| addLabel ("flex-grow", flexGrowEditor); | addLabel ("flex-grow", flexGrowEditor); | ||||
| y += 20; | y += 20; | ||||
| setupTextEditor (flexShrinkEditor, { x, y, 20, 18 }, "1"); | |||||
| setupTextEditor (flexShrinkEditor, { x, y, 20, 18 }, "1", [this]() { flexItem.flexShrink = flexShrinkEditor.getText().getFloatValue(); }); | |||||
| addLabel ("flex-shrink", flexShrinkEditor); | addLabel ("flex-shrink", flexShrinkEditor); | ||||
| y += 20; | y += 20; | ||||
| setupTextEditor (flexBasisEditor, { x, y, 33, 18 }, "100"); | |||||
| setupTextEditor (flexBasisEditor, { x, y, 33, 18 }, "100", [this]() { flexItem.flexBasis = flexBasisEditor.getText().getFloatValue(); }); | |||||
| addLabel ("flex-basis", flexBasisEditor); | addLabel ("flex-basis", flexBasisEditor); | ||||
| y += 20; | y += 20; | ||||
| @@ -67,11 +66,18 @@ struct DemoFlexPanel : public juce::Component, | |||||
| addLabel ("align-self", alignSelfCombo); | addLabel ("align-self", alignSelfCombo); | ||||
| } | } | ||||
| void setupTextEditor (TextEditor& te, Rectangle<int> b, StringRef initialText) | |||||
| void setupTextEditor (TextEditor& te, Rectangle<int> b, StringRef initialText, std::function<void()> updateFn) | |||||
| { | { | ||||
| te.setBounds (b); | te.setBounds (b); | ||||
| te.setText (initialText); | te.setText (initialText); | ||||
| te.addListener (this); | |||||
| te.onTextChange = [this, updateFn]() | |||||
| { | |||||
| updateFn(); | |||||
| if (auto parent = getParentComponent()) | |||||
| parent->resized(); | |||||
| }; | |||||
| addAndMakeVisible (te); | addAndMakeVisible (te); | ||||
| } | } | ||||
| @@ -99,19 +105,6 @@ struct DemoFlexPanel : public juce::Component, | |||||
| parent->resized(); | parent->resized(); | ||||
| } | } | ||||
| void textEditorTextChanged (TextEditor& textEditor) override | |||||
| { | |||||
| auto textIntValue = textEditor.getText().getFloatValue(); | |||||
| if (&textEditor == &flexOrderEditor) flexItem.order = (int) textIntValue; | |||||
| if (&textEditor == &flexGrowEditor) flexItem.flexGrow = textIntValue; | |||||
| if (&textEditor == &flexBasisEditor) flexItem.flexBasis = textIntValue; | |||||
| if (&textEditor == &flexShrinkEditor) flexItem.flexShrink = textIntValue; | |||||
| if (auto parent = getParentComponent()) | |||||
| parent->resized(); | |||||
| } | |||||
| void paint (Graphics& g) override | void paint (Graphics& g) override | ||||
| { | { | ||||
| auto r = getLocalBounds(); | auto r = getLocalBounds(); | ||||
| @@ -32,8 +32,7 @@ | |||||
| flag is used to promt the user to save the note when it is closed. | flag is used to promt the user to save the note when it is closed. | ||||
| */ | */ | ||||
| class Note : public Component, | class Note : public Component, | ||||
| public FileBasedDocument, | |||||
| private TextEditor::Listener | |||||
| public FileBasedDocument | |||||
| { | { | ||||
| public: | public: | ||||
| Note (const String& name, const String& contents) | Note (const String& name, const String& contents) | ||||
| @@ -50,12 +49,7 @@ public: | |||||
| editor.setReturnKeyStartsNewLine (true); | editor.setReturnKeyStartsNewLine (true); | ||||
| editor.getTextValue().referTo (textValueObject); | editor.getTextValue().referTo (textValueObject); | ||||
| addAndMakeVisible (editor); | addAndMakeVisible (editor); | ||||
| editor.addListener (this); | |||||
| } | |||||
| ~Note() | |||||
| { | |||||
| editor.removeListener (this); | |||||
| editor.onTextChange = [this]() { changed(); }; | |||||
| } | } | ||||
| void resized() override | void resized() override | ||||
| @@ -107,22 +101,11 @@ private: | |||||
| Value textValueObject; | Value textValueObject; | ||||
| TextEditor editor; | TextEditor editor; | ||||
| void textEditorTextChanged (TextEditor& ed) override | |||||
| { | |||||
| // let our FileBasedDocument know we've changed | |||||
| if (&ed == &editor) | |||||
| changed(); | |||||
| } | |||||
| void lookAndFeelChanged() override | void lookAndFeelChanged() override | ||||
| { | { | ||||
| editor.applyFontToAllText (editor.getFont()); | editor.applyFontToAllText (editor.getFont()); | ||||
| } | } | ||||
| void textEditorReturnKeyPressed (TextEditor&) override {} | |||||
| void textEditorEscapeKeyPressed (TextEditor&) override {} | |||||
| void textEditorFocusLost (TextEditor&) override {} | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Note) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Note) | ||||
| }; | }; | ||||
| @@ -29,7 +29,6 @@ | |||||
| //============================================================================== | //============================================================================== | ||||
| class NetworkingDemo : public Component, | class NetworkingDemo : public Component, | ||||
| private TextEditor::Listener, | |||||
| private Thread | private Thread | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -41,7 +40,7 @@ public: | |||||
| addAndMakeVisible (urlBox); | addAndMakeVisible (urlBox); | ||||
| urlBox.setText ("https://www.google.com"); | urlBox.setText ("https://www.google.com"); | ||||
| urlBox.addListener (this); | |||||
| urlBox.onReturnKey = [this]() { fetchButton.triggerClick(); }; | |||||
| addAndMakeVisible (fetchButton); | addAndMakeVisible (fetchButton); | ||||
| fetchButton.setButtonText ("Download URL Contents"); | fetchButton.setButtonText ("Download URL Contents"); | ||||
| @@ -106,11 +105,6 @@ private: | |||||
| CodeDocument resultsDocument; | CodeDocument resultsDocument; | ||||
| CodeEditorComponent resultsBox; | CodeEditorComponent resultsBox; | ||||
| void textEditorReturnKeyPressed (TextEditor&) override | |||||
| { | |||||
| fetchButton.triggerClick(); | |||||
| } | |||||
| void lookAndFeelChanged() override | void lookAndFeelChanged() override | ||||
| { | { | ||||
| urlBox.applyFontToAllText (urlBox.getFont()); | urlBox.applyFontToAllText (urlBox.getFont()); | ||||
| @@ -68,21 +68,17 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| class WebBrowserDemo : public Component, | |||||
| private TextEditor::Listener | |||||
| class WebBrowserDemo : public Component | |||||
| { | { | ||||
| public: | public: | ||||
| WebBrowserDemo() | WebBrowserDemo() | ||||
| : goButton ("Go", "Go to URL"), | |||||
| backButton ("<<", "Back"), | |||||
| forwardButton (">>", "Forward") | |||||
| { | { | ||||
| setOpaque (true); | setOpaque (true); | ||||
| // Create an address box.. | // Create an address box.. | ||||
| addAndMakeVisible (addressTextBox); | addAndMakeVisible (addressTextBox); | ||||
| addressTextBox.setTextToShowWhenEmpty ("Enter a web address, e.g. https://www.juce.com", Colours::grey); | addressTextBox.setTextToShowWhenEmpty ("Enter a web address, e.g. https://www.juce.com", Colours::grey); | ||||
| addressTextBox.addListener (this); | |||||
| addressTextBox.onReturnKey = [this]() { webView->goToURL (addressTextBox.getText()); }; | |||||
| // create the actual browser component | // create the actual browser component | ||||
| addAndMakeVisible (webView = new DemoBrowserComponent (addressTextBox)); | addAndMakeVisible (webView = new DemoBrowserComponent (addressTextBox)); | ||||
| @@ -118,16 +114,10 @@ private: | |||||
| ScopedPointer<DemoBrowserComponent> webView; | ScopedPointer<DemoBrowserComponent> webView; | ||||
| TextEditor addressTextBox; | TextEditor addressTextBox; | ||||
| TextButton goButton, backButton, forwardButton; | |||||
| void textEditorTextChanged (TextEditor&) override {} | |||||
| void textEditorEscapeKeyPressed (TextEditor&) override {} | |||||
| void textEditorFocusLost (TextEditor&) override {} | |||||
| void textEditorReturnKeyPressed (TextEditor&) override | |||||
| { | |||||
| webView->goToURL (addressTextBox.getText()); | |||||
| } | |||||
| TextButton goButton { "Go", "Go to URL" }, | |||||
| backButton { "<<", "Back" }, | |||||
| forwardButton { ">>", "Forward" }; | |||||
| void lookAndFeelChanged() override | void lookAndFeelChanged() override | ||||
| { | { | ||||
| @@ -198,8 +198,7 @@ static String getNoDeviceString() { return "<< " + TRANS("none") + " >>"; } | |||||
| //============================================================================== | //============================================================================== | ||||
| class AudioDeviceSettingsPanel : public Component, | class AudioDeviceSettingsPanel : public Component, | ||||
| private ChangeListener, | |||||
| private ComboBox::Listener | |||||
| private ChangeListener | |||||
| { | { | ||||
| public: | public: | ||||
| AudioDeviceSettingsPanel (AudioIODeviceType& t, AudioDeviceSetupDetails& setupDetails, | AudioDeviceSettingsPanel (AudioIODeviceType& t, AudioDeviceSetupDetails& setupDetails, | ||||
| @@ -328,17 +327,13 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void comboBoxChanged (ComboBox* comboBoxThatHasChanged) override | |||||
| void updateConfig (bool updateOutputDevice, bool updateInputDevice, bool updateSampleRate, bool updateBufferSize) | |||||
| { | { | ||||
| if (comboBoxThatHasChanged == nullptr) | |||||
| return; | |||||
| AudioDeviceManager::AudioDeviceSetup config; | AudioDeviceManager::AudioDeviceSetup config; | ||||
| setup.manager->getAudioDeviceSetup (config); | setup.manager->getAudioDeviceSetup (config); | ||||
| String error; | String error; | ||||
| if (comboBoxThatHasChanged == outputDeviceDropDown | |||||
| || comboBoxThatHasChanged == inputDeviceDropDown) | |||||
| if (updateOutputDevice || updateInputDevice) | |||||
| { | { | ||||
| if (outputDeviceDropDown != nullptr) | if (outputDeviceDropDown != nullptr) | ||||
| config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String() | config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String() | ||||
| @@ -351,7 +346,7 @@ public: | |||||
| if (! type.hasSeparateInputsAndOutputs()) | if (! type.hasSeparateInputsAndOutputs()) | ||||
| config.inputDeviceName = config.outputDeviceName; | config.inputDeviceName = config.outputDeviceName; | ||||
| if (comboBoxThatHasChanged == inputDeviceDropDown) | |||||
| if (updateInputDevice) | |||||
| config.useDefaultInputChannels = true; | config.useDefaultInputChannels = true; | ||||
| else | else | ||||
| config.useDefaultOutputChannels = true; | config.useDefaultOutputChannels = true; | ||||
| @@ -364,7 +359,7 @@ public: | |||||
| updateControlPanelButton(); | updateControlPanelButton(); | ||||
| resized(); | resized(); | ||||
| } | } | ||||
| else if (comboBoxThatHasChanged == sampleRateDropDown) | |||||
| else if (updateSampleRate) | |||||
| { | { | ||||
| if (sampleRateDropDown->getSelectedId() > 0) | if (sampleRateDropDown->getSelectedId() > 0) | ||||
| { | { | ||||
| @@ -372,7 +367,7 @@ public: | |||||
| error = setup.manager->setAudioDeviceSetup (config, true); | error = setup.manager->setAudioDeviceSetup (config, true); | ||||
| } | } | ||||
| } | } | ||||
| else if (comboBoxThatHasChanged == bufferSizeDropDown) | |||||
| else if (updateBufferSize) | |||||
| { | { | ||||
| if (bufferSizeDropDown->getSelectedId() > 0) | if (bufferSizeDropDown->getSelectedId() > 0) | ||||
| { | { | ||||
| @@ -606,7 +601,8 @@ private: | |||||
| if (outputDeviceDropDown == nullptr) | if (outputDeviceDropDown == nullptr) | ||||
| { | { | ||||
| outputDeviceDropDown = new ComboBox(); | outputDeviceDropDown = new ComboBox(); | ||||
| outputDeviceDropDown->addListener (this); | |||||
| outputDeviceDropDown->onChange = [this]() { updateConfig (true, false, false, false); }; | |||||
| addAndMakeVisible (outputDeviceDropDown); | addAndMakeVisible (outputDeviceDropDown); | ||||
| outputDeviceLabel = new Label ({}, type.hasSeparateInputsAndOutputs() ? TRANS("Output:") | outputDeviceLabel = new Label ({}, type.hasSeparateInputsAndOutputs() ? TRANS("Output:") | ||||
| @@ -634,7 +630,7 @@ private: | |||||
| if (inputDeviceDropDown == nullptr) | if (inputDeviceDropDown == nullptr) | ||||
| { | { | ||||
| inputDeviceDropDown = new ComboBox(); | inputDeviceDropDown = new ComboBox(); | ||||
| inputDeviceDropDown->addListener (this); | |||||
| inputDeviceDropDown->onChange = [this]() { updateConfig (false, true, false, false); }; | |||||
| addAndMakeVisible (inputDeviceDropDown); | addAndMakeVisible (inputDeviceDropDown); | ||||
| inputDeviceLabel = new Label ({}, TRANS("Input:")); | inputDeviceLabel = new Label ({}, TRANS("Input:")); | ||||
| @@ -662,7 +658,7 @@ private: | |||||
| else | else | ||||
| { | { | ||||
| sampleRateDropDown->clear(); | sampleRateDropDown->clear(); | ||||
| sampleRateDropDown->removeListener (this); | |||||
| sampleRateDropDown->onChange = {}; | |||||
| } | } | ||||
| for (auto rate : currentDevice->getAvailableSampleRates()) | for (auto rate : currentDevice->getAvailableSampleRates()) | ||||
| @@ -672,7 +668,7 @@ private: | |||||
| } | } | ||||
| sampleRateDropDown->setSelectedId (roundToInt (currentDevice->getCurrentSampleRate()), dontSendNotification); | sampleRateDropDown->setSelectedId (roundToInt (currentDevice->getCurrentSampleRate()), dontSendNotification); | ||||
| sampleRateDropDown->addListener (this); | |||||
| sampleRateDropDown->onChange = [this]() { updateConfig (false, false, true, false); }; | |||||
| } | } | ||||
| void updateBufferSizeComboBox (AudioIODevice* currentDevice) | void updateBufferSizeComboBox (AudioIODevice* currentDevice) | ||||
| @@ -687,7 +683,7 @@ private: | |||||
| else | else | ||||
| { | { | ||||
| bufferSizeDropDown->clear(); | bufferSizeDropDown->clear(); | ||||
| bufferSizeDropDown->removeListener (this); | |||||
| bufferSizeDropDown->onChange = {}; | |||||
| } | } | ||||
| auto currentRate = currentDevice->getCurrentSampleRate(); | auto currentRate = currentDevice->getCurrentSampleRate(); | ||||
| @@ -699,7 +695,7 @@ private: | |||||
| bufferSizeDropDown->addItem (String (bs) + " samples (" + String (bs * 1000.0 / currentRate, 1) + " ms)", bs); | bufferSizeDropDown->addItem (String (bs) + " samples (" + String (bs * 1000.0 / currentRate, 1) + " ms)", bs); | ||||
| bufferSizeDropDown->setSelectedId (currentDevice->getCurrentBufferSizeSamples(), dontSendNotification); | bufferSizeDropDown->setSelectedId (currentDevice->getCurrentBufferSizeSamples(), dontSendNotification); | ||||
| bufferSizeDropDown->addListener (this); | |||||
| bufferSizeDropDown->onChange = [this]() { updateConfig (false, false, false, true); }; | |||||
| } | } | ||||
| public: | public: | ||||
| @@ -31,7 +31,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_, | |||||
| const File& initialFileOrDirectory, | const File& initialFileOrDirectory, | ||||
| const FileFilter* fileFilter_, | const FileFilter* fileFilter_, | ||||
| FilePreviewComponent* previewComp_) | FilePreviewComponent* previewComp_) | ||||
| : FileFilter (String()), | |||||
| : FileFilter ({}), | |||||
| fileFilter (fileFilter_), | fileFilter (fileFilter_), | ||||
| flags (flags_), | flags (flags_), | ||||
| previewComp (previewComp_), | previewComp (previewComp_), | ||||
| @@ -93,7 +93,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_, | |||||
| addAndMakeVisible (currentPathBox); | addAndMakeVisible (currentPathBox); | ||||
| currentPathBox.setEditableText (true); | currentPathBox.setEditableText (true); | ||||
| resetRecentPaths(); | resetRecentPaths(); | ||||
| currentPathBox.addListener (this); | |||||
| currentPathBox.onChange = [this]() { updateSelectedPath(); }; | |||||
| addAndMakeVisible (filenameBox); | addAndMakeVisible (filenameBox); | ||||
| filenameBox.setMultiLine (false); | filenameBox.setMultiLine (false); | ||||
| @@ -410,7 +410,7 @@ void FileBrowserComponent::fileDoubleClicked (const File& f) | |||||
| setRoot (f); | setRoot (f); | ||||
| if ((flags & canSelectDirectories) != 0 && (flags & doNotClearFileNameOnRootChange) == 0) | if ((flags & canSelectDirectories) != 0 && (flags & doNotClearFileNameOnRootChange) == 0) | ||||
| filenameBox.setText (String()); | |||||
| filenameBox.setText ({}); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -455,7 +455,7 @@ void FileBrowserComponent::textEditorReturnKeyPressed (TextEditor&) | |||||
| chosenFiles.clear(); | chosenFiles.clear(); | ||||
| if ((flags & doNotClearFileNameOnRootChange) == 0) | if ((flags & doNotClearFileNameOnRootChange) == 0) | ||||
| filenameBox.setText (String()); | |||||
| filenameBox.setText ({}); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -482,7 +482,7 @@ void FileBrowserComponent::textEditorFocusLost (TextEditor&) | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void FileBrowserComponent::comboBoxChanged (ComboBox*) | |||||
| void FileBrowserComponent::updateSelectedPath() | |||||
| { | { | ||||
| auto newText = currentPathBox.getText().trim().unquoted(); | auto newText = currentPathBox.getText().trim().unquoted(); | ||||
| @@ -493,9 +493,9 @@ void FileBrowserComponent::comboBoxChanged (ComboBox*) | |||||
| StringArray rootNames, rootPaths; | StringArray rootNames, rootPaths; | ||||
| getRoots (rootNames, rootPaths); | getRoots (rootNames, rootPaths); | ||||
| if (rootPaths [index].isNotEmpty()) | |||||
| if (rootPaths[index].isNotEmpty()) | |||||
| { | { | ||||
| setRoot (File (rootPaths [index])); | |||||
| setRoot (File (rootPaths[index])); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -549,8 +549,8 @@ void FileBrowserComponent::getDefaultRoots (StringArray& rootNames, StringArray& | |||||
| rootNames.add (name); | rootNames.add (name); | ||||
| } | } | ||||
| rootPaths.add (String()); | |||||
| rootNames.add (String()); | |||||
| rootPaths.add ({}); | |||||
| rootNames.add ({}); | |||||
| rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName()); | rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName()); | ||||
| rootNames.add (TRANS("Documents")); | rootNames.add (TRANS("Documents")); | ||||
| @@ -573,8 +573,8 @@ void FileBrowserComponent::getDefaultRoots (StringArray& rootNames, StringArray& | |||||
| rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName()); | rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName()); | ||||
| rootNames.add (TRANS("Desktop")); | rootNames.add (TRANS("Desktop")); | ||||
| rootPaths.add (String()); | |||||
| rootNames.add (String()); | |||||
| rootPaths.add ({}); | |||||
| rootNames.add ({}); | |||||
| Array<File> volumes; | Array<File> volumes; | ||||
| File vol ("/Volumes"); | File vol ("/Volumes"); | ||||
| @@ -40,7 +40,6 @@ namespace juce | |||||
| class JUCE_API FileBrowserComponent : public Component, | class JUCE_API FileBrowserComponent : public Component, | ||||
| private FileBrowserListener, | private FileBrowserListener, | ||||
| private TextEditor::Listener, | private TextEditor::Listener, | ||||
| private ComboBox::Listener, | |||||
| private FileFilter, | private FileFilter, | ||||
| private Timer | private Timer | ||||
| { | { | ||||
| @@ -236,8 +235,6 @@ public: | |||||
| /** @internal */ | /** @internal */ | ||||
| void lookAndFeelChanged() override; | void lookAndFeelChanged() override; | ||||
| /** @internal */ | /** @internal */ | ||||
| void comboBoxChanged (ComboBox*) override; | |||||
| /** @internal */ | |||||
| void textEditorTextChanged (TextEditor&) override; | void textEditorTextChanged (TextEditor&) override; | ||||
| /** @internal */ | /** @internal */ | ||||
| void textEditorReturnKeyPressed (TextEditor&) override; | void textEditorReturnKeyPressed (TextEditor&) override; | ||||
| @@ -297,6 +294,7 @@ private: | |||||
| void timerCallback() override; | void timerCallback() override; | ||||
| void sendListenerChangeMessage(); | void sendListenerChangeMessage(); | ||||
| bool isFileOrDirSuitable (const File&) const; | bool isFileOrDirSuitable (const File&) const; | ||||
| void updateSelectedPath(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileBrowserComponent) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileBrowserComponent) | ||||
| }; | }; | ||||
| @@ -38,9 +38,8 @@ namespace juce | |||||
| either be read-only text, or editable. | either be read-only text, or editable. | ||||
| To find out when the user selects a different item or edits the text, you | To find out when the user selects a different item or edits the text, you | ||||
| can register a ComboBox::Listener to receive callbacks. | |||||
| @see ComboBox::Listener | |||||
| can assign a lambda to the onChange member, or register a ComboBox::Listener | |||||
| to receive callbacks. | |||||
| */ | */ | ||||
| class JUCE_API ComboBox : public Component, | class JUCE_API ComboBox : public Component, | ||||
| public SettableTooltipClient, | public SettableTooltipClient, | ||||
| @@ -1220,7 +1220,7 @@ void TextEditor::textChanged() | |||||
| { | { | ||||
| updateTextHolderSize(); | updateTextHolderSize(); | ||||
| if (listeners.size() > 0) | |||||
| if (listeners.size() != 0 || onTextChange != nullptr) | |||||
| postCommandMessage (TextEditorDefs::textChangeMessageId); | postCommandMessage (TextEditorDefs::textChangeMessageId); | ||||
| if (textValue.getValueSource().getReferenceCount() > 1) | if (textValue.getValueSource().getReferenceCount() > 1) | ||||
| @@ -2099,19 +2099,35 @@ void TextEditor::handleCommandMessage (const int commandId) | |||||
| { | { | ||||
| case TextEditorDefs::textChangeMessageId: | case TextEditorDefs::textChangeMessageId: | ||||
| listeners.callChecked (checker, [this] (Listener& l) { l.textEditorTextChanged (*this); }); | listeners.callChecked (checker, [this] (Listener& l) { l.textEditorTextChanged (*this); }); | ||||
| if (! checker.shouldBailOut() && onTextChange != nullptr) | |||||
| onTextChange(); | |||||
| break; | break; | ||||
| case TextEditorDefs::returnKeyMessageId: | case TextEditorDefs::returnKeyMessageId: | ||||
| listeners.callChecked (checker, [this] (Listener& l) { l.textEditorReturnKeyPressed (*this); }); | listeners.callChecked (checker, [this] (Listener& l) { l.textEditorReturnKeyPressed (*this); }); | ||||
| if (! checker.shouldBailOut() && onReturnKey != nullptr) | |||||
| onReturnKey(); | |||||
| break; | break; | ||||
| case TextEditorDefs::escapeKeyMessageId: | case TextEditorDefs::escapeKeyMessageId: | ||||
| listeners.callChecked (checker, [this] (Listener& l) { l.textEditorEscapeKeyPressed (*this); }); | listeners.callChecked (checker, [this] (Listener& l) { l.textEditorEscapeKeyPressed (*this); }); | ||||
| if (! checker.shouldBailOut() && onEscapeKey != nullptr) | |||||
| onEscapeKey(); | |||||
| break; | break; | ||||
| case TextEditorDefs::focusLossMessageId: | case TextEditorDefs::focusLossMessageId: | ||||
| updateValueFromText(); | updateValueFromText(); | ||||
| listeners.callChecked (checker, [this] (Listener& l) { l.textEditorFocusLost (*this); }); | listeners.callChecked (checker, [this] (Listener& l) { l.textEditorFocusLost (*this); }); | ||||
| if (! checker.shouldBailOut() && onFocusLost != nullptr) | |||||
| onFocusLost(); | |||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -318,6 +318,19 @@ public: | |||||
| */ | */ | ||||
| void removeListener (Listener* listenerToRemove); | void removeListener (Listener* listenerToRemove); | ||||
| //============================================================================== | |||||
| /** You can assign a lambda to this callback object to have it called when the text is changed. */ | |||||
| std::function<void()> onTextChange; | |||||
| /** You can assign a lambda to this callback object to have it called when the return key is pressed. */ | |||||
| std::function<void()> onReturnKey; | |||||
| /** You can assign a lambda to this callback object to have it called when the escape key is pressed. */ | |||||
| std::function<void()> onEscapeKey; | |||||
| /** You can assign a lambda to this callback object to have it called when the editor loses key focus. */ | |||||
| std::function<void()> onFocusLost; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the entire contents of the editor. */ | /** Returns the entire contents of the editor. */ | ||||
| String getText() const; | String getText() const; | ||||