summaryrefslogtreecommitdiff
path: root/hyprpm/src/progress/CProgressBar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hyprpm/src/progress/CProgressBar.cpp')
-rw-r--r--hyprpm/src/progress/CProgressBar.cpp96
1 files changed, 46 insertions, 50 deletions
diff --git a/hyprpm/src/progress/CProgressBar.cpp b/hyprpm/src/progress/CProgressBar.cpp
index 9f2df08a..819a3f4f 100644
--- a/hyprpm/src/progress/CProgressBar.cpp
+++ b/hyprpm/src/progress/CProgressBar.cpp
@@ -1,82 +1,78 @@
#include "CProgressBar.hpp"
#include <sys/ioctl.h>
-#include <algorithm>
+#include <unistd.h>
#include <cmath>
#include <format>
-
#include <print>
-#include <stdio.h>
-#include <unistd.h>
+#include <cstdio>
+
+#include <algorithm>
+#include <sstream>
#include "../helpers/Colors.hpp"
-void CProgressBar::printMessageAbove(const std::string& msg) {
- struct winsize w;
+static winsize getTerminalSize() {
+ winsize w{};
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+ return w;
+}
- std::string spaces;
- spaces.reserve(w.ws_col);
- for (size_t i = 0; i < w.ws_col; ++i) {
- spaces += ' ';
- }
+static void clearCurrentLine() {
+ std::print("\r\33[2K"); // ansi escape sequence to clear entire line
+}
- std::println("\r{}\r{}", spaces, msg);
- print();
+void CProgressBar::printMessageAbove(const std::string& msg) {
+ clearCurrentLine();
+ std::print("\r{}\n", msg);
+
+ print(); // reprint bar underneath
}
void CProgressBar::print() {
- struct winsize w;
- ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+ const auto w = getTerminalSize();
- if (m_bFirstPrint)
+ if (m_bFirstPrint) {
std::print("\n");
- m_bFirstPrint = false;
-
- std::string spaces;
- spaces.reserve(w.ws_col);
- for (size_t i = 0; i < w.ws_col; ++i) {
- spaces += ' ';
+ m_bFirstPrint = false;
}
- std::print("\r{}\r", spaces);
+ clearCurrentLine();
- std::string message = "";
-
- float percentDone = 0;
- if (m_fPercentage >= 0)
+ float percentDone = 0.0f;
+ if (m_fPercentage >= 0.0f)
percentDone = m_fPercentage;
- else
- percentDone = (float)m_iSteps / (float)m_iMaxSteps;
+ else {
+ // check for divide-by-zero
+ percentDone = m_iMaxSteps > 0 ? static_cast<float>(m_iSteps) / m_iMaxSteps : 0.0f;
+ }
+ // clamp to ensure no overflows (sanity check)
+ percentDone = std::clamp(percentDone, 0.0f, 1.0f);
- const auto BARWIDTH = std::clamp(w.ws_col - static_cast<unsigned long>(m_szCurrentMessage.length()) - 2, 0UL, 50UL);
+ const size_t BARWIDTH = std::clamp<size_t>(w.ws_col - m_szCurrentMessage.length() - 2, 0, 50);
- // draw bar
- message += std::string{" "} + Colors::GREEN;
- size_t i = 0;
- for (; i < std::floor(percentDone * BARWIDTH); ++i) {
- message += "━";
- }
+ std::ostringstream oss;
+ oss << ' ' << Colors::GREEN;
- if (i < BARWIDTH) {
- i++;
+ size_t filled = static_cast<size_t>(std::floor(percentDone * BARWIDTH));
+ size_t i = 0;
- message += std::string{"╍"} + Colors::RESET;
+ for (; i < filled; ++i)
+ oss << "━";
- for (; i < BARWIDTH; ++i) {
- message += "━";
- }
+ if (i < BARWIDTH) {
+ oss << "╍" << Colors::RESET;
+ ++i;
+ for (; i < BARWIDTH; ++i)
+ oss << "━";
} else
- message += Colors::RESET;
+ oss << Colors::RESET;
- // draw progress
- if (m_fPercentage >= 0)
- message += " " + std::format("{}%", static_cast<int>(percentDone * 100.0)) + " ";
+ if (m_fPercentage >= 0.0f)
+ oss << " " << std::format("{}%", static_cast<int>(percentDone * 100.0)) << ' ';
else
- message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
-
- // draw message
- std::print("{} {}", message, m_szCurrentMessage);
+ oss << " " << std::format("{} / {}", m_iSteps, m_iMaxSteps) << ' ';
+ std::print("{} {}", oss.str(), m_szCurrentMessage);
std::fflush(stdout);
}