diff --git a/libs/wxutil/ModalProgressDialog.cpp b/libs/wxutil/ModalProgressDialog.cpp index a14f9c45aa..0e5f50b4cd 100644 --- a/libs/wxutil/ModalProgressDialog.cpp +++ b/libs/wxutil/ModalProgressDialog.cpp @@ -12,6 +12,27 @@ ModalProgressDialog::ModalProgressDialog(const std::string& title, wxWindow* par wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_AUTO_HIDE) {} +void ModalProgressDialog::setFraction(double fraction) +{ + if (WasCancelled()) + { + throw OperationAbortedException(_("Operation cancelled by user")); + } + + if (fraction < 0) + { + fraction = 0.0; + } + else if (fraction > 1.0) + { + fraction = 1.0; + } + + int newValue = static_cast(fraction * 100); + + Update(newValue); +} + void ModalProgressDialog::setText(const std::string& text) { // If the aborted flag is set, throw an exception here diff --git a/libs/wxutil/ModalProgressDialog.h b/libs/wxutil/ModalProgressDialog.h index 8f849148c9..21c8c828c4 100644 --- a/libs/wxutil/ModalProgressDialog.h +++ b/libs/wxutil/ModalProgressDialog.h @@ -26,6 +26,13 @@ class ModalProgressDialog : : std::runtime_error(what) {} }; + /** + * Set the completed fraction of the progress bar. + * If the user has clicked the Cancel button since the last update, this method + * will throw an exception to indicate an aborted operation. + */ + void setFraction(double fraction); + /** * Set the text to display in the label, and pulse the progress bar. If the * user has clicked the Cancel button since the last update, this method diff --git a/radiant/ui/MapFileProgressHandler.h b/radiant/ui/MapFileProgressHandler.h index 5fd26d25b9..14c700a980 100644 --- a/radiant/ui/MapFileProgressHandler.h +++ b/radiant/ui/MapFileProgressHandler.h @@ -7,6 +7,7 @@ #include "messages/MapFileOperation.h" #include "wxutil/ModalProgressDialog.h" #include "wxutil/dialog/MessageBox.h" +#include "ui/mainframe/ScreenUpdateBlocker.h" #include "registry/registry.h" namespace ui @@ -17,7 +18,7 @@ class MapFileProgressHandler private: std::size_t _msgSubscription; - wxutil::ModalProgressDialogPtr _dialog; + std::unique_ptr _blocker; public: MapFileProgressHandler() @@ -42,33 +43,34 @@ class MapFileProgressHandler case map::FileOperation::Started: if (GlobalMainFrame().isActiveApp() && !registry::getValue(RKEY_MAP_SUPPRESS_LOAD_STATUS_DIALOG)) { - _dialog.reset(new wxutil::ModalProgressDialog( - msg.getOperationType() == map::FileOperation::Type::Export ? _("Writing map") : _("Loading map"))); + _blocker.reset(new ScreenUpdateBlocker( + msg.getOperationType() == map::FileOperation::Type::Export ? _("Writing map") : _("Loading map"), + _("Processing..."), true)); } break; case map::FileOperation::Progress: - if (!_dialog) break; + if (!_blocker) break; if (msg.canCalculateProgress()) { - _dialog->setTextAndFraction(msg.getText(), msg.getProgressFraction()); + _blocker->setMessageAndProgress(msg.getText(), msg.getProgressFraction()); } else { - _dialog->setText(msg.getText()); - _dialog->Pulse(); + _blocker->setMessage(msg.getText()); + _blocker->pulse(); } break; case map::FileOperation::Finished: - _dialog.reset(); + _blocker.reset(); break; }; } catch (const wxutil::ModalProgressDialog::OperationAbortedException&) { - _dialog.reset(); + _blocker.reset(); msg.cancelOperation(); } } diff --git a/radiant/ui/mainframe/ScreenUpdateBlocker.cpp b/radiant/ui/mainframe/ScreenUpdateBlocker.cpp index 7e3ec4a77b..bc79702ce7 100644 --- a/radiant/ui/mainframe/ScreenUpdateBlocker.cpp +++ b/radiant/ui/mainframe/ScreenUpdateBlocker.cpp @@ -12,10 +12,13 @@ namespace ui { ScreenUpdateBlocker::ScreenUpdateBlocker(const std::string& title, const std::string& message, bool forceDisplay) : - TransientWindow(title, GlobalMainFrame().getWxTopLevelWindow()), - _gauge(NULL), + wxutil::ModalProgressDialog(title, GlobalMainFrame().getWxTopLevelWindow()), +#if 0 + _gauge(nullptr), +#endif _pulseAllowed(true) { +#if 0 SetWindowStyleFlag(GetWindowStyleFlag() & ~(wxRESIZE_BORDER|wxCLOSE_BOX|wxMINIMIZE_BOX)); SetSizer(new wxBoxSizer(wxVERTICAL)); @@ -40,7 +43,7 @@ ScreenUpdateBlocker::ScreenUpdateBlocker(const std::string& title, const std::st Layout(); Fit(); CenterOnParent(); - +#endif // Set the "screen updates disabled" flag (also disables autosaver) GlobalMainFrame().disableScreenUpdates(); @@ -59,21 +62,15 @@ ScreenUpdateBlocker::ScreenUpdateBlocker(const std::string& title, const std::st // Register for the "is-active" changed event, to display this dialog // as soon as Radiant is getting the focus again - GlobalMainFrame().getWxTopLevelWindow()->Connect( - wxEVT_SET_FOCUS, wxFocusEventHandler(ScreenUpdateBlocker::onMainWindowFocus), NULL, this); - - Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(ScreenUpdateBlocker::onCloseEvent), NULL, this); + GlobalMainFrame().getWxTopLevelWindow()->Bind(wxEVT_SET_FOCUS, &ScreenUpdateBlocker::onMainWindowFocus, this); - Bind(wxEVT_IDLE, [&](wxIdleEvent&) - { - pulse(); - }); + Bind(wxEVT_CLOSE_WINDOW, &ScreenUpdateBlocker::onCloseEvent, this); + Bind(wxEVT_IDLE, [&](wxIdleEvent&) { pulse(); }); } ScreenUpdateBlocker::~ScreenUpdateBlocker() { - GlobalMainFrame().getWxTopLevelWindow()->Disconnect( - wxEVT_SET_FOCUS, wxFocusEventHandler(ScreenUpdateBlocker::onMainWindowFocus), NULL, this); + GlobalMainFrame().getWxTopLevelWindow()->Unbind(wxEVT_SET_FOCUS, &ScreenUpdateBlocker::onMainWindowFocus, this); // Process pending events to flush keystroke buffer etc. wxTheApp->Yield(true); @@ -92,25 +89,39 @@ void ScreenUpdateBlocker::pulse() { if (_pulseAllowed) { + ModalProgressDialog::Pulse(); +#if 0 _gauge->Pulse(); +#endif } } -void ScreenUpdateBlocker::setProgress(float progress) +void ScreenUpdateBlocker::doSetProgress(float progress) { + ModalProgressDialog::setFraction(progress); + +#if 0 if (progress < 0.0f) progress = 0.0f; if (progress > 1.0f) progress = 1.0f; _gauge->SetValue(static_cast(progress * 100)); - +#endif _pulseAllowed = false; +} +void ScreenUpdateBlocker::setProgress(float progress) +{ + doSetProgress(progress); +#if 0 Refresh(); Update(); +#endif } -void ScreenUpdateBlocker::setMessage(const std::string& message) +void ScreenUpdateBlocker::doSetMessage(const std::string& message) { + ModalProgressDialog::setText(message); +#if 0 std::size_t oldLength = _message->GetLabel().Length(); _message->SetLabel(message); @@ -121,9 +132,27 @@ void ScreenUpdateBlocker::setMessage(const std::string& message) Fit(); CenterOnParent(); } +#endif +} + +void ScreenUpdateBlocker::setMessage(const std::string& message) +{ + doSetMessage(message); + + Refresh(); + Update(); +} + +void ScreenUpdateBlocker::setMessageAndProgress(const std::string& message, float progress) +{ + ModalProgressDialog::setTextAndFraction(message, progress); +#if 0 + doSetProgress(progress); + doSetMessage(message); Refresh(); Update(); +#endif } void ScreenUpdateBlocker::onMainWindowFocus(wxFocusEvent& ev) diff --git a/radiant/ui/mainframe/ScreenUpdateBlocker.h b/radiant/ui/mainframe/ScreenUpdateBlocker.h index 9b43642f10..2cedb1c4af 100644 --- a/radiant/ui/mainframe/ScreenUpdateBlocker.h +++ b/radiant/ui/mainframe/ScreenUpdateBlocker.h @@ -3,7 +3,7 @@ #include "imainframe.h" #include -#include "wxutil/window/TransientWindow.h" +#include "wxutil/ModalProgressDialog.h" class wxGauge; class wxStaticText; @@ -13,14 +13,15 @@ namespace ui class ScreenUpdateBlocker : public IScopedScreenUpdateBlocker, - public wxutil::TransientWindow + public wxutil::ModalProgressDialog { private: std::unique_ptr _disabler; +#if 0 wxStaticText* _message; wxGauge* _gauge; - +#endif // Once we received a call to setProgress() further calls to pulse() are forbidden bool _pulseAllowed; @@ -31,10 +32,14 @@ class ScreenUpdateBlocker : void pulse(); void setProgress(float progress); void setMessage(const std::string& message); + void setMessageAndProgress(const std::string& message, float progress); ~ScreenUpdateBlocker(); private: + void doSetProgress(float progress); + void doSetMessage(const std::string& message); + // Called whenever the main window is changing its "active" state property. void onMainWindowFocus(wxFocusEvent& ev); void onCloseEvent(wxCloseEvent& ev);