mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 15:10:05 +00:00 
			
		
		
		
	Add generic progress dialog, and derived download dialog
This commit is contained in:
		
							parent
							
								
									4ac2626b65
								
							
						
					
					
						commit
						2f397106f9
					
				
					 6 changed files with 374 additions and 0 deletions
				
			
		|  | @ -221,6 +221,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp | ||||||
|            source/scwx/qt/ui/animation_dock_widget.hpp |            source/scwx/qt/ui/animation_dock_widget.hpp | ||||||
|            source/scwx/qt/ui/collapsible_group.hpp |            source/scwx/qt/ui/collapsible_group.hpp | ||||||
|            source/scwx/qt/ui/county_dialog.hpp |            source/scwx/qt/ui/county_dialog.hpp | ||||||
|  |            source/scwx/qt/ui/download_dialog.hpp | ||||||
|            source/scwx/qt/ui/flow_layout.hpp |            source/scwx/qt/ui/flow_layout.hpp | ||||||
|            source/scwx/qt/ui/imgui_debug_dialog.hpp |            source/scwx/qt/ui/imgui_debug_dialog.hpp | ||||||
|            source/scwx/qt/ui/imgui_debug_widget.hpp |            source/scwx/qt/ui/imgui_debug_widget.hpp | ||||||
|  | @ -232,6 +233,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp | ||||||
|            source/scwx/qt/ui/open_url_dialog.hpp |            source/scwx/qt/ui/open_url_dialog.hpp | ||||||
|            source/scwx/qt/ui/placefile_dialog.hpp |            source/scwx/qt/ui/placefile_dialog.hpp | ||||||
|            source/scwx/qt/ui/placefile_settings_widget.hpp |            source/scwx/qt/ui/placefile_settings_widget.hpp | ||||||
|  |            source/scwx/qt/ui/progress_dialog.hpp | ||||||
|            source/scwx/qt/ui/radar_site_dialog.hpp |            source/scwx/qt/ui/radar_site_dialog.hpp | ||||||
|            source/scwx/qt/ui/settings_dialog.hpp |            source/scwx/qt/ui/settings_dialog.hpp | ||||||
|            source/scwx/qt/ui/update_dialog.hpp) |            source/scwx/qt/ui/update_dialog.hpp) | ||||||
|  | @ -241,6 +243,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp | ||||||
|            source/scwx/qt/ui/animation_dock_widget.cpp |            source/scwx/qt/ui/animation_dock_widget.cpp | ||||||
|            source/scwx/qt/ui/collapsible_group.cpp |            source/scwx/qt/ui/collapsible_group.cpp | ||||||
|            source/scwx/qt/ui/county_dialog.cpp |            source/scwx/qt/ui/county_dialog.cpp | ||||||
|  |            source/scwx/qt/ui/download_dialog.cpp | ||||||
|            source/scwx/qt/ui/flow_layout.cpp |            source/scwx/qt/ui/flow_layout.cpp | ||||||
|            source/scwx/qt/ui/imgui_debug_dialog.cpp |            source/scwx/qt/ui/imgui_debug_dialog.cpp | ||||||
|            source/scwx/qt/ui/imgui_debug_widget.cpp |            source/scwx/qt/ui/imgui_debug_widget.cpp | ||||||
|  | @ -252,6 +255,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp | ||||||
|            source/scwx/qt/ui/open_url_dialog.cpp |            source/scwx/qt/ui/open_url_dialog.cpp | ||||||
|            source/scwx/qt/ui/placefile_dialog.cpp |            source/scwx/qt/ui/placefile_dialog.cpp | ||||||
|            source/scwx/qt/ui/placefile_settings_widget.cpp |            source/scwx/qt/ui/placefile_settings_widget.cpp | ||||||
|  |            source/scwx/qt/ui/progress_dialog.cpp | ||||||
|            source/scwx/qt/ui/radar_site_dialog.cpp |            source/scwx/qt/ui/radar_site_dialog.cpp | ||||||
|            source/scwx/qt/ui/settings_dialog.cpp |            source/scwx/qt/ui/settings_dialog.cpp | ||||||
|            source/scwx/qt/ui/update_dialog.cpp) |            source/scwx/qt/ui/update_dialog.cpp) | ||||||
|  | @ -266,6 +270,7 @@ set(UI_UI  source/scwx/qt/ui/about_dialog.ui | ||||||
|            source/scwx/qt/ui/open_url_dialog.ui |            source/scwx/qt/ui/open_url_dialog.ui | ||||||
|            source/scwx/qt/ui/placefile_dialog.ui |            source/scwx/qt/ui/placefile_dialog.ui | ||||||
|            source/scwx/qt/ui/placefile_settings_widget.ui |            source/scwx/qt/ui/placefile_settings_widget.ui | ||||||
|  |            source/scwx/qt/ui/progress_dialog.ui | ||||||
|            source/scwx/qt/ui/radar_site_dialog.ui |            source/scwx/qt/ui/radar_site_dialog.ui | ||||||
|            source/scwx/qt/ui/settings_dialog.ui |            source/scwx/qt/ui/settings_dialog.ui | ||||||
|            source/scwx/qt/ui/update_dialog.ui) |            source/scwx/qt/ui/update_dialog.ui) | ||||||
|  |  | ||||||
							
								
								
									
										134
									
								
								scwx-qt/source/scwx/qt/ui/download_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								scwx-qt/source/scwx/qt/ui/download_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,134 @@ | ||||||
