mirror of
https://github.com/hyprwm/hyprlock.git
synced 2025-01-26 04:19:48 +01:00
widgets: add scale widget implementation
- config: introduce special category and config values for scale - renderer: integrate scale widget into widget creation - scale: implement CScale class with drawing and timer functionality
This commit is contained in:
parent
742eb98c6a
commit
2f51092152
4 changed files with 193 additions and 0 deletions
|
@ -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::SWidgetConfig> 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<Hyprlang::STRING>(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<std::unique_ptr<IWidget>>* CRenderer::getOrCreateWidgetsFor(const CS
|
|||
resourceID = "image:" + PATH;
|
||||
|
||||
widgets[surf].emplace_back(std::make_unique<CImage>(surf->size, surf->output, resourceID, c.values));
|
||||
} else if (c.type == "scale") {
|
||||
widgets[surf].emplace_back(std::make_unique<CScale>(surf->size, c.values, surf->output->stringPort));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
105
src/renderer/widgets/Scale.cpp
Normal file
105
src/renderer/widgets/Scale.cpp
Normal file
|
@ -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 <hyprlang.hpp>
|
||||
|
||||
CScale::~CScale() {
|
||||
if (valueTimer) {
|
||||
valueTimer->cancel();
|
||||
valueTimer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void onTimer(std::shared_ptr<CTimer> 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<std::string, std::any>& props, const std::string& output) : viewport(viewport_), outputStringPort(output) {
|
||||
try {
|
||||
min = std::any_cast<Hyprlang::INT>(props.at("min"));
|
||||
max = std::any_cast<Hyprlang::INT>(props.at("max"));
|
||||
valuePreFormat = std::any_cast<Hyprlang::STRING>(props.at("value"));
|
||||
borderSize = std::any_cast<Hyprlang::INT>(props.at("border_size"));
|
||||
borderColor = std::any_cast<Hyprlang::INT>(props.at("border_color"));
|
||||
rounding = std::any_cast<Hyprlang::INT>(props.at("rounding"));
|
||||
configSize = CLayoutValueData::fromAnyPv(props.at("size"))->getAbsolute(viewport_);
|
||||
configPos = CLayoutValueData::fromAnyPv(props.at("position"))->getAbsolute(viewport_);
|
||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||
zindex = std::any_cast<Hyprlang::INT>(props.at("zindex"));
|
||||
color = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||
|
||||
value = formatString(valuePreFormat);
|
||||
|
||||
backgroundColor = std::any_cast<Hyprlang::INT>(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<float>(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);
|
||||
}
|
44
src/renderer/widgets/Scale.hpp
Normal file
44
src/renderer/widgets/Scale.hpp
Normal file
|
@ -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 <string>
|
||||
#include <unordered_map>
|
||||
#include <any>
|
||||
|
||||
class CScale : public IWidget {
|
||||
public:
|
||||
CScale(const Vector2D& viewport, const std::unordered_map<std::string, std::any>& 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<CTimer> 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<float> animatedValue;
|
||||
};
|
Loading…
Reference in a new issue