1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Added a callback so that ThreadWithProgressWindow can be used without blocking.

This commit is contained in:
jules 2014-02-19 12:14:56 +00:00
parent a6aca791af
commit 8c40999c51
3 changed files with 78 additions and 40 deletions

View file

@ -62,6 +62,27 @@ public:
setStatusMessage ("Finishing off the last few bits and pieces!");
wait (2000);
}
// This method gets called on the message thread once our thread has finished..
void threadComplete (bool userPressedCancel) override
{
if (userPressedCancel)
{
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Progress window",
"You pressed cancel!");
}
else
{
// thread finished normally..
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Progress window",
"Thread finished ok!");
}
// ..and clean up by deleting our thread object..
delete this;
}
};
@ -239,24 +260,9 @@ private:
}
else if (type == progressWindow)
{
DemoBackgroundThread demoThread;
#if JUCE_MODAL_LOOPS_PERMITTED
if (demoThread.runThread())
{
// thread finished normally..
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Progress window",
"Thread finished ok!");
}
else
{
// user pressed the cancel button..
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Progress window",
"You pressed cancel!");
}
#endif
// This will launch our ThreadWithProgressWindow in a modal state. (Our subclass
// will take care of deleting the object when the task has finished)
(new DemoBackgroundThread())->launchThread();
}
else if (type >= loadChooser && type <= saveChooser)
{

View file

@ -25,12 +25,13 @@
ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title,
const bool hasProgressBar,
const bool hasCancelButton,
const int timeOutMsWhenCancelling_,
const int cancellingTimeOutMs,
const String& cancelButtonText,
Component* componentToCentreAround)
: Thread ("Juce Progress Window"),
progress (0.0),
timeOutMsWhenCancelling (timeOutMsWhenCancelling_)
: Thread ("Juce Progress Window"),
progress (0.0),
timeOutMsWhenCancelling (cancellingTimeOutMs),
wasCancelledByUser (false)
{
alertWindow = LookAndFeel::getDefaultLookAndFeel()
.createAlertWindow (title, String(),
@ -52,8 +53,7 @@ ThreadWithProgressWindow::~ThreadWithProgressWindow()
stopThread (timeOutMsWhenCancelling);
}
#if JUCE_MODAL_LOOPS_PERMITTED
bool ThreadWithProgressWindow::runThread (const int priority)
void ThreadWithProgressWindow::launchThread (int priority)
{
jassert (MessageManager::getInstance()->isThisTheMessageThread());
@ -65,15 +65,8 @@ bool ThreadWithProgressWindow::runThread (const int priority)
alertWindow->setMessage (message);
}
const bool finishedNaturally = alertWindow->runModalLoop() != 0;
stopThread (timeOutMsWhenCancelling);
alertWindow->setVisible (false);
return finishedNaturally;
alertWindow->enterModalState();
}
#endif
void ThreadWithProgressWindow::setProgress (const double newProgress)
{
@ -88,15 +81,34 @@ void ThreadWithProgressWindow::setStatusMessage (const String& newStatusMessage)
void ThreadWithProgressWindow::timerCallback()
{
if (! isThreadRunning())
bool threadStillRunning = isThreadRunning();
if (! (threadStillRunning && alertWindow->isCurrentlyModal()))
{
// thread has finished normally..
stopTimer();
stopThread (timeOutMsWhenCancelling);
alertWindow->exitModalState (1);
alertWindow->setVisible (false);
wasCancelledByUser = threadStillRunning;
threadComplete (threadStillRunning);
return; // (this may be deleted now)
}
else
{
const ScopedLock sl (messageLock);
alertWindow->setMessage (message);
}
const ScopedLock sl (messageLock);
alertWindow->setMessage (message);
}
void ThreadWithProgressWindow::threadComplete (bool) {}
#if JUCE_MODAL_LOOPS_PERMITTED
bool ThreadWithProgressWindow::runThread (const int priority)
{
launchThread (priority);
while (isTimerRunning())
MessageManager::getInstance()->runDispatchLoopUntil (5);
return ! wasCancelledByUser;
}
#endif

View file

@ -111,6 +111,7 @@ public:
~ThreadWithProgressWindow();
//==============================================================================
#if JUCE_MODAL_LOOPS_PERMITTED
/** Starts the thread and waits for it to finish.
This will start the thread, make the dialog box appear, and wait until either
@ -123,6 +124,18 @@ public:
@returns true if the thread finished normally; false if the user pressed cancel
*/
bool runThread (int threadPriority = 5);
#endif
/** Starts the thread and returns.
This will start the thread and make the dialog box appear in a modal state. When
the thread finishes normally, or the cancel button is pressed, the window will be
hidden and the threadComplete() method will be called.
@param threadPriority the priority to use when starting the thread - see
Thread::startThread() for values
*/
void launchThread (int threadPriority = 5);
/** The thread should call this periodically to update the position of the progress bar.
@ -137,15 +150,22 @@ public:
/** Returns the AlertWindow that is being used. */
AlertWindow* getAlertWindow() const noexcept { return alertWindow; }
//==============================================================================
/** This method is called (on the message thread) when the operation has finished.
You may choose to use this callback to delete the ThreadWithProgressWindow object.
*/
virtual void threadComplete (bool userPressedCancel);
private:
//==============================================================================
void timerCallback() override;
double progress;
ScopedPointer <AlertWindow> alertWindow;
ScopedPointer<AlertWindow> alertWindow;
String message;
CriticalSection messageLock;
const int timeOutMsWhenCancelling;
bool wasCancelledByUser;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadWithProgressWindow)
};