#include "Label.hpp" #include "../../helpers/Color.hpp" #include #include "../Renderer.hpp" #include "../../helpers/Log.hpp" #include "../../core/hyprlock.hpp" CLabel::~CLabel() { labelTimer->cancel(); labelTimer.reset(); } static void onTimer(std::shared_ptr self, void* data) { const auto PLABEL = (CLabel*)data; // update label PLABEL->onTimerUpdate(); // plant new timer PLABEL->plantTimer(); } static void onAssetCallback(void* data) { const auto PLABEL = (CLabel*)data; PLABEL->renderSuper(); } void CLabel::onTimerUpdate() { std::string oldFormatted = label.formatted; label = formatString(labelPreFormat); if (label.formatted == oldFormatted && !label.alwaysUpdate) return; if (!pendingResourceID.empty()) return; // too many updates, we'll miss some. Shouldn't happen tbh // request new request.id = std::string{"label:"} + std::to_string((uintptr_t)this) + ",time:" + std::to_string(time(nullptr)); pendingResourceID = request.id; request.asset = label.formatted; request.callback = onAssetCallback; request.callbackData = this; g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); } void CLabel::plantTimer() { if (label.updateEveryMs != 0) labelTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)label.updateEveryMs), onTimer, this); } CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map& props, CSessionLockSurface* surface_) : surface(surface_), shadow(this, props, viewport_) { labelPreFormat = std::any_cast(props.at("text")); std::string fontFamily = std::any_cast(props.at("font_family")); CColor labelColor = std::any_cast(props.at("color")); int fontSize = std::any_cast(props.at("font_size")); label = formatString(labelPreFormat); request.id = std::string{"label:"} + std::to_string((uintptr_t)this) + ",time:" + std::to_string(time(nullptr)); resourceID = request.id; request.asset = label.formatted; request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT; request.props["font_family"] = fontFamily; request.props["color"] = labelColor; request.props["font_size"] = fontSize; request.props["cmd"] = label.cmd; g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); auto POS__ = std::any_cast(props.at("position")); pos = {POS__.x, POS__.y}; configPos = pos; viewport = viewport_; halign = std::any_cast(props.at("halign")); valign = std::any_cast(props.at("valign")); plantTimer(); } bool CLabel::draw(const SRenderData& data) { if (!asset) { asset = g_pRenderer->asyncResourceGatherer->getAssetByID(resourceID); if (!asset) return true; // calc pos pos = posFromHVAlign(viewport, asset->texture.m_vSize, configPos, halign, valign); shadow.markShadowDirty(); } if (!pendingResourceID.empty()) { // new asset is pending auto newAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(pendingResourceID); if (newAsset) { // new asset is ready :D g_pRenderer->asyncResourceGatherer->unloadAsset(asset); asset = newAsset; resourceID = pendingResourceID; pendingResourceID = ""; pos = posFromHVAlign(viewport, asset->texture.m_vSize, configPos, halign, valign); shadow.markShadowDirty(); } } CBox box = {pos.x, pos.y, asset->texture.m_vSize.x, asset->texture.m_vSize.y}; shadow.draw(data); g_pRenderer->renderTexture(box, asset->texture, data.opacity); return false; } void CLabel::renderSuper() { surface->render(); }