Browse Source

Added some event lambda callbacks for TextEditor and simplified a bit more code using them

tags/2021-05-28
jules 7 years ago
parent
commit
80a7718286
11 changed files with 93 additions and 115 deletions
  1. +14
    -18
      examples/Demo/Source/Demos/CryptographyDemo.cpp
  2. +14
    -21
      examples/Demo/Source/Demos/FlexBoxDemo.cpp
  3. +2
    -19
      examples/Demo/Source/Demos/MDIDemo.cpp
  4. +1
    -7
      examples/Demo/Source/Demos/NetworkingDemo.cpp
  5. +5
    -15
      examples/Demo/Source/Demos/WebBrowserDemo.cpp
  6. +13
    -17
      modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp
  7. +11
    -11
      modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp
  8. +1
    -3
      modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h
  9. +2
    -3
      modules/juce_gui_basics/widgets/juce_ComboBox.h
  10. +17
    -1
      modules/juce_gui_basics/widgets/juce_TextEditor.cpp
  11. +13
    -0
      modules/juce_gui_basics/widgets/juce_TextEditor.h

+ 14
- 18
examples/Demo/Source/Demos/CryptographyDemo.cpp View File

@@ -57,7 +57,7 @@ public:
area.removeFromTop (10);
area.reduce (5, 5);
Rectangle<int> topArea (area.removeFromTop (34));
auto topArea = area.removeFromTop (34);
topArea.removeFromLeft (110);
bitSize.setBounds (topArea.removeFromLeft (topArea.getWidth() / 2).reduced (5));
generateRSAButton.setBounds (topArea.reduced (5));
@@ -123,8 +123,7 @@ private:
};
//==============================================================================
class HashesComponent : public Component,
private TextEditor::Listener
class HashesComponent : public Component
{
public:
HashesComponent()
@@ -137,7 +136,17 @@ public:
hashEntryBox.setReturnKeyStartsNewLine (true);
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);
hashLabel2.setText ("MD5 Result:", dontSendNotification);
@@ -156,14 +165,6 @@ public:
updateHashes();
}
void updateHashes()
{
String text = hashEntryBox.getText();
updateMD5Result (text.toUTF8());
updateSHA256Result (text.toUTF8());
updateWhirlpoolResult (text.toUTF8());
}
void updateMD5Result (CharPointer_UTF8 text)
{
md5Result.setText (MD5 (text).toHexString(), dontSendNotification);
@@ -181,7 +182,7 @@ public:
void resized() override
{
Rectangle<int> area (getLocalBounds());
auto area = getLocalBounds();
hashGroup.setBounds (area);
area.removeFromLeft (120);
area.removeFromTop (10);
@@ -198,11 +199,6 @@ private:
Label md5Result, shaResult, whirlpoolResult;
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
{
hashGroup.setColour (GroupComponent::outlineColourId,


+ 14
- 21
examples/Demo/Source/Demos/FlexBoxDemo.cpp View File

@@ -29,27 +29,26 @@
// these classes are C++11-only
#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)
{
int x = 70;
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);
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);
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);
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);
y += 20;
@@ -67,11 +66,18 @@ struct DemoFlexPanel : public juce::Component,
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.setText (initialText);
te.addListener (this);
te.onTextChange = [this, updateFn]()
{
updateFn();
if (auto parent = getParentComponent())
parent->resized();
};
addAndMakeVisible (te);
}
@@ -99,19 +105,6 @@ struct DemoFlexPanel : public juce::Component,
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
{
auto r = getLocalBounds();


+ 2
- 19
examples/Demo/Source/Demos/MDIDemo.cpp View File

@@ -32,8 +32,7 @@
flag is used to promt the user to save the note when it is closed.
*/
class Note : public Component,
public FileBasedDocument,
private TextEditor::Listener
public FileBasedDocument
{
public:
Note (const String& name, const String& contents)
@@ -50,12 +49,7 @@ public:
editor.setReturnKeyStartsNewLine (true);
editor.getTextValue().referTo (textValueObject);
addAndMakeVisible (editor);
editor.addListener (this);
}
~Note()
{
editor.removeListener (this);
editor.onTextChange = [this]() { changed(); };
}
void resized() override
@@ -107,22 +101,11 @@ private:
Value textValueObject;
TextEditor editor;
void textEditorTextChanged (TextEditor& ed) override
{
// let our FileBasedDocument know we've changed
if (&ed == &editor)
changed();
}
void lookAndFeelChanged() override
{
editor.applyFontToAllText (editor.getFont());
}
void textEditorReturnKeyPressed (TextEditor&) override {}
void textEditorEscapeKeyPressed (TextEditor&) override {}
void textEditorFocusLost (TextEditor&) override {}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Note)
};


