Make progress bars less jerky
This commit is contained in:
parent
382708132c
commit
932747e70a
2 changed files with 36 additions and 2 deletions
|
@ -56,7 +56,7 @@ public:
|
|||
}
|
||||
|
||||
void SetProgress(int64_t cur, int64_t max) {
|
||||
Main().Async([=]{ dialog->gauge->SetValue(mid<int>(0, double(cur) / max * 100, 100)); });
|
||||
Main().Async([=]{ dialog->SetProgress(mid<int>(0, double(cur) / max * 300, 300)); });
|
||||
}
|
||||
|
||||
void Log(std::string const& str) {
|
||||
|
@ -79,9 +79,11 @@ public:
|
|||
DialogProgress::DialogProgress(wxWindow *parent, wxString const& title_text, wxString const& message)
|
||||
: wxDialog(parent, -1, title_text, wxDefaultPosition, wxDefaultSize, wxBORDER_RAISED)
|
||||
, pulse_timer(GetEventHandler())
|
||||
, progress_current(0)
|
||||
, progress_target(0)
|
||||
{
|
||||
title = new wxStaticText(this, -1, title_text, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE);
|
||||
gauge = new wxGauge(this, -1, 100, wxDefaultPosition, wxSize(300,20));
|
||||
gauge = new wxGauge(this, -1, 300, wxDefaultPosition, wxSize(300,20));
|
||||
text = new wxStaticText(this, -1, message, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE);
|
||||
cancel_button = new wxButton(this, wxID_CANCEL);
|
||||
log_output = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxSize(600, 240), wxTE_MULTILINE | wxTE_READONLY);
|
||||
|
@ -160,6 +162,17 @@ void DialogProgress::OnShow(wxShowEvent&) {
|
|||
}
|
||||
|
||||
void DialogProgress::OnIdle(wxIdleEvent&) {
|
||||
if (progress_current != progress_target) {
|
||||
using namespace std::chrono;
|
||||
auto now = steady_clock::now();
|
||||
int ms = mid<int>(0, duration_cast<milliseconds>(now - progress_anim_start_time).count(), progress_anim_duration);
|
||||
int dist = (progress_target - progress_anim_start_value) * ms / progress_anim_duration;
|
||||
if (dist) {
|
||||
progress_current = progress_anim_start_value + dist;
|
||||
gauge->SetValue(progress_current);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pending_log) return;
|
||||
|
||||
if (log_output->IsEmpty()) {
|
||||
|
@ -180,3 +193,16 @@ void DialogProgress::OnCancel(wxCommandEvent &) {
|
|||
cancel_button->Enable(false);
|
||||
cancel_button->SetLabelText(_("Cancelling..."));
|
||||
}
|
||||
|
||||
void DialogProgress::SetProgress(int target) {
|
||||
using namespace std::chrono;
|
||||
|
||||
progress_anim_start_value = progress_current;
|
||||
auto now = steady_clock::now();
|
||||
if (progress_target == 0)
|
||||
progress_anim_duration = 1000;
|
||||
else
|
||||
progress_anim_duration = std::max<int>(100, duration_cast<milliseconds>(now - progress_anim_start_time).count() * 11 / 10);
|
||||
progress_anim_start_time = now;
|
||||
progress_target = target;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
/// @ingroup utility
|
||||
///
|
||||
|
||||
#include <chrono>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
|
@ -43,11 +44,18 @@ class DialogProgress : public wxDialog, public agi::BackgroundRunner {
|
|||
wxTimer pulse_timer;
|
||||
|
||||
wxString pending_log;
|
||||
int progress_anim_start_value;
|
||||
int progress_current;
|
||||
int progress_target;
|
||||
std::chrono::steady_clock::time_point progress_anim_start_time;
|
||||
int progress_anim_duration;
|
||||
|
||||
void OnShow(wxShowEvent&);
|
||||
void OnCancel(wxCommandEvent &);
|
||||
void OnIdle(wxIdleEvent&);
|
||||
|
||||
void SetProgress(int target);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param parent Parent window of the dialog
|
||||
|
|
Loading…
Reference in a new issue