mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-11-16 23:05:58 +01:00
label: add time and dynamic timers
This commit is contained in:
parent
c60b7b8aef
commit
7370fc624f
9 changed files with 255 additions and 38 deletions
|
@ -4,8 +4,12 @@
|
||||||
#include "../renderer/Renderer.hpp"
|
#include "../renderer/Renderer.hpp"
|
||||||
#include "Password.hpp"
|
#include "Password.hpp"
|
||||||
#include "Egl.hpp"
|
#include "Egl.hpp"
|
||||||
|
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <cuchar>
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
CHyprlock::CHyprlock(const std::string& wlDisplay) {
|
CHyprlock::CHyprlock(const std::string& wlDisplay) {
|
||||||
m_sWaylandState.display = wl_display_connect(wlDisplay.empty() ? nullptr : wlDisplay.c_str());
|
m_sWaylandState.display = wl_display_connect(wlDisplay.empty() ? nullptr : wlDisplay.c_str());
|
||||||
|
@ -110,9 +114,120 @@ void CHyprlock::run() {
|
||||||
|
|
||||||
lockSession();
|
lockSession();
|
||||||
|
|
||||||
while (wl_display_dispatch(m_sWaylandState.display) != -1) {
|
pollfd pollfds[] = {
|
||||||
|
{
|
||||||
|
.fd = wl_display_get_fd(m_sWaylandState.display),
|
||||||
|
.events = POLLIN,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::thread pollThr([this, &pollfds]() {
|
||||||
|
while (1) {
|
||||||
|
int ret = poll(pollfds, 1, 5000 /* 5 seconds, reasonable. It's because we might need to terminate */);
|
||||||
|
if (ret < 0) {
|
||||||
|
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
|
||||||
|
m_bTerminate = true;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
if (pollfds[i].revents & POLLHUP) {
|
||||||
|
Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i);
|
||||||
|
m_bTerminate = true;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_bTerminate)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
Debug::log(TRACE, "[core] got poll event");
|
||||||
|
std::lock_guard<std::mutex> lg2(m_sLoopState.eventLoopMutex);
|
||||||
|
m_sLoopState.event = true;
|
||||||
|
m_sLoopState.loopCV.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread timersThr([this]() {
|
||||||
|
while (1) {
|
||||||
|
// calc nearest thing
|
||||||
|
m_sLoopState.timersMutex.lock();
|
||||||
|
|
||||||
|
float least = 10000;
|
||||||
|
for (auto& t : m_vTimers) {
|
||||||
|
const auto TIME = t->leftMs();
|
||||||
|
if (TIME < least)
|
||||||
|
least = TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sLoopState.timersMutex.unlock();
|
||||||
|
|
||||||
|
std::unique_lock lk(m_sLoopState.timerRequestMutex);
|
||||||
|
m_sLoopState.timerCV.wait_for(lk, std::chrono::milliseconds((int)least + 1), [this] { return m_sLoopState.event; });
|
||||||
|
|
||||||
|
// notify main
|
||||||
|
std::lock_guard<std::mutex> lg2(m_sLoopState.eventLoopMutex);
|
||||||
|
Debug::log(TRACE, "timer thread firing");
|
||||||
|
m_sLoopState.event = true;
|
||||||
|
m_sLoopState.loopCV.notify_all();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_sLoopState.event = true; // let it process once
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
std::unique_lock lk(m_sLoopState.eventRequestMutex);
|
||||||
|
if (m_sLoopState.event == false)
|
||||||
|
m_sLoopState.loopCV.wait(lk, [this] { return m_sLoopState.event; });
|
||||||
|
|
||||||
if (m_bTerminate)
|
if (m_bTerminate)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lg(m_sLoopState.eventLoopMutex);
|
||||||
|
|
||||||
|
m_sLoopState.event = false;
|
||||||
|
|
||||||
|
if (pollfds[0].revents & POLLIN /* dbus */) {
|
||||||
|
Debug::log(TRACE, "got wl event");
|
||||||
|
wl_display_flush(m_sWaylandState.display);
|
||||||
|
if (wl_display_prepare_read(m_sWaylandState.display) == 0) {
|
||||||
|
wl_display_read_events(m_sWaylandState.display);
|
||||||
|
wl_display_dispatch_pending(m_sWaylandState.display);
|
||||||
|
} else {
|
||||||
|
wl_display_dispatch(m_sWaylandState.display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sLoopState.timersMutex.lock();
|
||||||
|
auto timerscpy = m_vTimers;
|
||||||
|
m_sLoopState.timersMutex.unlock();
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<CTimer>> passed;
|
||||||
|
|
||||||
|
for (auto& t : timerscpy) {
|
||||||
|
if (t->passed() && !t->cancelled()) {
|
||||||
|
t->call(t);
|
||||||
|
passed.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->cancelled())
|
||||||
|
passed.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sLoopState.timersMutex.lock();
|
||||||
|
std::erase_if(m_vTimers, [passed](const auto& timer) { return std::find(passed.begin(), passed.end(), timer) != passed.end(); });
|
||||||
|
m_sLoopState.timersMutex.unlock();
|
||||||
|
|
||||||
|
passed.clear();
|
||||||
|
|
||||||
|
// finalize wayland dispatching. Dispatch pending on the queue
|
||||||
|
int ret = 0;
|
||||||
|
do {
|
||||||
|
ret = wl_display_dispatch_pending(m_sWaylandState.display);
|
||||||
|
wl_display_flush(m_sWaylandState.display);
|
||||||
|
} while (ret > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Reached the end, exiting");
|
Debug::log(LOG, "Reached the end, exiting");
|
||||||
|
@ -375,3 +490,8 @@ wp_viewporter* CHyprlock::getViewporter() {
|
||||||
size_t CHyprlock::getPasswordBufferLen() {
|
size_t CHyprlock::getPasswordBufferLen() {
|
||||||
return m_sPasswordState.passBuffer.length();
|
return m_sPasswordState.passBuffer.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CTimer> CHyprlock::addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data) {
|
||||||
|
std::lock_guard<std::mutex> lg(m_sLoopState.timersMutex);
|
||||||
|
return m_vTimers.emplace_back(std::make_shared<CTimer>(timeout, cb_, data));
|
||||||
|
}
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
#include "viewporter-protocol.h"
|
#include "viewporter-protocol.h"
|
||||||
#include "Output.hpp"
|
#include "Output.hpp"
|
||||||
#include "CursorShape.hpp"
|
#include "CursorShape.hpp"
|
||||||
|
#include "Timer.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
@ -21,6 +23,8 @@ class CHyprlock {
|
||||||
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
|
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
|
||||||
void onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
|
void onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
|
||||||
|
|
||||||
|
std::shared_ptr<CTimer> addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(std::shared_ptr<CTimer> self, void* data)> cb_, void* data);
|
||||||
|
|
||||||
void onLockLocked();
|
void onLockLocked();
|
||||||
void onLockFinished();
|
void onLockFinished();
|
||||||
|
|
||||||
|
@ -68,7 +72,20 @@ class CHyprlock {
|
||||||
std::string passBuffer = "";
|
std::string passBuffer = "";
|
||||||
} m_sPasswordState;
|
} m_sPasswordState;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
std::mutex timersMutex;
|
||||||
|
std::mutex eventRequestMutex;
|
||||||
|
std::mutex eventLoopMutex;
|
||||||
|
std::condition_variable loopCV;
|
||||||
|
bool event = false;
|
||||||
|
|
||||||
|
std::condition_variable timerCV;
|
||||||
|
std::mutex timerRequestMutex;
|
||||||
|
} m_sLoopState;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<COutput>> m_vOutputs;
|
std::vector<std::unique_ptr<COutput>> m_vOutputs;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<CTimer>> m_vTimers;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CHyprlock> g_pHyprlock;
|
inline std::unique_ptr<CHyprlock> g_pHyprlock;
|
|
@ -14,8 +14,10 @@ int main(int argc, char** argv, char** envp) {
|
||||||
else if (arg == "--quiet" || arg == "-q")
|
else if (arg == "--quiet" || arg == "-q")
|
||||||
Debug::quiet = true;
|
Debug::quiet = true;
|
||||||
|
|
||||||
else if (arg == "--display" && i + 1 < argc)
|
else if (arg == "--display" && i + 1 < argc) {
|
||||||
wlDisplay = argv[i + 1];
|
wlDisplay = argv[i + 1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -89,12 +89,13 @@ void CAsyncResourceGatherer::apply() {
|
||||||
|
|
||||||
for (auto& t : preloadTargets) {
|
for (auto& t : preloadTargets) {
|
||||||
if (t.type == TARGET_IMAGE) {
|
if (t.type == TARGET_IMAGE) {
|
||||||
const auto ASSET = &assets[t.id];
|
std::lock_guard<std::mutex> lg(asyncLoopState.assetsMutex);
|
||||||
|
const auto ASSET = &assets[t.id];
|
||||||
|
|
||||||
const auto CAIROFORMAT = cairo_image_surface_get_format((cairo_surface_t*)t.cairosurface);
|
const auto CAIROFORMAT = cairo_image_surface_get_format((cairo_surface_t*)t.cairosurface);
|
||||||
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA;
|
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA;
|
||||||
const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
|
const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
|
||||||
const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||||
|
|
||||||
ASSET->texture.m_vSize = t.size;
|
ASSET->texture.m_vSize = t.size;
|
||||||
ASSET->texture.allocate();
|
ASSET->texture.allocate();
|
||||||
|
@ -233,4 +234,10 @@ void CAsyncResourceGatherer::requestAsyncAssetPreload(const SPreloadRequest& req
|
||||||
std::unique_lock lk(cvmtx);
|
std::unique_lock lk(cvmtx);
|
||||||
asyncLoopState.pending = true;
|
asyncLoopState.pending = true;
|
||||||
asyncLoopState.loopGuard.notify_all();
|
asyncLoopState.loopGuard.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAsyncResourceGatherer::unloadAsset(SPreloadedAsset* asset) {
|
||||||
|
std::lock_guard<std::mutex> lg(asyncLoopState.assetsMutex);
|
||||||
|
|
||||||
|
std::erase_if(assets, [asset](const auto& a) { return &a.second == asset; });
|
||||||
}
|
}
|
|
@ -42,6 +42,7 @@ class CAsyncResourceGatherer {
|
||||||
};
|
};
|
||||||
|
|
||||||
void requestAsyncAssetPreload(const SPreloadRequest& request);
|
void requestAsyncAssetPreload(const SPreloadRequest& request);
|
||||||
|
void unloadAsset(SPreloadedAsset* asset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::thread initThread;
|
std::thread initThread;
|
||||||
|
@ -56,6 +57,8 @@ class CAsyncResourceGatherer {
|
||||||
|
|
||||||
std::mutex requestMutex;
|
std::mutex requestMutex;
|
||||||
|
|
||||||
|
std::mutex assetsMutex;
|
||||||
|
|
||||||
std::vector<SPreloadRequest> requests;
|
std::vector<SPreloadRequest> requests;
|
||||||
bool pending = false;
|
bool pending = false;
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ std::vector<std::unique_ptr<IWidget>>* CRenderer::getOrCreateWidgetsFor(const CS
|
||||||
} else if (c.type == "input-field") {
|
} else if (c.type == "input-field") {
|
||||||
widgets[surf].emplace_back(std::make_unique<CPasswordInputField>(surf->size, c.values));
|
widgets[surf].emplace_back(std::make_unique<CPasswordInputField>(surf->size, c.values));
|
||||||
} else if (c.type == "label") {
|
} else if (c.type == "label") {
|
||||||
widgets[surf].emplace_back(std::make_unique<CLabel>(surf->size, c.values));
|
widgets[surf].emplace_back(std::make_unique<CLabel>(surf->size, c.values, /* evil */ const_cast<CSessionLockSurface*>(surf)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,11 @@ class IWidget {
|
||||||
virtual bool draw(const SRenderData& data) = 0;
|
virtual bool draw(const SRenderData& data) = 0;
|
||||||
|
|
||||||
virtual Vector2D posFromHVAlign(const Vector2D& viewport, const Vector2D& size, const Vector2D& offset, const std::string& halign, const std::string& valign);
|
virtual Vector2D posFromHVAlign(const Vector2D& viewport, const Vector2D& size, const Vector2D& offset, const std::string& halign, const std::string& valign);
|
||||||
|
|
||||||
|
struct SFormatResult {
|
||||||
|
std::string formatted;
|
||||||
|
float updateEveryMs = 0; // 0 means don't (static)
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual SFormatResult formatString(std::string in);
|
||||||
};
|
};
|
|
@ -3,32 +3,59 @@
|
||||||
#include <hyprlang.hpp>
|
#include <hyprlang.hpp>
|
||||||
#include "../Renderer.hpp"
|
#include "../Renderer.hpp"
|
||||||
#include "../../helpers/Log.hpp"
|
#include "../../helpers/Log.hpp"
|
||||||
|
#include "../../core/hyprlock.hpp"
|
||||||
|
|
||||||
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
|
CLabel::~CLabel() {
|
||||||
if (from.empty())
|
labelTimer->cancel();
|
||||||
|
labelTimer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onTimer(std::shared_ptr<CTimer> self, void* data) {
|
||||||
|
const auto PLABEL = (CLabel*)data;
|
||||||
|
|
||||||
|
// update label
|
||||||
|
PLABEL->onTimerUpdate();
|
||||||
|
|
||||||
|
// render and replant
|
||||||
|
PLABEL->renderSuper();
|
||||||
|
PLABEL->plantTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLabel::onTimerUpdate() {
|
||||||
|
std::string oldFormatted = label.formatted;
|
||||||
|
|
||||||
|
label = formatString(labelPreFormat);
|
||||||
|
|
||||||
|
if (label.formatted == oldFormatted)
|
||||||
return;
|
return;
|
||||||
size_t pos = 0;
|
|
||||||
while ((pos = str.find(from, pos)) != std::string::npos) {
|
if (!pendingResourceID.empty())
|
||||||
str.replace(pos, from.length(), to);
|
return; // too many updates, we'll miss some. Shouldn't happen tbh
|
||||||
pos += to.length();
|
|
||||||
}
|
// 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;
|
||||||
|
|
||||||
|
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CLabel::formatString(std::string in) {
|
void CLabel::plantTimer() {
|
||||||
replaceAll(in, "$USER", std::string{getlogin()});
|
if (label.updateEveryMs != 0)
|
||||||
return in;
|
labelTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)label.updateEveryMs), onTimer, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props) {
|
CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props, CSessionLockSurface* surface_) : surface(surface_) {
|
||||||
std::string labelPreFormat = std::any_cast<Hyprlang::STRING>(props.at("text"));
|
labelPreFormat = std::any_cast<Hyprlang::STRING>(props.at("text"));
|
||||||
std::string fontFamily = std::any_cast<Hyprlang::STRING>(props.at("font_family"));
|
std::string fontFamily = std::any_cast<Hyprlang::STRING>(props.at("font_family"));
|
||||||
CColor labelColor = std::any_cast<Hyprlang::INT>(props.at("color"));
|
CColor labelColor = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||||
int fontSize = std::any_cast<Hyprlang::INT>(props.at("font_size"));
|
int fontSize = std::any_cast<Hyprlang::INT>(props.at("font_size"));
|
||||||
|
|
||||||
CAsyncResourceGatherer::SPreloadRequest request;
|
label = formatString(labelPreFormat);
|
||||||
request.id = std::string{"label:"} + std::to_string((uintptr_t)this);
|
|
||||||
|
request.id = std::string{"label:"} + std::to_string((uintptr_t)this) + ",time:" + std::to_string(time(nullptr));
|
||||||
resourceID = request.id;
|
resourceID = request.id;
|
||||||
request.asset = formatString(labelPreFormat);
|
request.asset = label.formatted;
|
||||||
request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT;
|
request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT;
|
||||||
request.props["font_family"] = fontFamily;
|
request.props["font_family"] = fontFamily;
|
||||||
request.props["color"] = labelColor;
|
request.props["color"] = labelColor;
|
||||||
|
@ -38,12 +65,14 @@ CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string,
|
||||||
|
|
||||||
auto POS__ = std::any_cast<Hyprlang::VEC2>(props.at("position"));
|
auto POS__ = std::any_cast<Hyprlang::VEC2>(props.at("position"));
|
||||||
pos = {POS__.x, POS__.y};
|
pos = {POS__.x, POS__.y};
|
||||||
|
configPos = pos;
|
||||||
|
|
||||||
viewport = viewport_;
|
viewport = viewport_;
|
||||||
label = request.asset;
|
|
||||||
|
|
||||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||||
|
|
||||||
|
plantTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CLabel::draw(const SRenderData& data) {
|
bool CLabel::draw(const SRenderData& data) {
|
||||||
|
@ -54,7 +83,20 @@ bool CLabel::draw(const SRenderData& data) {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// calc pos
|
// calc pos
|
||||||
pos = posFromHVAlign(viewport, asset->texture.m_vSize, pos, halign, valign);
|
pos = posFromHVAlign(viewport, asset->texture.m_vSize, configPos, halign, valign);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CBox box = {pos.x, pos.y, asset->texture.m_vSize.x, asset->texture.m_vSize.y};
|
CBox box = {pos.x, pos.y, asset->texture.m_vSize.x, asset->texture.m_vSize.y};
|
||||||
|
@ -62,4 +104,8 @@ bool CLabel::draw(const SRenderData& data) {
|
||||||
g_pRenderer->renderTexture(box, asset->texture, data.opacity);
|
g_pRenderer->renderTexture(box, asset->texture, data.opacity);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLabel::renderSuper() {
|
||||||
|
surface->render();
|
||||||
}
|
}
|
|
@ -2,25 +2,40 @@
|
||||||
|
|
||||||
#include "IWidget.hpp"
|
#include "IWidget.hpp"
|
||||||
#include "../../helpers/Vector2D.hpp"
|
#include "../../helpers/Vector2D.hpp"
|
||||||
|
#include "../../core/Timer.hpp"
|
||||||
|
#include "../AsyncResourceGatherer.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <any>
|
#include <any>
|
||||||
|
|
||||||
struct SPreloadedAsset;
|
struct SPreloadedAsset;
|
||||||
|
class CSessionLockSurface;
|
||||||
|
|
||||||
class CLabel : public IWidget {
|
class CLabel : public IWidget {
|
||||||
public:
|
public:
|
||||||
CLabel(const Vector2D& viewport, const std::unordered_map<std::string, std::any>& props);
|
CLabel(const Vector2D& viewport, const std::unordered_map<std::string, std::any>& props, CSessionLockSurface* surface_);
|
||||||
|
~CLabel();
|
||||||
|
|
||||||
virtual bool draw(const SRenderData& data);
|
virtual bool draw(const SRenderData& data);
|
||||||
|
|
||||||
private:
|
void renderSuper();
|
||||||
std::string formatString(std::string in);
|
void onTimerUpdate();
|
||||||
|
void plantTimer();
|
||||||
|
|
||||||
Vector2D viewport;
|
private:
|
||||||
Vector2D pos;
|
std::string labelPreFormat;
|
||||||
std::string resourceID;
|
IWidget::SFormatResult label;
|
||||||
std::string label;
|
|
||||||
std::string halign, valign;
|
Vector2D viewport;
|
||||||
SPreloadedAsset* asset = nullptr;
|
Vector2D pos;
|
||||||
|
Vector2D configPos;
|
||||||
|
std::string resourceID;
|
||||||
|
std::string pendingResourceID; // if dynamic label
|
||||||
|
std::string halign, valign;
|
||||||
|
SPreloadedAsset* asset = nullptr;
|
||||||
|
CSessionLockSurface* surface = nullptr;
|
||||||
|
|
||||||
|
CAsyncResourceGatherer::SPreloadRequest request;
|
||||||
|
|
||||||
|
std::shared_ptr<CTimer> labelTimer;
|
||||||
};
|
};
|
Loading…
Reference in a new issue