diff --git a/src/GUI/ProgressStatusBar.cpp b/src/GUI/ProgressStatusBar.cpp index 24822748b..ceb909af8 100644 --- a/src/GUI/ProgressStatusBar.cpp +++ b/src/GUI/ProgressStatusBar.cpp @@ -1,5 +1,62 @@ #include "ProgressStatusBar.hpp" - +#include "misc_ui.hpp" namespace Slic3r { namespace GUI { +ProgressStatusBar::ProgressStatusBar(wxWindow* parent, int id) : wxStatusBar(parent, id) { + this->prog->Hide(); + this->cancelbutton->Hide(); + + this->SetFieldsCount(3); + const int tmpWidths[] {-1, 150, 155}; // need to make the array ahead of time in C++ + this->SetStatusWidths(3, tmpWidths); + + // Assign events. + this->Bind(wxEVT_TIMER, [=](wxTimerEvent& e){this->OnTimer(e);}); + this->Bind(wxEVT_SIZE, [=](wxSizeEvent& e){this->OnSize(e);}); + this->Bind(wxEVT_BUTTON, [=](wxCommandEvent& e) { this->cancel_cb(); this->cancelbutton->Hide();}); +} + +ProgressStatusBar::~ProgressStatusBar() { + if (this->timer != nullptr) { + if (this->timer->IsRunning()) + this->timer->Stop(); + } +} + +/// wxPerl version of this used a impromptu hashmap and a loop +/// which more impractical here. +/// Opportunity to refactor here. +void ProgressStatusBar::OnSize(wxSizeEvent &e) { + + // position 0 is reserved for status text + // position 1 is cancel button + // position 2 is prog + + { + wxRect rect; + this->GetFieldRect(1, rect); + const auto& offset = ( wxGTK ? 1 : 0); // cosmetic 1px offset on wxgtk + const auto& pos {wxPoint(rect.x + offset, rect.y + offset)}; + this->cancelbutton->Move(pos); + this->cancelbutton->SetSize(rect.GetWidth() - offset, rect.GetHeight()); + } + + { + wxRect rect; + this->GetFieldRect(2, rect); + const auto& offset = ( wxGTK ? 1 : 0); // cosmetic 1px offset on wxgtk + const auto& pos {wxPoint(rect.x + offset, rect.y + offset)}; + this->prog->Move(pos); + this->prog->SetSize(rect.GetWidth() - offset, rect.GetHeight()); + } + e.Skip(); +} + +void ProgressStatusBar::OnTimer(wxTimerEvent& e) { + if (this->prog->IsShown()) + this->timer->Stop(); + if (this->busy) + this->prog->Pulse(); +} + }} // Namespace Slic3r::GUI diff --git a/src/GUI/ProgressStatusBar.hpp b/src/GUI/ProgressStatusBar.hpp index f2984691b..44e6dd60c 100644 --- a/src/GUI/ProgressStatusBar.hpp +++ b/src/GUI/ProgressStatusBar.hpp @@ -2,13 +2,56 @@ #define PROGRESSSTATUSBAR_HPP #include #include +#include +#include +#include namespace Slic3r { namespace GUI { class ProgressStatusBar : public wxStatusBar { public: /// Constructor stub from parent - ProgressStatusBar(wxWindow* parent, int id) : wxStatusBar(parent, id) { } + ProgressStatusBar(wxWindow* parent, int id); + + /// Stop any running timers before destruction. + ~ProgressStatusBar(); + + /// + wxTimer* timer {new wxTimer(this)}; + + /// Progress bar + wxGauge* prog {new wxGauge(this, wxGA_HORIZONTAL, 100, wxDefaultPosition, wxDefaultSize)}; + + /// General cancel button. Using applications can assign functions to it. + wxButton* cancelbutton {new wxButton(this, -1, _("Cancel"), wxDefaultPosition, wxDefaultSize)}; + + /// Set callback function for cancel button press. + void SetCancelCallback(std::function cb) { + this->cancel_cb = cb; + cb == nullptr ? this->cancelbutton->Hide() : this->cancelbutton->Show(); + } + + /// Accessor function for the current value of the progress bar + size_t GetProgress() {return this->prog->GetValue();} + + /// Accessor function for busy state + bool IsBusy() {return this->busy;} + + /// Show the progress bar. + void ShowProgress(bool show = true) { this->prog->Show(show); this->prog->Pulse(); } + + void SetRange(int range) { if (range != this->prog->GetRange() ) this->prog->SetRange(range);} + +private: + void OnSize(wxSizeEvent& e); + void OnTimer(wxTimerEvent& e); + void Run(int rate = 100) { if (this->timer->IsRunning()) this->timer->Start(rate);}; + + // Cancel callback function + std::function cancel_cb {[](){;}}; + + bool busy {false}; + }; }} // Namespace Slic3r::GUI diff --git a/src/GUI/misc_ui.hpp b/src/GUI/misc_ui.hpp index e733fe565..90ad19070 100644 --- a/src/GUI/misc_ui.hpp +++ b/src/GUI/misc_ui.hpp @@ -27,6 +27,11 @@ constexpr OS the_os = OS::Windows; constexpr OS the_os = OS::Mac; #elif __linux__ constexpr OS the_os = OS::Linux; + #ifdef __WXGTK__ + constexpr bool wxGTK {true}; + #else + constexpr bool wxGTK {false}; + #endif #endif #ifdef SLIC3R_DEV