|  | #include <scwx/qt/ui/download_dialog.hpp> | ||||||
|  | #include <scwx/util/strings.hpp> | ||||||
|  | 
 | ||||||
|  | #include <boost/timer/timer.hpp> | ||||||
|  | #include <fmt/chrono.h> | ||||||
|  | #include <fmt/format.h> | ||||||
|  | #include <QDialogButtonBox> | ||||||
|  | #include <QPushButton> | ||||||
|  | #include <QTimer> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class DownloadDialog::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl(DownloadDialog* self) : self_ {self} | ||||||
|  |    { | ||||||
|  |       updateTimer_.setSingleShot(true); | ||||||
|  |       updateTimer_.setInterval(0); | ||||||
|  | 
 | ||||||
|  |       QObject::connect(&updateTimer_, | ||||||
|  |                        &QTimer::timeout, | ||||||
|  |                        self_, | ||||||
|  |                        [this]() { UpdateProgress(); }); | ||||||
|  |    }; | ||||||
|  |    ~Impl() = default; | ||||||
|  | 
 | ||||||
|  |    void UpdateProgress(); | ||||||
|  | 
 | ||||||
|  |    DownloadDialog* self_; | ||||||
|  | 
 | ||||||
|  |    boost::timer::cpu_timer timer_ {}; | ||||||
|  |    QTimer                  updateTimer_ {}; | ||||||
|  | 
 | ||||||
