mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-11-16 23:05:58 +01:00
widgets: add support for specifing size and position options via percentages of output dimensions (#541)
* config: introduce a custom value type for layout related options * widgets: use CLayoutValueData for size and position options * widgets: catch bad_any_cast and out_of_range when contructing widgets other than label * config: rename and restrict CLayoutValueData::fromAny to fromAnyPv This is only for casting `any` variables that represent a void * to a CLayoutValueData*, not just any any. * misc: remove debug prints
This commit is contained in:
parent
1cd3231537
commit
4fc133c96f
7 changed files with 200 additions and 90 deletions
53
src/config/ConfigDataValues.hpp
Normal file
53
src/config/ConfigDataValues.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
#include "../helpers/Log.hpp"
|
||||
#include <hyprutils/math/Vector2D.hpp>
|
||||
#include <any>
|
||||
#include <string>
|
||||
|
||||
enum eConfigValueDataTypes {
|
||||
CVD_TYPE_INVALID = -1,
|
||||
CVD_TYPE_LAYOUT = 0,
|
||||
};
|
||||
|
||||
class ICustomConfigValueData {
|
||||
public:
|
||||
virtual ~ICustomConfigValueData() = 0;
|
||||
|
||||
virtual eConfigValueDataTypes getDataType() = 0;
|
||||
|
||||
virtual std::string toString() = 0;
|
||||
};
|
||||
|
||||
class CLayoutValueData : public ICustomConfigValueData {
|
||||
public:
|
||||
CLayoutValueData() {};
|
||||
virtual ~CLayoutValueData() {};
|
||||
|
||||
virtual eConfigValueDataTypes getDataType() {
|
||||
return CVD_TYPE_LAYOUT;
|
||||
}
|
||||
|
||||
virtual std::string toString() {
|
||||
return std::format("{}{},{}{}", m_vValues.x, (m_sIsRelative.x) ? "%" : "px", m_vValues.y, (m_sIsRelative.y) ? "%" : "px");
|
||||
}
|
||||
|
||||
static CLayoutValueData* fromAnyPv(const std::any& v) {
|
||||
RASSERT(v.type() == typeid(void*), "Invalid config value type");
|
||||
const auto P = (CLayoutValueData*)std::any_cast<void*>(v);
|
||||
RASSERT(P, "Empty config value");
|
||||
return P;
|
||||
}
|
||||
|
||||
Hyprutils::Math::Vector2D getAbsolute(const Hyprutils::Math::Vector2D& viewport) {
|
||||
return {
|
||||
(m_sIsRelative.x ? (m_vValues.x / 100) * viewport.x : m_vValues.x),
|
||||
(m_sIsRelative.y ? (m_vValues.y / 100) * viewport.y : m_vValues.y),
|
||||
};
|
||||
}
|
||||
|
||||
Hyprutils::Math::Vector2D m_vValues;
|
||||
struct {
|
||||
bool x = false;
|
||||
bool y = false;
|
||||
} m_sIsRelative;
|
||||
};
|
|
@ -1,12 +1,17 @@
|
|||
#include "ConfigManager.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include "../helpers/Log.hpp"
|
||||
#include "../config/ConfigDataValues.hpp"
|
||||
#include <hyprutils/path/Path.hpp>
|
||||
#include <filesystem>
|
||||
#include <glob.h>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
|
||||
ICustomConfigValueData::~ICustomConfigValueData() {
|
||||
; // empty
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleSource(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
@ -19,6 +24,51 @@ static Hyprlang::CParseResult handleSource(const char* c, const char* v) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult configHandleLayoutOption(const char* v, void** data) {
|
||||
const std::string VALUE = v;
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
|
||||
if (!*data)
|
||||
*data = new CLayoutValueData();
|
||||
|
||||
const auto DATA = (CLayoutValueData*)(*data);
|
||||
const auto SPLIT = VALUE.find(',');
|
||||
if (SPLIT == std::string::npos) {
|
||||
result.setError(std::format("expected two comma seperated values, got {}", VALUE).c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
auto lhs = VALUE.substr(0, SPLIT);
|
||||
auto rhs = VALUE.substr(SPLIT + 1);
|
||||
if (rhs.starts_with(" "))
|
||||
rhs = rhs.substr(1);
|
||||
|
||||
if (lhs.contains(",") || rhs.contains(",")) {
|
||||
result.setError(std::format("too many arguments in {}", VALUE).c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (lhs.ends_with("%")) {
|
||||
DATA->m_sIsRelative.x = true;
|
||||
lhs.pop_back();
|
||||
}
|
||||
|
||||
if (rhs.ends_with("%")) {
|
||||
DATA->m_sIsRelative.y = true;
|
||||
rhs.pop_back();
|
||||
}
|
||||
|
||||
DATA->m_vValues = Hyprutils::Math::Vector2D{std::stof(lhs), std::stof(rhs)};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void configHandleLayoutOptionDestroy(void** data) {
|
||||
if (*data)
|
||||
delete reinterpret_cast<CLayoutValueData*>(*data);
|
||||
}
|
||||
|
||||
static std::string getMainConfigPath() {
|
||||
static const auto paths = Hyprutils::Path::findConfig("hyprlock");
|
||||
if (paths.first.has_value())
|
||||
|
@ -39,7 +89,6 @@ void CConfigManager::init() {
|
|||
m_config.addSpecialConfigValue(name, "shadow_passes", Hyprlang::INT{0}); \
|
||||
m_config.addSpecialConfigValue(name, "shadow_color", Hyprlang::INT{0xFF000000}); \
|
||||
m_config.addSpecialConfigValue(name, "shadow_boost", Hyprlang::FLOAT{1.2});
|
||||
|
||||
m_config.addConfigValue("general:disable_loading_bar", Hyprlang::INT{0});
|
||||
m_config.addConfigValue("general:text_trim", Hyprlang::INT{1});
|
||||
m_config.addConfigValue("general:hide_cursor", Hyprlang::INT{0});
|
||||
|
@ -69,12 +118,12 @@ void CConfigManager::init() {
|
|||
|
||||
m_config.addSpecialCategory("shape", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
||||
m_config.addSpecialConfigValue("shape", "monitor", Hyprlang::STRING{""});
|
||||
m_config.addSpecialConfigValue("shape", "size", Hyprlang::VEC2{100, 100});
|
||||
m_config.addSpecialConfigValue("shape", "size", Hyprlang::CUSTOMTYPE{&configHandleLayoutOption, configHandleLayoutOptionDestroy, "100,100"});
|
||||
m_config.addSpecialConfigValue("shape", "rounding", Hyprlang::INT{0});
|
||||
m_config.addSpecialConfigValue("shape", "border_size", Hyprlang::INT{0});
|
||||
m_config.addSpecialConfigValue("shape", "border_color", Hyprlang::INT{0xFF00CFE6});
|
||||
m_config.addSpecialConfigValue("shape", "color", Hyprlang::INT{0xFF111111});
|
||||
m_config.addSpecialConfigValue("shape", "position", Hyprlang::VEC2{0, 0});
|
||||
m_config.addSpecialConfigValue("shape", "position", Hyprlang::CUSTOMTYPE{&configHandleLayoutOption, configHandleLayoutOptionDestroy, "0,0"});
|
||||
m_config.addSpecialConfigValue("shape", "halign", Hyprlang::STRING{"center"});
|
||||
m_config.addSpecialConfigValue("shape", "valign", Hyprlang::STRING{"center"});
|
||||
m_config.addSpecialConfigValue("shape", "rotate", Hyprlang::FLOAT{0});
|
||||
|
@ -89,7 +138,7 @@ void CConfigManager::init() {
|
|||
m_config.addSpecialConfigValue("image", "rounding", Hyprlang::INT{-1});
|
||||
m_config.addSpecialConfigValue("image", "border_size", Hyprlang::INT{4});
|
||||
m_config.addSpecialConfigValue("image", "border_color", Hyprlang::INT{0xFFDDDDDD});
|
||||
m_config.addSpecialConfigValue("image", "position", Hyprlang::VEC2{0, 0});
|
||||
m_config.addSpecialConfigValue("image", "position", Hyprlang::CUSTOMTYPE{&configHandleLayoutOption, configHandleLayoutOptionDestroy, "0,0"});
|
||||
m_config.addSpecialConfigValue("image", "halign", Hyprlang::STRING{"center"});
|
||||
m_config.addSpecialConfigValue("image", "valign", Hyprlang::STRING{"center"});
|
||||
m_config.addSpecialConfigValue("image", "rotate", Hyprlang::FLOAT{0});
|
||||
|
@ -100,7 +149,7 @@ void CConfigManager::init() {
|
|||
|
||||
m_config.addSpecialCategory("input-field", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
||||
m_config.addSpecialConfigValue("input-field", "monitor", Hyprlang::STRING{""});
|
||||
m_config.addSpecialConfigValue("input-field", "size", Hyprlang::VEC2{400, 90});
|
||||
m_config.addSpecialConfigValue("input-field", "size", Hyprlang::CUSTOMTYPE{&configHandleLayoutOption, configHandleLayoutOptionDestroy, "400,90"});
|
||||
m_config.addSpecialConfigValue("input-field", "inner_color", Hyprlang::INT{0xFFDDDDDD});
|
||||
m_config.addSpecialConfigValue("input-field", "outer_color", Hyprlang::INT{0xFF111111});
|
||||
m_config.addSpecialConfigValue("input-field", "outline_thickness", Hyprlang::INT{4});
|
||||
|
@ -116,7 +165,7 @@ void CConfigManager::init() {
|
|||
m_config.addSpecialConfigValue("input-field", "font_family", Hyprlang::STRING{"Sans"});
|
||||
m_config.addSpecialConfigValue("input-field", "halign", Hyprlang::STRING{"center"});
|
||||
m_config.addSpecialConfigValue("input-field", "valign", Hyprlang::STRING{"center"});
|
||||
m_config.addSpecialConfigValue("input-field", "position", Hyprlang::VEC2{0, 0});
|
||||
m_config.addSpecialConfigValue("input-field", "position", Hyprlang::CUSTOMTYPE{&configHandleLayoutOption, configHandleLayoutOptionDestroy, "0,0"});
|
||||
m_config.addSpecialConfigValue("input-field", "placeholder_text", Hyprlang::STRING{"<i>Input Password</i>"});
|
||||
m_config.addSpecialConfigValue("input-field", "hide_input", Hyprlang::INT{0});
|
||||
m_config.addSpecialConfigValue("input-field", "rounding", Hyprlang::INT{-1});
|
||||
|
@ -135,7 +184,7 @@ void CConfigManager::init() {
|
|||
|
||||
m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
||||
m_config.addSpecialConfigValue("label", "monitor", Hyprlang::STRING{""});
|
||||
m_config.addSpecialConfigValue("label", "position", Hyprlang::VEC2{0, 0});
|
||||
m_config.addSpecialConfigValue("label", "position", Hyprlang::CUSTOMTYPE{&configHandleLayoutOption, configHandleLayoutOptionDestroy, "0,0"});
|
||||
m_config.addSpecialConfigValue("label", "color", Hyprlang::INT{0xFFFFFFFF});
|
||||
m_config.addSpecialConfigValue("label", "font_size", Hyprlang::INT{16});
|
||||
m_config.addSpecialConfigValue("label", "text", Hyprlang::STRING{"Sample Text"});
|
||||
|
|
|
@ -5,8 +5,3 @@
|
|||
#include <hyprutils/math/Vector2D.hpp>
|
||||
|
||||
std::string absolutePath(const std::string&, const std::string&);
|
||||
|
||||
//
|
||||
inline Hyprutils::Math::Vector2D Vector2DFromHyprlang(const Hyprlang::VEC2& vec) {
|
||||
return Hyprutils::Math::Vector2D{vec.x, vec.y};
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "../Renderer.hpp"
|
||||
#include "../../core/hyprlock.hpp"
|
||||
#include "../../helpers/Log.hpp"
|
||||
#include "../../helpers/MiscFunctions.hpp"
|
||||
#include "../../config/ConfigDataValues.hpp"
|
||||
#include <cmath>
|
||||
#include <hyprlang.hpp>
|
||||
|
||||
|
@ -82,11 +82,12 @@ void CImage::plantTimer() {
|
|||
CImage::CImage(const Vector2D& viewport_, COutput* output_, const std::string& resourceID_, const std::unordered_map<std::string, std::any>& props) :
|
||||
viewport(viewport_), resourceID(resourceID_), output(output_), shadow(this, props, viewport_) {
|
||||
|
||||
try {
|
||||
size = std::any_cast<Hyprlang::INT>(props.at("size"));
|
||||
rounding = std::any_cast<Hyprlang::INT>(props.at("rounding"));
|
||||
border = std::any_cast<Hyprlang::INT>(props.at("border_size"));
|
||||
color = std::any_cast<Hyprlang::INT>(props.at("border_color"));
|
||||
pos = Vector2DFromHyprlang(std::any_cast<Hyprlang::VEC2>(props.at("position")));
|
||||
pos = 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"));
|
||||
angle = std::any_cast<Hyprlang::FLOAT>(props.at("rotate"));
|
||||
|
@ -94,6 +95,11 @@ CImage::CImage(const Vector2D& viewport_, COutput* output_, const std::string& r
|
|||
path = std::any_cast<Hyprlang::STRING>(props.at("path"));
|
||||
reloadTime = std::any_cast<Hyprlang::INT>(props.at("reload_time"));
|
||||
reloadCommand = std::any_cast<Hyprlang::STRING>(props.at("reload_cmd"));
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
RASSERT(false, "Failed to construct CImage: {}", e.what()); //
|
||||
} catch (const std::out_of_range& e) {
|
||||
RASSERT(false, "Missing propperty for CImage: {}", e.what()); //
|
||||
}
|
||||
|
||||
try {
|
||||
modificationTime = std::filesystem::last_write_time(path);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "../../helpers/Log.hpp"
|
||||
#include "../../core/hyprlock.hpp"
|
||||
#include "../../helpers/Color.hpp"
|
||||
#include "../../helpers/MiscFunctions.hpp"
|
||||
#include "../../config/ConfigDataValues.hpp"
|
||||
#include <hyprlang.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -73,7 +73,13 @@ void CLabel::plantTimer() {
|
|||
CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props, const std::string& output) :
|
||||
outputStringPort(output), shadow(this, props, viewport_) {
|
||||
try {
|
||||
pos = CLayoutValueData::fromAnyPv(props.at("position"))->getAbsolute(viewport_);
|
||||
labelPreFormat = std::any_cast<Hyprlang::STRING>(props.at("text"));
|
||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||
angle = std::any_cast<Hyprlang::FLOAT>(props.at("rotate"));
|
||||
angle = angle * M_PI / 180.0;
|
||||
|
||||
std::string textAlign = std::any_cast<Hyprlang::STRING>(props.at("text_align"));
|
||||
std::string fontFamily = std::any_cast<Hyprlang::STRING>(props.at("font_family"));
|
||||
CColor labelColor = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||
|
@ -93,27 +99,18 @@ CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string,
|
|||
if (!textAlign.empty())
|
||||
request.props["text_align"] = textAlign;
|
||||
|
||||
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
RASSERT(false, "Failed to construct CLabel: {}", e.what()); //
|
||||
} catch (const std::out_of_range& e) {
|
||||
RASSERT(false, "Missing property for CLabel: {}", e.what()); //
|
||||
}
|
||||
|
||||
pos = Vector2DFromHyprlang(std::any_cast<Hyprlang::VEC2>(props.at("position")));
|
||||
configPos = pos;
|
||||
|
||||
viewport = viewport_;
|
||||
|
||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||
|
||||
angle = std::any_cast<Hyprlang::FLOAT>(props.at("rotate"));
|
||||
angle = angle * M_PI / 180.0;
|
||||
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
||||
|
||||
plantTimer();
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
Debug::log(ERR, "Failed to construct CLabel: {}", e.what());
|
||||
throw;
|
||||
} catch (const std::out_of_range& e) {
|
||||
Debug::log(ERR, "Missing propperty for CLabel:{}", e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
bool CLabel::draw(const SRenderData& data) {
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#include "../Renderer.hpp"
|
||||
#include "../../core/hyprlock.hpp"
|
||||
#include "../../core/Auth.hpp"
|
||||
#include "../../helpers/MiscFunctions.hpp"
|
||||
#include "../../config/ConfigDataValues.hpp"
|
||||
#include "../../helpers/Log.hpp"
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <algorithm>
|
||||
#include <hyprlang.hpp>
|
||||
|
@ -10,8 +11,12 @@
|
|||
using namespace Hyprutils::String;
|
||||
|
||||
CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props, const std::string& output) :
|
||||
outputStringPort(output), shadow(this, props, viewport_) {
|
||||
size = Vector2DFromHyprlang(std::any_cast<Hyprlang::VEC2>(props.at("size")));
|
||||
viewport(viewport_), outputStringPort(output), shadow(this, props, viewport_) {
|
||||
try {
|
||||
pos = CLayoutValueData::fromAnyPv(props.at("position"))->getAbsolute(viewport_);
|
||||
size = CLayoutValueData::fromAnyPv(props.at("size"))->getAbsolute(viewport_);
|
||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||
outThick = std::any_cast<Hyprlang::INT>(props.at("outline_thickness"));
|
||||
dots.size = std::any_cast<Hyprlang::FLOAT>(props.at("dots_size"));
|
||||
dots.spacing = std::any_cast<Hyprlang::FLOAT>(props.at("dots_spacing"));
|
||||
|
@ -38,16 +43,15 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
|
|||
colorConfig.num = std::any_cast<Hyprlang::INT>(props.at("numlock_color"));
|
||||
colorConfig.invertNum = std::any_cast<Hyprlang::INT>(props.at("invert_numlock"));
|
||||
colorConfig.swapFont = std::any_cast<Hyprlang::INT>(props.at("swap_font_color"));
|
||||
viewport = viewport_;
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
RASSERT(false, "Failed to construct CPasswordInputField: {}", e.what()); //
|
||||
} catch (const std::out_of_range& e) {
|
||||
RASSERT(false, "Missing property for CPasswordInputField: {}", e.what()); //
|
||||
}
|
||||
|
||||
auto POS__ = std::any_cast<Hyprlang::VEC2>(props.at("position"));
|
||||
pos = {POS__.x, POS__.y};
|
||||
configPos = pos;
|
||||
configSize = size;
|
||||
|
||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||
|
||||
pos = posFromHVAlign(viewport, size, pos, halign, valign);
|
||||
dots.size = std::clamp(dots.size, 0.2f, 0.8f);
|
||||
dots.spacing = std::clamp(dots.spacing, -1.f, 1.f);
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
#include "Shape.hpp"
|
||||
#include "../Renderer.hpp"
|
||||
#include "../../helpers/MiscFunctions.hpp"
|
||||
#include "../../config/ConfigDataValues.hpp"
|
||||
#include <cmath>
|
||||
#include <hyprlang.hpp>
|
||||
|
||||
CShape::CShape(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props) : shadow(this, props, viewport_) {
|
||||
|
||||
size = Vector2DFromHyprlang(std::any_cast<Hyprlang::VEC2>(props.at("size")));
|
||||
try {
|
||||
size = CLayoutValueData::fromAnyPv(props.at("size"))->getAbsolute(viewport_);
|
||||
rounding = std::any_cast<Hyprlang::INT>(props.at("rounding"));
|
||||
border = std::any_cast<Hyprlang::INT>(props.at("border_size"));
|
||||
color = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||
borderColor = std::any_cast<Hyprlang::INT>(props.at("border_color"));
|
||||
pos = Vector2DFromHyprlang(std::any_cast<Hyprlang::VEC2>(props.at("position")));
|
||||
pos = 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"));
|
||||
angle = std::any_cast<Hyprlang::FLOAT>(props.at("rotate"));
|
||||
xray = std::any_cast<Hyprlang::INT>(props.at("xray"));
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
RASSERT(false, "Failed to construct CShape: {}", e.what()); //
|
||||
} catch (const std::out_of_range& e) {
|
||||
RASSERT(false, "Missing property for CShape: {}", e.what()); //
|
||||
}
|
||||
|
||||
viewport = viewport_;
|
||||
angle = angle * M_PI / 180.0;
|
||||
|
|
Loading…
Reference in a new issue