Okay, in that case, go ahead. I don’t know the example code too well
Here’s the link.
It’s the BasicWindow class code example:
And yes, I’ll switch over to deleteAndZero()
Ah, now I understand why you use a SafePointer
in first place - to be able to check if the window has deleted itself (when it was closed). That makes sense.
Yep, I don’t really know how else to manage any other pointer if it were used to point at a window that can self-delete. I wouldn’t have access to the window pointer to set it to NULL, so I use SafePointer.
SafePointers are very slick!
I was given this suggestion for a popupwindow:
struct PopupWindow : public DocumentWindow
{
std::function<void()> onClose;
PopupWindow( /*args*/ ) : DocumentWindow( /*typical args*/ ) {}
void closeButtonPressed() override
{
if( onClose ) { onClose(); }
}
};
struct MainComponent : public Component
{
std::unique_ptr<PopupWindow> popupWindow;
//snip...
void showPopup()
{
popupWindow = std::make_unique<PopupWindow>( /* args */ );
popupWindow.get()->onClose = [this]()
{
this->popupWindow.reset( nullptr );
};
popupWindow.get()->centreWithSize( /*args */ );
popupWindow.get()->setVisible(true);
}
};
No safe pointers, no tight coupling, super easy to show/delete, and NO self deletion.
Thanks for this suggestion. I received similar advice but was unable to get the lambda to properly capture variables from the application for the pop-up window to interact with. For some reason, I was able to close the popup from the lambda, but not change text in my main application GUI.
I took this approach which worked:
Popup
class AudioSettingsWindow : public DocumentWindow,
ChangeListener
{
// (constructor, other code...)
// override close button
void closeButtonPressed() override
{
if (closeSettings)
{
closeSettings();
}
}
// callback method to be set in main application
std::function<void()> closeSettings;
}
Main application
class BHRecDemo : public Component
{
BHRecDemo()
{
// other initialization code...
// Creates settings window -KGK
settingsButton.onClick = [this]
{
if (settingsWindow != nullptr) {
settingsWindow.reset();
settingsButton.setButtonText(openSettings);
}
else
{
// Create settings window
settingsWindow = std::make_unique<AudioSettingsWindow>(
"Audio Settings", audioDeviceManager.get());
settingsWindow->centreWithSize(500, 600);
settingsWindow->setVisible(true);
// Assign callback to handle the deletion of the settings window
settingsWindow.get()->closeSettings = std::bind(&BHRecDemo::closeSettingsWindow, this);
// Cleanup main app
this->toFront(true);
settingsButton.setButtonText(closeSettings);
}
};
}
void closeSettingsWindow()
{
settingsWindow.reset();
settingsButton.setButtonText(openSettings);
}
const juce::String openSettings = "Open Settings";
const juce::String closeSettings = "Close Settings";
TextButton recordButton { "Record" };
TextButton settingsButton{ openSettings };
std::unique_ptr <AudioSettingsWindow> settingsWindow;
}
I like not having the callback function inline, but more importantly I had to do it this way to avoid null pointer errors when trying to update the button text. It was some kind of scoping issue, but it persisted even when I made the button a public member… really I don’t have a clue what the problem was.