mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-11-16 23:05:58 +01:00
renderer: add shadowable props
This commit is contained in:
parent
2fa0da47ab
commit
a4dc596cb8
13 changed files with 173 additions and 21 deletions
|
@ -35,6 +35,13 @@ CConfigManager::CConfigManager() : m_config(getMainConfigPath().c_str(), Hyprlan
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::init() {
|
void CConfigManager::init() {
|
||||||
|
|
||||||
|
#define SHADOWABLE(name) \
|
||||||
|
m_config.addSpecialConfigValue(name, "shadow_size", Hyprlang::INT{3}); \
|
||||||
|
m_config.addSpecialConfigValue(name, "shadow_passes", Hyprlang::INT{2}); \
|
||||||
|
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:disable_loading_bar", Hyprlang::INT{0});
|
||||||
m_config.addConfigValue("general:hide_cursor", Hyprlang::INT{0});
|
m_config.addConfigValue("general:hide_cursor", Hyprlang::INT{0});
|
||||||
m_config.addConfigValue("general:grace", Hyprlang::INT{0});
|
m_config.addConfigValue("general:grace", Hyprlang::INT{0});
|
||||||
|
@ -70,6 +77,7 @@ void CConfigManager::init() {
|
||||||
m_config.addSpecialConfigValue("input-field", "placeholder_text", Hyprlang::STRING{"<i>Input Password</i>"});
|
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", "hide_input", Hyprlang::INT{0});
|
||||||
m_config.addSpecialConfigValue("input-field", "rounding", Hyprlang::INT{-1});
|
m_config.addSpecialConfigValue("input-field", "rounding", Hyprlang::INT{-1});
|
||||||
|
SHADOWABLE("input-field");
|
||||||
|
|
||||||
m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
||||||
m_config.addSpecialConfigValue("label", "monitor", Hyprlang::STRING{""});
|
m_config.addSpecialConfigValue("label", "monitor", Hyprlang::STRING{""});
|
||||||
|
@ -80,6 +88,7 @@ void CConfigManager::init() {
|
||||||
m_config.addSpecialConfigValue("label", "font_family", Hyprlang::STRING{"Sans"});
|
m_config.addSpecialConfigValue("label", "font_family", Hyprlang::STRING{"Sans"});
|
||||||
m_config.addSpecialConfigValue("label", "halign", Hyprlang::STRING{"none"});
|
m_config.addSpecialConfigValue("label", "halign", Hyprlang::STRING{"none"});
|
||||||
m_config.addSpecialConfigValue("label", "valign", Hyprlang::STRING{"none"});
|
m_config.addSpecialConfigValue("label", "valign", Hyprlang::STRING{"none"});
|
||||||
|
SHADOWABLE("label");
|
||||||
|
|
||||||
m_config.registerHandler(&::handleSource, "source", {false});
|
m_config.registerHandler(&::handleSource, "source", {false});
|
||||||
|
|
||||||
|
@ -89,6 +98,8 @@ void CConfigManager::init() {
|
||||||
|
|
||||||
if (result.error)
|
if (result.error)
|
||||||
Debug::log(ERR, "Config has errors:\n{}\nProceeding ignoring faulty entries", result.getError());
|
Debug::log(ERR, "Config has errors:\n{}\nProceeding ignoring faulty entries", result.getError());
|
||||||
|
|
||||||
|
#undef SHADOWABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mutex configMtx;
|
std::mutex configMtx;
|
||||||
|
@ -101,6 +112,12 @@ void* const* CConfigManager::getValuePtr(const std::string& name) {
|
||||||
std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
||||||
std::vector<CConfigManager::SWidgetConfig> result;
|
std::vector<CConfigManager::SWidgetConfig> result;
|
||||||
|
|
||||||
|
#define SHADOWABLE(name) \
|
||||||
|
{"shadow_size", m_config.getSpecialConfigValue(name, "shadow_size", k.c_str())}, {"shadow_passes", m_config.getSpecialConfigValue(name, "shadow_passes", k.c_str())}, \
|
||||||
|
{"shadow_color", m_config.getSpecialConfigValue(name, "shadow_color", k.c_str())}, { \
|
||||||
|
"shadow_boost", m_config.getSpecialConfigValue(name, "shadow_boost", k.c_str()) \
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
auto keys = m_config.listKeysForSpecialCategory("background");
|
auto keys = m_config.listKeysForSpecialCategory("background");
|
||||||
for (auto& k : keys) {
|
for (auto& k : keys) {
|
||||||
|
@ -146,6 +163,7 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
||||||
{"placeholder_text", m_config.getSpecialConfigValue("input-field", "placeholder_text", k.c_str())},
|
{"placeholder_text", m_config.getSpecialConfigValue("input-field", "placeholder_text", k.c_str())},
|
||||||
{"hide_input", m_config.getSpecialConfigValue("input-field", "hide_input", k.c_str())},
|
{"hide_input", m_config.getSpecialConfigValue("input-field", "hide_input", k.c_str())},
|
||||||
{"rounding", m_config.getSpecialConfigValue("input-field", "rounding", k.c_str())},
|
{"rounding", m_config.getSpecialConfigValue("input-field", "rounding", k.c_str())},
|
||||||
|
SHADOWABLE("input-field"),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -165,6 +183,7 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
||||||
{"text", m_config.getSpecialConfigValue("label", "text", k.c_str())},
|
{"text", m_config.getSpecialConfigValue("label", "text", k.c_str())},
|
||||||
{"halign", m_config.getSpecialConfigValue("label", "halign", k.c_str())},
|
{"halign", m_config.getSpecialConfigValue("label", "halign", k.c_str())},
|
||||||
{"valign", m_config.getSpecialConfigValue("label", "valign", k.c_str())},
|
{"valign", m_config.getSpecialConfigValue("label", "valign", k.c_str())},
|
||||||
|
SHADOWABLE("label"),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
@ -17,11 +17,11 @@ static uint32_t glFormatToType(uint32_t gl) {
|
||||||
return gl != GL_RGBA ? GL_UNSIGNED_INT_2_10_10_10_REV : GL_UNSIGNED_BYTE;
|
return gl != GL_RGBA ? GL_UNSIGNED_INT_2_10_10_10_REV : GL_UNSIGNED_BYTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFramebuffer::alloc(int w, int h) {
|
bool CFramebuffer::alloc(int w, int h, bool highres) {
|
||||||
bool firstAlloc = false;
|
bool firstAlloc = false;
|
||||||
|
|
||||||
uint32_t glFormat = drmFormatToGL(DRM_FORMAT_XRGB2101010); // TODO: revise only 10b when I find a way to figure out without sc whether display is 10b
|
uint32_t glFormat = highres ? GL_RGBA16F : drmFormatToGL(DRM_FORMAT_XRGB2101010); // TODO: revise only 10b when I find a way to figure out without sc whether display is 10b
|
||||||
uint32_t glType = glFormatToType(glFormat);
|
uint32_t glType = highres ? GL_FLOAT : glFormatToType(glFormat);
|
||||||
|
|
||||||
if (m_iFb == (uint32_t)-1) {
|
if (m_iFb == (uint32_t)-1) {
|
||||||
firstAlloc = true;
|
firstAlloc = true;
|
||||||
|
|
|
@ -8,7 +8,7 @@ class CFramebuffer {
|
||||||
public:
|
public:
|
||||||
~CFramebuffer();
|
~CFramebuffer();
|
||||||
|
|
||||||
bool alloc(int w, int h);
|
bool alloc(int w, int h, bool highres = false);
|
||||||
void addStencil();
|
void addStencil();
|
||||||
void bind() const;
|
void bind() const;
|
||||||
void release();
|
void release();
|
||||||
|
|
|
@ -146,6 +146,9 @@ CRenderer::CRenderer() {
|
||||||
blurFinishShader.texAttrib = glGetAttribLocation(prog, "texcoord");
|
blurFinishShader.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||||
blurFinishShader.brightness = glGetUniformLocation(prog, "brightness");
|
blurFinishShader.brightness = glGetUniformLocation(prog, "brightness");
|
||||||
blurFinishShader.noise = glGetUniformLocation(prog, "noise");
|
blurFinishShader.noise = glGetUniformLocation(prog, "noise");
|
||||||
|
blurFinishShader.colorize = glGetUniformLocation(prog, "colorize");
|
||||||
|
blurFinishShader.colorizeTint = glGetUniformLocation(prog, "colorizeTint");
|
||||||
|
blurFinishShader.boostA = glGetUniformLocation(prog, "boostA");
|
||||||
|
|
||||||
wlr_matrix_identity(projMatrix.data());
|
wlr_matrix_identity(projMatrix.data());
|
||||||
|
|
||||||
|
@ -164,6 +167,10 @@ CRenderer::SRenderFeedback CRenderer::renderLock(const CSessionLockSurface& surf
|
||||||
g_pEGL->makeCurrent(surf.eglSurface);
|
g_pEGL->makeCurrent(surf.eglSurface);
|
||||||
glViewport(0, 0, surf.size.x, surf.size.y);
|
glViewport(0, 0, surf.size.x, surf.size.y);
|
||||||
|
|
||||||
|
GLint fb = 0;
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fb);
|
||||||
|
pushFb(fb);
|
||||||
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
@ -330,8 +337,8 @@ void CRenderer::blurFB(const CFramebuffer& outfb, SBlurParams params) {
|
||||||
wlr_matrix_multiply(glMatrix, projection.data(), matrix);
|
wlr_matrix_multiply(glMatrix, projection.data(), matrix);
|
||||||
|
|
||||||
CFramebuffer mirrors[2];
|
CFramebuffer mirrors[2];
|
||||||
mirrors[0].alloc(outfb.m_vSize.x, outfb.m_vSize.y);
|
mirrors[0].alloc(outfb.m_vSize.x, outfb.m_vSize.y, true);
|
||||||
mirrors[1].alloc(outfb.m_vSize.x, outfb.m_vSize.y);
|
mirrors[1].alloc(outfb.m_vSize.x, outfb.m_vSize.y, true);
|
||||||
|
|
||||||
CFramebuffer* currentRenderToFB = &mirrors[0];
|
CFramebuffer* currentRenderToFB = &mirrors[0];
|
||||||
|
|
||||||
|
@ -442,6 +449,10 @@ void CRenderer::blurFB(const CFramebuffer& outfb, SBlurParams params) {
|
||||||
glUniformMatrix3fv(blurFinishShader.proj, 1, GL_TRUE, glMatrix);
|
glUniformMatrix3fv(blurFinishShader.proj, 1, GL_TRUE, glMatrix);
|
||||||
glUniform1f(blurFinishShader.noise, params.noise);
|
glUniform1f(blurFinishShader.noise, params.noise);
|
||||||
glUniform1f(blurFinishShader.brightness, params.brightness);
|
glUniform1f(blurFinishShader.brightness, params.brightness);
|
||||||
|
glUniform1i(blurFinishShader.colorize, params.colorize.has_value());
|
||||||
|
if (params.colorize.has_value())
|
||||||
|
glUniform3f(blurFinishShader.colorizeTint, params.colorize->r, params.colorize->g, params.colorize->b);
|
||||||
|
glUniform1f(blurFinishShader.boostA, params.boostA);
|
||||||
|
|
||||||
glUniform1i(blurFinishShader.tex, 0);
|
glUniform1i(blurFinishShader.tex, 0);
|
||||||
|
|
||||||
|
@ -468,3 +479,13 @@ void CRenderer::blurFB(const CFramebuffer& outfb, SBlurParams params) {
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CRenderer::pushFb(GLint fb) {
|
||||||
|
boundFBs.push_back(fb);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRenderer::popFb() {
|
||||||
|
boundFBs.pop_back();
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundFBs.empty() ? 0 : boundFBs.back());
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "../core/LockSurface.hpp"
|
#include "../core/LockSurface.hpp"
|
||||||
#include "Shader.hpp"
|
#include "Shader.hpp"
|
||||||
|
@ -24,6 +25,8 @@ class CRenderer {
|
||||||
struct SBlurParams {
|
struct SBlurParams {
|
||||||
int size = 0, passes = 0;
|
int size = 0, passes = 0;
|
||||||
float noise = 0, contrast = 0, brightness = 0, vibrancy = 0, vibrancy_darkness = 0;
|
float noise = 0, contrast = 0, brightness = 0, vibrancy = 0, vibrancy_darkness = 0;
|
||||||
|
std::optional<CColor> colorize;
|
||||||
|
float boostA = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
SRenderFeedback renderLock(const CSessionLockSurface& surface);
|
SRenderFeedback renderLock(const CSessionLockSurface& surface);
|
||||||
|
@ -35,6 +38,9 @@ class CRenderer {
|
||||||
std::unique_ptr<CAsyncResourceGatherer> asyncResourceGatherer;
|
std::unique_ptr<CAsyncResourceGatherer> asyncResourceGatherer;
|
||||||
std::chrono::system_clock::time_point gatheredAt;
|
std::chrono::system_clock::time_point gatheredAt;
|
||||||
|
|
||||||
|
void pushFb(GLint fb);
|
||||||
|
void popFb();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
widgetMap_t widgets;
|
widgetMap_t widgets;
|
||||||
|
|
||||||
|
@ -49,6 +55,8 @@ class CRenderer {
|
||||||
|
|
||||||
std::array<float, 9> projMatrix;
|
std::array<float, 9> projMatrix;
|
||||||
std::array<float, 9> projection;
|
std::array<float, 9> projection;
|
||||||
|
|
||||||
|
std::vector<GLint> boundFBs;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CRenderer> g_pRenderer;
|
inline std::unique_ptr<CRenderer> g_pRenderer;
|
|
@ -59,6 +59,11 @@ class CShader {
|
||||||
GLint brightness = -1;
|
GLint brightness = -1;
|
||||||
GLint noise = -1;
|
GLint noise = -1;
|
||||||
|
|
||||||
|
// colorize
|
||||||
|
GLint colorize = -1;
|
||||||
|
GLint colorizeTint = -1;
|
||||||
|
GLint boostA = -1;
|
||||||
|
|
||||||
GLint getUniformLocation(const std::string&);
|
GLint getUniformLocation(const std::string&);
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
|
@ -331,6 +331,10 @@ uniform sampler2D tex;
|
||||||
uniform float noise;
|
uniform float noise;
|
||||||
uniform float brightness;
|
uniform float brightness;
|
||||||
|
|
||||||
|
uniform int colorize;
|
||||||
|
uniform vec3 colorizeTint;
|
||||||
|
uniform float boostA;
|
||||||
|
|
||||||
float hash(vec2 p) {
|
float hash(vec2 p) {
|
||||||
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
|
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
|
||||||
}
|
}
|
||||||
|
@ -348,6 +352,13 @@ void main() {
|
||||||
pixColor.rgb *= brightness;
|
pixColor.rgb *= brightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixColor.a *= boostA;
|
||||||
|
|
||||||
|
if (colorize == 1) {
|
||||||
|
gl_FragColor = vec4(colorizeTint.r, colorizeTint.g, colorizeTint.b, pixColor.a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gl_FragColor = pixColor;
|
gl_FragColor = pixColor;
|
||||||
}
|
}
|
||||||
)#";
|
)#";
|
|
@ -52,7 +52,8 @@ void CLabel::plantTimer() {
|
||||||
labelTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)label.updateEveryMs), onTimer, this);
|
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, CSessionLockSurface* surface_) : surface(surface_) {
|
CLabel::CLabel(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props, CSessionLockSurface* surface_) :
|
||||||
|
surface(surface_), shadow(this, props, viewport_) {
|
||||||
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"));
|
||||||
|
@ -92,6 +93,7 @@ bool CLabel::draw(const SRenderData& data) {
|
||||||
|
|
||||||
// calc pos
|
// calc pos
|
||||||
pos = posFromHVAlign(viewport, asset->texture.m_vSize, configPos, halign, valign);
|
pos = posFromHVAlign(viewport, asset->texture.m_vSize, configPos, halign, valign);
|
||||||
|
shadow.markShadowDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pendingResourceID.empty()) {
|
if (!pendingResourceID.empty()) {
|
||||||
|
@ -104,11 +106,12 @@ bool CLabel::draw(const SRenderData& data) {
|
||||||
resourceID = pendingResourceID;
|
resourceID = pendingResourceID;
|
||||||
pendingResourceID = "";
|
pendingResourceID = "";
|
||||||
pos = posFromHVAlign(viewport, asset->texture.m_vSize, configPos, halign, valign);
|
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};
|
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);
|
g_pRenderer->renderTexture(box, asset->texture, data.opacity);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IWidget.hpp"
|
#include "IWidget.hpp"
|
||||||
|
#include "Shadowable.hpp"
|
||||||
#include "../../helpers/Vector2D.hpp"
|
#include "../../helpers/Vector2D.hpp"
|
||||||
#include "../../core/Timer.hpp"
|
#include "../../core/Timer.hpp"
|
||||||
#include "../AsyncResourceGatherer.hpp"
|
#include "../AsyncResourceGatherer.hpp"
|
||||||
|
@ -38,4 +39,6 @@ class CLabel : public IWidget {
|
||||||
CAsyncResourceGatherer::SPreloadRequest request;
|
CAsyncResourceGatherer::SPreloadRequest request;
|
||||||
|
|
||||||
std::shared_ptr<CTimer> labelTimer;
|
std::shared_ptr<CTimer> labelTimer;
|
||||||
|
|
||||||
|
CShadowable shadow;
|
||||||
};
|
};
|
|
@ -3,7 +3,7 @@
|
||||||
#include "../../core/hyprlock.hpp"
|
#include "../../core/hyprlock.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props) {
|
CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props) : shadow(this, props, viewport_) {
|
||||||
size = std::any_cast<Hyprlang::VEC2>(props.at("size"));
|
size = std::any_cast<Hyprlang::VEC2>(props.at("size"));
|
||||||
inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
||||||
outer = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
outer = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
||||||
|
@ -105,6 +105,11 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
CBox inputFieldBox = {pos, size};
|
CBox inputFieldBox = {pos, size};
|
||||||
CBox outerBox = {pos - Vector2D{outThick, outThick}, size + Vector2D{outThick * 2, outThick * 2}};
|
CBox outerBox = {pos - Vector2D{outThick, outThick}, size + Vector2D{outThick * 2, outThick * 2}};
|
||||||
|
|
||||||
|
if (firstRender) {
|
||||||
|
firstRender = false;
|
||||||
|
shadow.markShadowDirty();
|
||||||
|
}
|
||||||
|
|
||||||
bool forceReload = false;
|
bool forceReload = false;
|
||||||
|
|
||||||
updateFade();
|
updateFade();
|
||||||
|
@ -112,6 +117,10 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
updateFailTex();
|
updateFailTex();
|
||||||
updateHiddenInputState();
|
updateHiddenInputState();
|
||||||
|
|
||||||
|
SRenderData shadowData = data;
|
||||||
|
shadowData.opacity *= fade.a;
|
||||||
|
shadow.draw(shadowData);
|
||||||
|
|
||||||
float passAlpha = g_pHyprlock->passwordCheckWaiting() ? 0.5 : 1.0;
|
float passAlpha = g_pHyprlock->passwordCheckWaiting() ? 0.5 : 1.0;
|
||||||
|
|
||||||
CColor outerCol = outer;
|
CColor outerCol = outer;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "IWidget.hpp"
|
#include "IWidget.hpp"
|
||||||
#include "../../helpers/Vector2D.hpp"
|
#include "../../helpers/Vector2D.hpp"
|
||||||
#include "../../helpers/Color.hpp"
|
#include "../../helpers/Color.hpp"
|
||||||
|
#include "Shadowable.hpp"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <any>
|
#include <any>
|
||||||
|
@ -22,6 +23,8 @@ class CPasswordInputField : public IWidget {
|
||||||
void updateFailTex();
|
void updateFailTex();
|
||||||
void updateHiddenInputState();
|
void updateHiddenInputState();
|
||||||
|
|
||||||
|
bool firstRender = true;
|
||||||
|
|
||||||
Vector2D size;
|
Vector2D size;
|
||||||
Vector2D pos;
|
Vector2D pos;
|
||||||
Vector2D viewport;
|
Vector2D viewport;
|
||||||
|
@ -64,4 +67,6 @@ class CPasswordInputField : public IWidget {
|
||||||
} hiddenInputState;
|
} hiddenInputState;
|
||||||
|
|
||||||
bool fadeOnEmpty;
|
bool fadeOnEmpty;
|
||||||
|
|
||||||
|
CShadowable shadow;
|
||||||
};
|
};
|
||||||
|
|
36
src/renderer/widgets/Shadowable.cpp
Normal file
36
src/renderer/widgets/Shadowable.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include "Shadowable.hpp"
|
||||||
|
#include "../Renderer.hpp"
|
||||||
|
|
||||||
|
CShadowable::CShadowable(IWidget* widget_, const std::unordered_map<std::string, std::any>& props, const Vector2D& viewport_) : widget(widget_), viewport(viewport_) {
|
||||||
|
size = std::any_cast<Hyprlang::INT>(props.at("shadow_size"));
|
||||||
|
passes = std::any_cast<Hyprlang::INT>(props.at("shadow_passes"));
|
||||||
|
color = std::any_cast<Hyprlang::INT>(props.at("shadow_color"));
|
||||||
|
boostA = std::any_cast<Hyprlang::FLOAT>(props.at("shadow_boost"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CShadowable::markShadowDirty() {
|
||||||
|
|
||||||
|
if (!shadowFB.isAllocated())
|
||||||
|
shadowFB.alloc(viewport.x, viewport.y, true);
|
||||||
|
|
||||||
|
g_pRenderer->pushFb(shadowFB.m_iFb);
|
||||||
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
ignoreDraw = true;
|
||||||
|
widget->draw(IWidget::SRenderData{.opacity = 1.0});
|
||||||
|
ignoreDraw = false;
|
||||||
|
|
||||||
|
g_pRenderer->blurFB(shadowFB, CRenderer::SBlurParams{.size = size, .passes = passes, .colorize = color, .boostA = boostA});
|
||||||
|
|
||||||
|
g_pRenderer->popFb();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CShadowable::draw(const IWidget::SRenderData& data) {
|
||||||
|
if (!shadowFB.isAllocated() || ignoreDraw)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CBox box = {0, 0, viewport.x, viewport.y};
|
||||||
|
g_pRenderer->renderTexture(box, shadowFB.m_cTex, 1.0, 0, WL_OUTPUT_TRANSFORM_NORMAL);
|
||||||
|
return true;
|
||||||
|
}
|
32
src/renderer/widgets/Shadowable.hpp
Normal file
32
src/renderer/widgets/Shadowable.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Framebuffer.hpp"
|
||||||
|
#include "../Texture.hpp"
|
||||||
|
#include "../../helpers/Color.hpp"
|
||||||
|
#include "IWidget.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
class CShadowable {
|
||||||
|
public:
|
||||||
|
CShadowable(IWidget* widget_, const std::unordered_map<std::string, std::any>& props, const Vector2D& viewport_ /* TODO: make this not the entire viewport */);
|
||||||
|
|
||||||
|
// instantly re-renders the shadow using the widget's draw() method
|
||||||
|
void markShadowDirty();
|
||||||
|
virtual bool draw(const IWidget::SRenderData& data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
IWidget* widget = nullptr;
|
||||||
|
int size = 10;
|
||||||
|
int passes = 4;
|
||||||
|
float boostA = 1.0;
|
||||||
|
CColor color{0, 0, 0, 1.0};
|
||||||
|
Vector2D viewport;
|
||||||
|
|
||||||
|
// to avoid recursive shadows
|
||||||
|
bool ignoreDraw = false;
|
||||||
|
|
||||||
|
CFramebuffer shadowFB;
|
||||||
|
};
|
Loading…
Reference in a new issue