reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

progress.cpp (2535B)


      1 /* ReaPack: Package manager for REAPER
      2  * Copyright (C) 2015-2025  Christian Fillion
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU Lesser General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU Lesser General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Lesser General Public License
     15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16  */
     17 
     18 #include "progress.hpp"
     19 
     20 #include "resource.hpp"
     21 #include "win32.hpp"
     22 
     23 #include <sstream>
     24 
     25 Progress::Progress(ThreadPool *pool)
     26   : Dialog(IDD_PROGRESS_DIALOG),
     27     m_pool(pool), m_current(), m_label(nullptr), m_progress(nullptr),
     28     m_done(0), m_total(0)
     29 {
     30   m_pool->onPush >> std::bind(&Progress::addTask, this, std::placeholders::_1);
     31 }
     32 
     33 void Progress::onInit()
     34 {
     35   Dialog::onInit();
     36 
     37   m_label = getControl(IDC_LABEL);
     38   m_progress = getControl(IDC_PROGRESS);
     39 
     40   Win32::setWindowText(m_label, "Initializing...");
     41 }
     42 
     43 void Progress::onCommand(const int id, int)
     44 {
     45   switch(id) {
     46   case IDCANCEL:
     47     m_pool->abort();
     48 
     49     // don't wait until the current downloads are finished
     50     // before getting out of the user way
     51     hide();
     52     break;
     53   }
     54 }
     55 
     56 void Progress::onTimer(const int id)
     57 {
     58 #ifdef _WIN32
     59   if(!IsWindowEnabled(handle()))
     60     return;
     61 #endif
     62 
     63   show();
     64   stopTimer(id);
     65 }
     66 
     67 void Progress::addTask(ThreadTask *task)
     68 {
     69   m_total++;
     70   if(m_current.step)
     71     updateProgress();
     72 
     73   if(!isVisible())
     74     startTimer(100);
     75 
     76   task->onStartAsync >> [=] {
     77     m_current = task->summary();
     78     updateProgress();
     79   };
     80 
     81   task->onFinishAsync >> [=] {
     82     m_done++;
     83     updateProgress();
     84   };
     85 }
     86 
     87 void Progress::updateProgress()
     88 {
     89   Win32::setWindowText(m_label, String::format("%s %s of %s: %s",
     90     m_current.step,
     91     String::number(std::min(m_done + 1, m_total)).c_str(),
     92     String::number(m_total).c_str(),
     93     m_current.item.c_str()
     94   ).c_str());
     95 
     96   const double pos = static_cast<double>(
     97     std::min(m_done + 1, m_total)) / std::max(2, m_total);
     98   const int percent = static_cast<int>(pos * 100);
     99 
    100   SendMessage(m_progress, PBM_SETPOS, percent, 0);
    101   Win32::setWindowText(handle(), String::format(
    102     "ReaPack: Operation in progress (%d%%)", percent
    103   ).c_str());
    104 }