diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index bda91ef..cd8cfb6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -321,6 +321,22 @@ void CConfigManager::init() { m_config.addSpecialConfigValue("label", "zindex", Hyprlang::INT{0}); SHADOWABLE("label"); + m_config.addSpecialCategory("scale", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true}); + m_config.addSpecialConfigValue("scale", "monitor", Hyprlang::STRING{""}); + m_config.addSpecialConfigValue("scale", "min", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("scale", "max", Hyprlang::INT{100}); + m_config.addSpecialConfigValue("scale", "value", Hyprlang::STRING{""}); + m_config.addSpecialConfigValue("scale", "border_size", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("scale", "border_color", Hyprlang::INT{0xFF000000}); + m_config.addSpecialConfigValue("scale", "rounding", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("scale", "size", LAYOUTCONFIG("100,20")); + m_config.addSpecialConfigValue("scale", "position", LAYOUTCONFIG("0,0")); + m_config.addSpecialConfigValue("scale", "halign", Hyprlang::STRING{"center"}); + m_config.addSpecialConfigValue("scale", "valign", Hyprlang::STRING{"center"}); + m_config.addSpecialConfigValue("scale", "zindex", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("scale", "color", Hyprlang::INT{0xFF00FF00}); + m_config.addSpecialConfigValue("scale", "background_color", Hyprlang::INT{0xFF000000}); + m_config.registerHandler(&::handleSource, "source", {false}); m_config.registerHandler(&::handleBezier, "bezier", {false}); m_config.registerHandler(&::handleAnimation, "animation", {false}); @@ -515,6 +531,31 @@ std::vector CConfigManager::getWidgetConfigs() { // clang-format on } + keys = m_config.listKeysForSpecialCategory("scale"); + for (auto& k : keys) { + // clang-format off + result.push_back(CConfigManager::SWidgetConfig{ + "scale", + std::any_cast(m_config.getSpecialConfigValue("scale", "monitor", k.c_str())), + { + {"min", m_config.getSpecialConfigValue("scale", "min", k.c_str())}, + {"max", m_config.getSpecialConfigValue("scale", "max", k.c_str())}, + {"value", m_config.getSpecialConfigValue("scale", "value", k.c_str())}, + {"border_size", m_config.getSpecialConfigValue("scale", "border_size", k.c_str())}, + {"border_color", m_config.getSpecialConfigValue("scale", "border_color", k.c_str())}, + {"rounding", m_config.getSpecialConfigValue("scale", "rounding", k.c_str())}, + {"size", m_config.getSpecialConfigValue("scale", "size", k.c_str())}, + {"position", m_config.getSpecialConfigValue("scale", "position", k.c_str())}, + {"halign", m_config.getSpecialConfigValue("scale", "halign", k.c_str())}, + {"valign", m_config.getSpecialConfigValue("scale", "valign", k.c_str())}, + {"zindex", m_config.getSpecialConfigValue("scale", "zindex", k.c_str())}, + {"color", m_config.getSpecialConfigValue("scale", "color", k.c_str())}, + {"background_color", m_config.getSpecialConfigValue("scale", "background_color", k.c_str())}, + } + }); + // clang-format on + } + return result; } diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 288ef7d..aba5b37 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -16,6 +16,7 @@ #include "widgets/Label.hpp" #include "widgets/Image.hpp" #include "widgets/Shape.hpp" +#include "widgets/Scale.hpp" inline const float fullVerts[] = { 1, 0, // top right @@ -447,6 +448,8 @@ std::vector>* CRenderer::getOrCreateWidgetsFor(const CS resourceID = "image:" + PATH; widgets[surf].emplace_back(std::make_unique(surf->size, surf->output, resourceID, c.values)); + } else if (c.type == "scale") { + widgets[surf].emplace_back(std::make_unique(surf->size, c.values, surf->output->stringPort)); } } } diff --git a/src/renderer/widgets/Scale.cpp b/src/renderer/widgets/Scale.cpp new file mode 100644 index 0000000..a1ea5f9 --- /dev/null +++ b/src/renderer/widgets/Scale.cpp @@ -0,0 +1,105 @@ +#include "Scale.hpp" +#include "../Renderer.hpp" +#include "../../core/AnimationManager.hpp" +#include "../../helpers/Log.hpp" +#include "../../config/ConfigDataValues.hpp" +#include "../../config/ConfigManager.hpp" +#include "../../core/hyprlock.hpp" +#include + +CScale::~CScale() { + if (valueTimer) { + valueTimer->cancel(); + valueTimer.reset(); + } +} + +static void onTimer(std::shared_ptr self, void* data) { + if (data == nullptr) + return; + + const auto PSCALE = (CScale*)data; + + PSCALE->onTimerUpdate(); + PSCALE->plantTimer(); +} + +void CScale::onTimerUpdate() { + updateValue(); + g_pHyprlock->renderOutput(outputStringPort); +} + +void CScale::plantTimer() { + if (value.updateEveryMs != 0) + valueTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)value.updateEveryMs), onTimer, this, value.allowForceUpdate); + else if (value.updateEveryMs == 0 && value.allowForceUpdate) + valueTimer = g_pHyprlock->addTimer(std::chrono::hours(1), onTimer, this, true); +} + +CScale::CScale(const Vector2D& viewport_, const std::unordered_map& props, const std::string& output) : viewport(viewport_), outputStringPort(output) { + try { + min = std::any_cast(props.at("min")); + max = std::any_cast(props.at("max")); + valuePreFormat = std::any_cast(props.at("value")); + borderSize = std::any_cast(props.at("border_size")); + borderColor = std::any_cast(props.at("border_color")); + rounding = std::any_cast(props.at("rounding")); + configSize = CLayoutValueData::fromAnyPv(props.at("size"))->getAbsolute(viewport_); + configPos = CLayoutValueData::fromAnyPv(props.at("position"))->getAbsolute(viewport_); + halign = std::any_cast(props.at("halign")); + valign = std::any_cast(props.at("valign")); + zindex = std::any_cast(props.at("zindex")); + color = std::any_cast(props.at("color")); + + value = formatString(valuePreFormat); + + backgroundColor = std::any_cast(props.at("background_color")); + + } catch (const std::bad_any_cast& e) { RASSERT(false, "Failed to construct CScale: {}", e.what()); } catch (const std::out_of_range& e) { + RASSERT(false, "Missing property for CScale: {}", e.what()); + } + + pos = posFromHVAlign(viewport, size, configPos, halign, valign); + size = configSize; + + g_pAnimationManager->createAnimation(0.f, animatedValue, g_pConfigManager->m_AnimationTree.getConfig("inputFieldWidth")); + + updateValue(); + + plantTimer(); +} + +void CScale::updateValue() { + int value = getValue(); + if (value < min) + value = min; + else if (value > max) + value = max; + + *animatedValue = static_cast(value - min) / (max - min); +} + +bool CScale::draw(const SRenderData& data) { + CBox box = {pos.x, pos.y, size.x, size.y}; + g_pRenderer->renderRect(box, backgroundColor, rounding); + + CBox progress = {pos.x, pos.y, size.x * animatedValue->value(), size.y}; + g_pRenderer->renderRect(progress, color, rounding); + + if (borderSize > 0) + g_pRenderer->renderBorder(box, borderColor, borderSize, rounding, data.opacity); + + return false; +} + +int CScale::getValue() { + if (value.cmd) { + const auto _value = g_pHyprlock->spawnSync(value.formatted); + if (_value.empty()) + return 0; + else + return std::stoi(_value); + } + + return std::stoi(value.formatted); +} \ No newline at end of file diff --git a/src/renderer/widgets/Scale.hpp b/src/renderer/widgets/Scale.hpp new file mode 100644 index 0000000..779d195 --- /dev/null +++ b/src/renderer/widgets/Scale.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "IWidget.hpp" +#include "../../helpers/Color.hpp" +#include "../../helpers/Math.hpp" +#include "../../helpers/AnimatedVariable.hpp" +#include "../../core/Timer.hpp" +#include +#include +#include + +class CScale : public IWidget { + public: + CScale(const Vector2D& viewport, const std::unordered_map& props, const std::string& output); + ~CScale(); + + virtual bool draw(const SRenderData& data); + + void onTimerUpdate(); + void plantTimer(); + + private: + void updateValue(); + int getValue(); + + std::string valuePreFormat; + IWidget::SFormatResult value; + + std::shared_ptr valueTimer = nullptr; + + Vector2D viewport; + Vector2D pos; + Vector2D size; + Vector2D configPos; + Vector2D configSize; + + std::string halign, valign; + int min, max, borderSize, rounding, zindex; + CHyprColor borderColor, color, backgroundColor; + + std::string outputStringPort; + + PHLANIMVAR animatedValue; +};