SNI: Add Icon positioning config options

This commit is contained in:
scorpion-26 2023-05-04 16:14:18 +02:00
parent 79e78826e0
commit e9c9d3abb1
5 changed files with 91 additions and 5 deletions

View file

@ -27,6 +27,14 @@ void ApplyProperty<uint32_t>(uint32_t& propertyToSet, const std::string_view& va
propertyToSet = atoi(valStr.c_str());
}
template<>
void ApplyProperty<int32_t>(int32_t& propertyToSet, const std::string_view& value)
{
// Why, C++?
std::string valStr = std::string(value);
propertyToSet = atoi(valStr.c_str());
}
template<>
void ApplyProperty<double>(double& propertyToSet, const std::string_view& value)
{
@ -53,6 +61,30 @@ void ApplyProperty<bool>(bool& propertyToSet, const std::string_view& value)
}
}
template<>
void ApplyProperty<std::pair<std::string, uint32_t>>(std::pair<std::string, uint32_t>& propertyToSet, const std::string_view& value)
{
// TODO: Ignore escaped delimiter (e.g. \, is the same as ,)
const char delim = ',';
const char* whitespace = " \t";
size_t delimPos = value.find(delim);
if (delimPos == std::string::npos)
{
propertyToSet = {std::string(value), 0};
return;
}
std::string_view before = value.substr(0, delimPos);
std::string_view after = value.substr(delimPos + 1);
// Strip whitespaces for before
size_t beginBefore = before.find_first_not_of(whitespace);
size_t endBefore = before.find_last_not_of(whitespace);
before = before.substr(beginBefore, endBefore - beginBefore + 1);
ApplyProperty(propertyToSet.first, before);
ApplyProperty(propertyToSet.second, after);
}
template<typename T>
void AddConfigVar(const std::string& propertyName, T& propertyToSet, std::string_view line, bool& setConfig)
{
@ -161,6 +193,21 @@ void Config::Load()
AddConfigVar("AudioMinVolume", config.audioMinVolume, lineView, foundProperty);
AddConfigVar("AudioMaxVolume", config.audioMaxVolume, lineView, foundProperty);
std::pair<std::string, uint32_t> buf;
bool hasntFoundProperty = !foundProperty;
AddConfigVar("SNIIconSize", buf, lineView, foundProperty);
if (foundProperty && hasntFoundProperty)
{
// This was found
config.sniIconSizes[buf.first] = buf.second;
}
hasntFoundProperty = !foundProperty;
AddConfigVar("SNIPaddingTop", buf, lineView, foundProperty);
if (foundProperty && hasntFoundProperty)
{
config.sniPaddingTop[buf.first] = buf.second;
}
if (foundProperty == false)
{
LOG("Warning: unknown config var: " << lineView);

View file

@ -2,6 +2,7 @@
#include <string>
#include <vector>
#include <cstdint>
#include <unordered_map>
class Config
{
@ -39,6 +40,10 @@ public:
uint32_t checkUpdateInterval = 5 * 60; // Interval to run the "checkPackagesCommand". In seconds
// SNIIconSize: ["Title String"], ["Size"]
std::unordered_map<std::string, uint32_t> sniIconSizes;
std::unordered_map<std::string, int32_t> sniPaddingTop;
// Only affects outputs (i.e.: speakers, not microphones). This remaps the range of the volume; In percent
double audioMinVolume = 0.f; // Map the minimum volume to this value
double audioMaxVolume = 100.f; // Map the maximum volume to this value

View file

@ -326,6 +326,33 @@ namespace SNI
LOG("SNI: Add " << item.name << " to widget");
auto texture = Widget::Create<Texture>();
bool wasExplicitOverride = false;
for (auto& [filter, size] : Config::Get().sniIconSizes)
{
if (item.tooltip.find(filter) != std::string::npos)
{
wasExplicitOverride = true;
texture->ForceHeight(size);
}
else if (filter == "*" && !wasExplicitOverride)
{
texture->ForceHeight(size);
}
}
wasExplicitOverride = false;
for (auto& [filter, padding] : Config::Get().sniPaddingTop)
{
if (item.tooltip.find(filter) != std::string::npos)
{
LOG("Padding " << padding);
wasExplicitOverride = true;
texture->AddPaddingTop(padding);
}
else if (filter == "*" && !wasExplicitOverride)
{
texture->AddPaddingTop(padding);
}
}
texture->SetHorizontalTransform({0, true, Alignment::Fill});
texture->SetBuf(item.w, item.h, item.iconData);
texture->SetTooltip(item.tooltip);

View file

@ -520,13 +520,15 @@ void Texture::Draw(cairo_t* cr)
{
GtkAllocation dim;
gtk_widget_get_allocation(m_Widget, &dim);
double ratio = (double)m_Width / (double)m_Height;
gtk_widget_set_size_request(m_Widget, dim.height * ratio, dim.height);
double scale = (double)dim.height / (double)m_Height;
double height = m_ForcedHeight != 0 ? m_ForcedHeight : dim.height;
double scale = (double)height / (double)m_Height;
double width = (double)m_Width * scale;
gtk_widget_set_size_request(m_Widget, width + 2, height);
cairo_scale(cr, scale, scale);
cairo_rectangle(cr, 0.f, 0.f, m_Width, m_Height);
gdk_cairo_set_source_pixbuf(cr, m_Pixbuf, 0, 0);
cairo_rectangle(cr, (dim.width - width) / 2.0, m_Padding + (dim.height - height) / 2.0, m_Width, m_Height);
gdk_cairo_set_source_pixbuf(cr, m_Pixbuf, (dim.width - width) / 2.0, m_Padding + (dim.height - height) / 2.0);
cairo_fill(cr);
}

View file

@ -277,11 +277,16 @@ public:
// Non-Owning, ARGB32
void SetBuf(size_t width, size_t height, uint8_t* buf);
void ForceHeight(size_t height) { m_ForcedHeight = height; };
void AddPaddingTop(int32_t topPadding) { m_Padding = topPadding; };
private:
void Draw(cairo_t* cr) override;
size_t m_Width;
size_t m_Height;
size_t m_ForcedHeight = 0;
int32_t m_Padding = 0;
GBytes* m_Bytes;
GdkPixbuf* m_Pixbuf;
};