+ 1
- 7
examples/Demo/Source/Demos/NetworkingDemo.cpp View File

@@ -29,7 +29,6 @@
//==============================================================================
class NetworkingDemo : public Component,
private TextEditor::Listener,
private Thread
{
public:
@@ -41,7 +40,7 @@ public:
addAndMakeVisible (urlBox);
urlBox.setText ("https://www.google.com");
urlBox.addListener (this);
urlBox.onReturnKey = [this]() { fetchButton.triggerClick(); };
addAndMakeVisible (fetchButton);
fetchButton.setButtonText ("Download URL Contents");
@@ -106,11 +105,6 @@ private:
CodeDocument resultsDocument;
CodeEditorComponent resultsBox;
void textEditorReturnKeyPressed (TextEditor&) override
{
fetchButton.triggerClick();
}
void lookAndFeelChanged() override
{
urlBox.applyFontToAllText (urlBox.getFont());


+ 5
- 15
examples/Demo/Source/Demos/WebBrowserDemo.cpp View File

@@ -68,21 +68,17 @@ private:
//==============================================================================
class WebBrowserDemo : public Component,
private TextEditor::Listener
class WebBrowserDemo : public Component
{
public:
WebBrowserDemo()
: goButton ("Go", "Go to URL"),
backButton ("<<", "Back"),
forwardButton (">>", "Forward")
{
setOpaque (true);
// Create an address box..
addAndMakeVisible (addressTextBox);
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
addAndMakeVisible (webView = new DemoBrowserComponent (addressTextBox));
@@ -118,16 +114,10 @@ private:
ScopedPointer<DemoBrowserComponent> webView;
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
{


+ 13
- 17
modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp View File

@@ -198,8 +198,7 @@ static String getNoDeviceString() { return "<< " + TRANS("none") + " >>"; }
//==============================================================================
class AudioDeviceSettingsPanel : public Component,
private ChangeListener,
private ComboBox::Listener
private ChangeListener
{
public:
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;
setup.manager->getAudioDeviceSetup (config);
String error;
if (comboBoxThatHasChanged == outputDeviceDropDown
|| comboBoxThatHasChanged == inputDeviceDropDown)
if (updateOutputDevice || updateInputDevice)
{
if (outputDeviceDropDown != nullptr)
config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String()
@@ -351,7 +346,7 @@ public:
if (! type.hasSeparateInputsAndOutputs())
config.inputDeviceName = config.outputDeviceName;
if (comboBoxThatHasChanged == inputDeviceDropDown)
if (updateInputDevice)
config.useDefaultInputChannels = true;
else
config.useDefaultOutputChannels = true;
@@ -364,7 +359,7 @@ public:
updateControlPanelButton();
resized();
}
else if (comboBoxThatHasChanged == sampleRateDropDown)
else if (updateSampleRate)
{
if (sampleRateDropDown->getSelectedId() > 0)
{
@@ -372,7 +367,7 @@ public:
error = setup.manager->setAudioDeviceSetup (config, true);
}
}
else if (comboBoxThatHasChanged == bufferSizeDropDown)
else if (updateBufferSize)
{
if (bufferSizeDropDown->getSelectedId() > 0)
{
@@ -606,7 +601,8 @@ private:
if (outputDeviceDropDown == nullptr)
{
outputDeviceDropDown = new ComboBox();
outputDeviceDropDown->addListener (this);
outputDeviceDropDown->onChange = [this]() { updateConfig (true, false, false, false); };
addAndMakeVisible (outputDeviceDropDown);
outputDeviceLabel = new Label ({}, type.hasSeparateInputsAndOutputs() ? TRANS("Output:")
@@ -634,7 +630,7 @@ private:
if (inputDeviceDropDown == nullptr)
{
inputDeviceDropDown = new ComboBox();
inputDeviceDropDown->addListener (this);
inputDeviceDropDown->onChange = [this]() { updateConfig (false, true, false, false); };
addAndMakeVisible (inputDeviceDropDown);
inputDeviceLabel = new Label ({}, TRANS("Input:"));
@@ -662,7 +658,7 @@ private:
else
{
sampleRateDropDown->clear();
sampleRateDropDown->removeListener (this);
sampleRateDropDown->onChange = {};
}
for (auto rate : currentDevice->getAvailableSampleRates())
@@ -672,7 +668,7 @@ private:
}
sampleRateDropDown->setSelectedId (roundToInt (currentDevice->getCurrentSampleRate()), dontSendNotification);
sampleRateDropDown->addListener (this);
sampleRateDropDown->onChange = [this]() { updateConfig (false, false, true, false); };
}
void updateBufferSizeComboBox (AudioIODevice* currentDevice)
@@ -687,7 +683,7 @@ private:
else
{
bufferSizeDropDown->clear();
bufferSizeDropDown->removeListener (this);
bufferSizeDropDown->onChange = {};
}
auto currentRate = currentDevice->getCurrentSampleRate();
@@ -699,7 +695,7 @@ private:
bufferSizeDropDown->addItem (String (bs) + " samples (" + String (bs * 1000.0 / currentRate, 1) + " ms)", bs);
bufferSizeDropDown->setSelectedId (currentDevice->getCurrentBufferSizeSamples(), dontSendNotification);
bufferSizeDropDown->addListener (this);
bufferSizeDropDown->onChange = [this]() { updateConfig (false, false, false, true); };
}
public:


+ 11
- 11
modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp View File

@@ -31,7 +31,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_,
const File& initialFileOrDirectory,
const FileFilter* fileFilter_,
FilePreviewComponent* previewComp_)
: FileFilter (String()),
: FileFilter ({}),
fileFilter (fileFilter_),
flags (flags_),
previewComp (previewComp_),
@@ -93,7 +93,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_,
addAndMakeVisible (currentPathBox);
currentPathBox.setEditableText (true);
resetRecentPaths();
currentPathBox.addListener (this);
currentPathBox.onChange = [this]() { updateSelectedPath(); };
addAndMakeVisible (filenameBox);
filenameBox.setMultiLine (false);
@@ -410,7 +410,7 @@ void FileBrowserComponent::fileDoubleClicked (const File& f)
setRoot (f);
if ((flags & canSelectDirectories) != 0 && (flags & doNotClearFileNameOnRootChange) == 0)
filenameBox.setText (String());
filenameBox.setText ({});
}
else
{
@@ -455,7 +455,7 @@ void FileBrowserComponent::textEditorReturnKeyPressed (TextEditor&)
chosenFiles.clear();
if ((flags & doNotClearFileNameOnRootChange) == 0)
filenameBox.setText (String());
filenameBox.setText ({});
}
else
{
@@ -482,7 +482,7 @@ void FileBrowserComponent::textEditorFocusLost (TextEditor&)
}
//==============================================================================
void FileBrowserComponent::comboBoxChanged (ComboBox*)
void FileBrowserComponent::updateSelectedPath()
{
auto newText = currentPathBox.getText().trim().unquoted();
@@ -493,9 +493,9 @@ void FileBrowserComponent::comboBoxChanged (ComboBox*)
StringArray rootNames, rootPaths;
getRoots (rootNames, rootPaths);
if (rootPaths [index].isNotEmpty())
if (rootPaths[index].isNotEmpty())
{
setRoot (File (rootPaths [index]));
setRoot (File (rootPaths[index]));
}
else
{
@@ -549,8 +549,8 @@ void FileBrowserComponent::getDefaultRoots (StringArray& rootNames, StringArray&
rootNames.add (name);
}
rootPaths.add (String());
rootNames.add (String());
rootPaths.add ({});
rootNames.add ({});
rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName());
rootNames.add (TRANS("Documents"));
@@ -573,8 +573,8 @@ void FileBrowserComponent::getDefaultRoots (StringArray& rootNames, StringArray&
rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName());
rootNames.add (TRANS("Desktop"));
rootPaths.add (String());
rootNames.add (String());
rootPaths.add ({});
rootNames.add ({});
Array<File> volumes;
File vol ("/Volumes");


+ 1
- 3
modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h View File

@@ -40,7 +40,6 @@ namespace juce
class JUCE_API FileBrowserComponent : public Component,
private FileBrowserListener,
private TextEditor::Listener,
private ComboBox::Listener,
private FileFilter,
private Timer
{
@@ -236,8 +235,6 @@ public:
/** @internal */
void lookAndFeelChanged() override;
/** @internal */
void comboBoxChanged (ComboBox*) override;
/** @internal */
void textEditorTextChanged (TextEditor&) override;
/** @internal */
void textEditorReturnKeyPressed (TextEditor&) override;
@@ -297,6 +294,7 @@ private:
void timerCallback() override;
void sendListenerChangeMessage();
bool isFileOrDirSuitable (const File&) const;
void updateSelectedPath();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileBrowserComponent)
};


+ 2
- 3
modules/juce_gui_basics/widgets/juce_ComboBox.h View File

@@ -38,9 +38,8 @@ namespace juce
either be read-only text, or editable.
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,
public SettableTooltipClient,


+ 17
- 1
modules/juce_gui_basics/widgets/juce_TextEditor.cpp View File

@@ -1220,7 +1220,7 @@ void TextEditor::textChanged()
{
updateTextHolderSize();
if (listeners.size() > 0)
if (listeners.size() != 0 || onTextChange != nullptr)
postCommandMessage (TextEditorDefs::textChangeMessageId);
if (textValue.getValueSource().getReferenceCount() > 1)
@@ -2099,19 +2099,35 @@ void TextEditor::handleCommandMessage (const int commandId)
{
case TextEditorDefs::textChangeMessageId:
listeners.callChecked (checker, [this] (Listener& l) { l.textEditorTextChanged (*this); });
if (! checker.shouldBailOut() && onTextChange != nullptr)
onTextChange();
break;
case TextEditorDefs::returnKeyMessageId:
listeners.callChecked (checker, [this] (Listener& l) { l.textEditorReturnKeyPressed (*this); });
if (! checker.shouldBailOut() && onReturnKey != nullptr)
onReturnKey();
break;
case TextEditorDefs::escapeKeyMessageId:
listeners.callChecked (checker, [this] (Listener& l) { l.textEditorEscapeKeyPressed (*this); });
if (! checker.shouldBailOut() && onEscapeKey != nullptr)
onEscapeKey();
break;
case TextEditorDefs::focusLossMessageId:
updateValueFromText();
listeners.callChecked (checker, [this] (Listener& l) { l.textEditorFocusLost (*this); });
if (! checker.shouldBailOut() && onFocusLost != nullptr)
onFocusLost();
break;
default:


+ 13
- 0
modules/juce_gui_basics/widgets/juce_TextEditor.h View File

@@ -318,6 +318,19 @@ public:
*/
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. */
String getText() const;


Loading…
Cancel
Save