Files
hyprland/hyprpm/src/progress/CProgressBar.cpp
s1dd 1c530cbc66 hyprpm: Minor optimizations and refactor of helpers and progress bar (#10246)
* hyprpm: optimize sys.cpp

* hyprpm: refine progress bar logic

* chore: fix fetchSuperuserBins

* chore: modify one line if/else statements

* chore: fix if/else statements

* chore: follow naming convention for const vars

* chore: revert shell escape logic
2025-05-05 04:22:22 +02:00

79 lines
1.9 KiB
C++

#include "CProgressBar.hpp"
#include <sys/ioctl.h>
#include <unistd.h>
#include <cmath>
#include <format>
#include <print>
#include <cstdio>
#include <algorithm>
#include <sstream>
#include "../helpers/Colors.hpp"
static winsize getTerminalSize() {
winsize w{};
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
return w;
}
static void clearCurrentLine() {
std::print("\r\33[2K"); // ansi escape sequence to clear entire line
}
void CProgressBar::printMessageAbove(const std::string& msg) {
clearCurrentLine();
std::print("\r{}\n", msg);
print(); // reprint bar underneath
}
void CProgressBar::print() {
const auto w = getTerminalSize();
if (m_bFirstPrint) {
std::print("\n");
m_bFirstPrint = false;
}
clearCurrentLine();
float percentDone = 0.0f;
if (m_fPercentage >= 0.0f)
percentDone = m_fPercentage;
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 size_t BARWIDTH = std::clamp<size_t>(w.ws_col - m_szCurrentMessage.length() - 2, 0, 50);
std::ostringstream oss;
oss << ' ' << Colors::GREEN;
size_t filled = static_cast<size_t>(std::floor(percentDone * BARWIDTH));
size_t i = 0;
for (; i < filled; ++i)
oss << "";
if (i < BARWIDTH) {
oss << "" << Colors::RESET;
++i;
for (; i < BARWIDTH; ++i)
oss << "";
} else
oss << Colors::RESET;
if (m_fPercentage >= 0.0f)
oss << " " << std::format("{}%", static_cast<int>(percentDone * 100.0)) << ' ';
else
oss << " " << std::format("{} / {}", m_iSteps, m_iMaxSteps) << ' ';
std::print("{} {}", oss.str(), m_szCurrentMessage);
std::fflush(stdout);
}