|  |    std::ptrdiff_t downloadedBytes_ {}; | ||||||
|  |    std::ptrdiff_t totalBytes_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | DownloadDialog::DownloadDialog(QWidget* parent) : | ||||||
|  |     ProgressDialog(parent), p {std::make_unique<Impl>(this)} | ||||||
|  | { | ||||||
|  |    auto buttonBox = button_box(); | ||||||
|  |    buttonBox->setStandardButtons(QDialogButtonBox::StandardButton::Ok | | ||||||
|  |                                  QDialogButtonBox::StandardButton::Cancel); | ||||||
|  |    buttonBox->button(QDialogButtonBox::StandardButton::Ok) | ||||||
|  |       ->setText("Install Now"); | ||||||
|  | 
 | ||||||
|  |    SetRange(0, 100); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DownloadDialog::~DownloadDialog() {} | ||||||
|  | 
 | ||||||
|  | void DownloadDialog::set_filename(const std::string& filename) | ||||||
|  | { | ||||||
|  |    QString label = tr("Downloading %1...").arg(filename.c_str()); | ||||||
|  |    SetTopLabelText(label); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DownloadDialog::StartDownload() | ||||||
|  | { | ||||||
|  |    // Hide the OK button until the download is finished
 | ||||||
|  |    button_box() | ||||||
|  |       ->button(QDialogButtonBox::StandardButton::Ok) | ||||||
|  |       ->setVisible(false); | ||||||
|  | 
 | ||||||
|  |    SetBottomLabelText(tr("Waiting for download to begin...")); | ||||||
|  |    p->timer_.start(); | ||||||
|  |    show(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DownloadDialog::UpdateProgress(std::ptrdiff_t downloadedBytes, | ||||||
|  |                                     std::ptrdiff_t totalBytes) | ||||||
|  | { | ||||||
|  |    p->downloadedBytes_ = downloadedBytes; | ||||||
|  |    p->totalBytes_      = totalBytes; | ||||||
|  | 
 | ||||||
|  |    // Use a one-shot timer to trigger an update, preventing multiple updates per
 | ||||||
|  |    // frame
 | ||||||
|  |    p->updateTimer_.start(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DownloadDialog::FinishDownload() | ||||||
|  | { | ||||||
|  |    button_box()->button(QDialogButtonBox::StandardButton::Ok)->setVisible(true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DownloadDialog::CancelDownload() | ||||||
|  | { | ||||||
|  |    SetValue(0); | ||||||
|  |    SetBottomLabelText(tr("Error occurred while downloading")); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DownloadDialog::Impl::UpdateProgress() | ||||||
|  | { | ||||||
|  |    using namespace std::chrono_literals; | ||||||
|  | 
 | ||||||
|  |    const std::ptrdiff_t downloadedBytes = downloadedBytes_; | ||||||
|  |    const std::ptrdiff_t totalBytes      = totalBytes_; | ||||||
|  | 
 | ||||||
|  |    const std::chrono::nanoseconds elapsed {timer_.elapsed().wall}; | ||||||
|  | 
 | ||||||
|  |    const double percentComplete = | ||||||
|  |       (totalBytes > 0.0) ? static_cast<double>(downloadedBytes) / totalBytes : | ||||||
|  |                            0.0; | ||||||
|  |    const int progressValue = static_cast<int>(percentComplete * 100.0); | ||||||
|  | 
 | ||||||
|  |    self_->SetValue(progressValue); | ||||||
|  | 
 | ||||||
|  |    const std::chrono::seconds timeRemaining = | ||||||
|  |       (percentComplete > 0.0) ? | ||||||
|  |          std::chrono::duration_cast<std::chrono::seconds>( | ||||||
|  |             elapsed / percentComplete - elapsed) : | ||||||
|  |          0s; | ||||||
|  |    const std::chrono::hours hoursRemaining = | ||||||
|  |       std::chrono::duration_cast<std::chrono::hours>(timeRemaining); | ||||||
|  | 
 | ||||||
|  |    const std::string progressText = | ||||||
|  |       fmt::format("{} of {} downloaded ({}:{:%M:%S} remaining)", | ||||||
|  |                   util::BytesToString(downloadedBytes), | ||||||
|  |                   util::BytesToString(totalBytes), | ||||||
|  |                   hoursRemaining.count(), | ||||||
|  |                   timeRemaining); | ||||||
|  | 
 | ||||||
|  |    self_->SetBottomLabelText(QString::fromStdString(progressText)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										38
									
								
								scwx-qt/source/scwx/qt/ui/download_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								scwx-qt/source/scwx/qt/ui/download_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/qt/ui/progress_dialog.hpp> | ||||||
|  | 
 | ||||||
|  | #include <cstddef> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | class DownloadDialog : public ProgressDialog | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  |    Q_DISABLE_COPY_MOVE(DownloadDialog) | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |    explicit DownloadDialog(QWidget* parent = nullptr); | ||||||
|  |    ~DownloadDialog(); | ||||||
|  | 
 | ||||||
|  |    void set_filename(const std::string& filename); | ||||||
|  | 
 | ||||||
|  | public slots: | ||||||
|  |    void StartDownload(); | ||||||
|  |    void UpdateProgress(std::ptrdiff_t downloadedBytes, | ||||||
|  |                        std::ptrdiff_t totalBytes); | ||||||
|  |    void FinishDownload(); | ||||||
|  |    void CancelDownload(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										66
									
								
								scwx-qt/source/scwx/qt/ui/progress_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								scwx-qt/source/scwx/qt/ui/progress_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | ||||||
|  | #include "progress_dialog.hpp" | ||||||
|  | #include "ui_progress_dialog.h" | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class ProgressDialog::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | ProgressDialog::ProgressDialog(QWidget* parent) : | ||||||
|  |     QDialog(parent), p {std::make_unique<Impl>()}, ui(new Ui::ProgressDialog) | ||||||
|  | { | ||||||
|  |    ui->setupUi(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ProgressDialog::~ProgressDialog() | ||||||
|  | { | ||||||
|  |    delete ui; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QDialogButtonBox* ProgressDialog::button_box() const | ||||||
|  | { | ||||||
|  |    return ui->buttonBox; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ProgressDialog::SetTopLabelText(const QString& text) | ||||||
|  | { | ||||||
|  |    ui->topLabel->setText(text); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ProgressDialog::SetBottomLabelText(const QString& text) | ||||||
|  | { | ||||||
|  |    ui->bottomLabel->setText(text); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ProgressDialog::SetMinimum(int minimum) | ||||||
|  | { | ||||||
|  |    ui->progressBar->setMinimum(minimum); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ProgressDialog::SetMaximum(int maximum) | ||||||
|  | { | ||||||
|  |    ui->progressBar->setMaximum(maximum); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ProgressDialog::SetRange(int minimum, int maximum) | ||||||
|  | { | ||||||
|  |    ui->progressBar->setRange(minimum, maximum); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ProgressDialog::SetValue(int value) | ||||||
|  | { | ||||||
|  |    ui->progressBar->setValue(value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										46
									
								
								scwx-qt/source/scwx/qt/ui/progress_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								scwx-qt/source/scwx/qt/ui/progress_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <QDialog> | ||||||
|  | 
 | ||||||
|  | class QDialogButtonBox; | ||||||
|  | 
 | ||||||
|  | namespace Ui | ||||||
|  | { | ||||||
|  | class ProgressDialog; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace ui | ||||||
|  | { | ||||||
|  | class ProgressDialog : public QDialog | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  |    Q_DISABLE_COPY_MOVE(ProgressDialog) | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |    explicit ProgressDialog(QWidget* parent = nullptr); | ||||||
|  |    ~ProgressDialog(); | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  |    QDialogButtonBox* button_box() const; | ||||||
|  | 
 | ||||||
|  | public slots: | ||||||
|  |    void SetTopLabelText(const QString& text); | ||||||
|  |    void SetBottomLabelText(const QString& text); | ||||||
|  |    void SetMinimum(int minimum); | ||||||
|  |    void SetMaximum(int maximum); | ||||||
|  |    void SetRange(int minimum, int maximum); | ||||||
|  |    void SetValue(int value); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  |    Ui::ProgressDialog*   ui; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace ui
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										85
									
								
								scwx-qt/source/scwx/qt/ui/progress_dialog.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								scwx-qt/source/scwx/qt/ui/progress_dialog.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,85 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>ProgressDialog</class> | ||||||
|  |  <widget class="QDialog" name="ProgressDialog"> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>394</width> | ||||||
|  |     <height>116</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Dialog</string> | ||||||
|  |   </property> | ||||||
|  |   <layout class="QVBoxLayout" name="verticalLayout"> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QLabel" name="topLabel"> | ||||||
|  |      <property name="text"> | ||||||
|  |       <string>Downloading supercell-wx-v0.4.4-windows-x64.msi...</string> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QProgressBar" name="progressBar"> | ||||||
|  |      <property name="value"> | ||||||
|  |       <number>24</number> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QLabel" name="bottomLabel"> | ||||||
|  |      <property name="text"> | ||||||
|  |       <string>25.3 MB of 69.1 MB downloaded (00:00:04 remaining)</string> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |    <item> | ||||||
|  |     <widget class="QDialogButtonBox" name="buttonBox"> | ||||||
|  |      <property name="orientation"> | ||||||
|  |       <enum>Qt::Horizontal</enum> | ||||||
|  |      </property> | ||||||
|  |      <property name="standardButtons"> | ||||||
|  |       <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |    </item> | ||||||
|  |   </layout> | ||||||
|  |  </widget> | ||||||
|  |  <resources/> | ||||||
|  |  <connections> | ||||||
|  |   <connection> | ||||||
|  |    <sender>buttonBox</sender> | ||||||
|  |    <signal>accepted()</signal> | ||||||
|  |    <receiver>ProgressDialog</receiver> | ||||||
|  |    <slot>accept()</slot> | ||||||
|  |    <hints> | ||||||
|  |     <hint type="sourcelabel"> | ||||||
|  |      <x>248</x> | ||||||
|  |      <y>254</y> | ||||||
|  |     </hint> | ||||||
|  |     <hint type="destinationlabel"> | ||||||
|  |      <x>157</x> | ||||||
|  |      <y>274</y> | ||||||
|  |     </hint> | ||||||
|  |    </hints> | ||||||
|  |   </connection> | ||||||
|  |   <connection> | ||||||
|  |    <sender>buttonBox</sender> | ||||||
|  |    <signal>rejected()</signal> | ||||||
|  |    <receiver>ProgressDialog</receiver> | ||||||
|  |    <slot>reject()</slot> | ||||||
|  |    <hints> | ||||||
|  |     <hint type="sourcelabel"> | ||||||
|  |      <x>316</x> | ||||||
|  |      <y>260</y> | ||||||
|  |     </hint> | ||||||
|  |     <hint type="destinationlabel"> | ||||||
|  |      <x>286</x> | ||||||
|  |      <y>274</y> | ||||||
|  |     </hint> | ||||||
|  |    </hints> | ||||||
|  |   </connection> | ||||||
|  |  </connections> | ||||||
|  | </ui> | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat