Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made preview display same format as output #112

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/nix-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install nix
uses: cachix/install-nix-action@v20
uses: cachix/install-nix-action@v27
with:
install_url: https://nixos.org/nix/install
extra_nix_config: |
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ project(
VERSION ${VERSION})

set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

add_compile_definitions(HYPRPICKER_VERSION="${VERSION}")

Expand Down
18 changes: 9 additions & 9 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 77 additions & 11 deletions src/hyprpicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,17 +425,82 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
cairo_clip(PCAIRO);
cairo_paint(PCAIRO);

if (!m_bDisableHexPreview) {
if (!m_bDisablePreview) {
const auto currentColor = getColorFromPixel(pSurface, CLICKPOS);
std::string hexBuffer;
if (m_bUseLowerCase)
hexBuffer = std::format("#{:02x}{:02x}{:02x}", currentColor.r, currentColor.g, currentColor.b);
else
hexBuffer = std::format("#{:02X}{:02X}{:02X}", currentColor.r, currentColor.g, currentColor.b);
std::string previewBuffer;

auto fmax3 = [](float a, float b, float c) -> float { return (a > b && a > c) ? a : (b > c) ? b : c; };
auto fmin3 = [](float a, float b, float c) -> float { return (a < b && a < c) ? a : (b < c) ? b : c; };

switch (m_bSelectedOutputMode) {
case OUTPUT_CMYK: {
float r = 1 - currentColor.r / 255.0f, g = 1 - currentColor.g / 255.0f, b = 1 - currentColor.b / 255.0f;
float k = fmin3(r, g, b), K = (k == 1) ? 1 : 1 - k;
float c = (r - k) / K, m = (g - k) / K, y = (b - k) / K;

c = std::round(c * 100);
m = std::round(m * 100);
y = std::round(y * 100);
k = std::round(k * 100);

previewBuffer = std::format("{}% {}% {}% {}%", c, m, y, k);
break;
}
case OUTPUT_HEX: {
previewBuffer = std::format("#{:02X}{:02X}{:02X}", currentColor.r, currentColor.g, currentColor.b);
break;
}
case OUTPUT_LHEX: {
previewBuffer = std::format("#{:02x}{:02x}{:02x}", currentColor.r, currentColor.g, currentColor.b);
break;
}
case OUTPUT_HSL:
case OUTPUT_HSV: {
auto floatEq = [](float a, float b) -> bool {
return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
};

float h, s, l, v;
float r = currentColor.r / 255.0f, g = currentColor.g / 255.0f, b = currentColor.b / 255.0f;
float max = fmax3(r, g, b), min = fmin3(r, g, b);
float c = max - min;

v = max;
if (c == 0)
h = 0;
else if (v == r)
h = 60 * (0 + (g - b) / c);
else if (v == g)
h = 60 * (2 + (b - r) / c);
else /* v == b */
h = 60 * (4 + (r - g) / c);

float l_or_v;
if (m_bSelectedOutputMode == OUTPUT_HSL) {
l = (max + min) / 2;
s = (floatEq(l, 0.0f) || floatEq(l, 1.0f)) ? 0 : (v - l) / std::min(l, 1 - l);
l_or_v = std::round(l * 100);
} else {
v = max;
s = floatEq(v, 0.0f) ? 0 : c / v;
l_or_v = std::round(v * 100);
}

h = std::round(h < 0 ? h + 360 : h);
s = std::round(s * 100);

previewBuffer = std::format("{} {}% {}%", h, s, l_or_v);
break;
}
case OUTPUT_RGB: {
previewBuffer = std::format("{} {} {}", currentColor.r, currentColor.g, currentColor.b);
break;
}
}

cairo_set_source_rgba(PCAIRO, 0.0, 0.0, 0.0, 0.5);

double x, y, width = 85, height = 28, radius = 6;
double x, y, width = 8 + (11 * previewBuffer.length()), height = 28, radius = 6;

if (CLICKPOS.y > (PBUFFER->pixelSize.y - 50) && CLICKPOS.x > (PBUFFER->pixelSize.x - 100)) {
x = CLICKPOS.x - 80;
Expand All @@ -450,7 +515,7 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
x = CLICKPOS.x;
y = CLICKPOS.y + 20;
}

x -= 5.5 * previewBuffer.length();
cairo_move_to(PCAIRO, x + radius, y);
cairo_arc(PCAIRO, x + width - radius, y + radius, radius, -M_PI_2, 0);
cairo_arc(PCAIRO, x + width - radius, y + height - radius, radius, 0, M_PI_2);
Expand All @@ -476,7 +541,7 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
else
cairo_move_to(PCAIRO, textX, CLICKPOS.y + 40);

cairo_show_text(PCAIRO, hexBuffer.c_str());
cairo_show_text(PCAIRO, previewBuffer.c_str());

cairo_surface_flush(PBUFFER->surface);
}
Expand Down Expand Up @@ -650,9 +715,10 @@ void CHyprpicker::initMouse() {
finish();
break;
}
case OUTPUT_HEX: {
case OUTPUT_HEX:
case OUTPUT_LHEX: {
auto toHex = [this](int i) -> std::string {
const char* DS = m_bUseLowerCase ? "0123456789abcdef" : "0123456789ABCDEF";
const char* DS = m_bSelectedOutputMode == OUTPUT_LHEX ? "0123456789abcdef" : "0123456789ABCDEF";

std::string result = "";

Expand Down
12 changes: 6 additions & 6 deletions src/hyprpicker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
enum eOutputMode {
OUTPUT_CMYK = 0,
OUTPUT_HEX,
OUTPUT_LHEX,
OUTPUT_RGB,
OUTPUT_HSL,
OUTPUT_HSV
Expand Down Expand Up @@ -40,12 +41,11 @@ class CHyprpicker {

bool m_bFancyOutput = true;

bool m_bAutoCopy = false;
bool m_bRenderInactive = false;
bool m_bNoZoom = false;
bool m_bNoFractional = false;
bool m_bDisableHexPreview = false;
bool m_bUseLowerCase = false;
bool m_bAutoCopy = false;
bool m_bRenderInactive = false;
bool m_bNoZoom = false;
bool m_bNoFractional = false;
bool m_bDisablePreview = false;

bool m_bRunning = true;

Expand Down
37 changes: 18 additions & 19 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@
static void help() {
std::cout << "Hyprpicker usage: hyprpicker [arg [...]].\n\nArguments:\n"
<< " -a | --autocopy | Automatically copies the output to the clipboard (requires wl-clipboard)\n"
<< " -f | --format=fmt | Specifies the output format (cmyk, hex, rgb, hsl, hsv)\n"
<< " -f | --format=fmt | Specifies the output format (cmyk, lhex, hex, rgb, hsl, hsv)\n"
<< " -n | --no-fancy | Disables the \"fancy\" (aka. colored) outputting\n"
<< " -h | --help | Show this help message\n"
<< " -r | --render-inactive | Render (freeze) inactive displays\n"
<< " -z | --no-zoom | Disable the zoom lens\n"
<< " -q | --quiet | Disable most logs (leaves errors)\n"
<< " -v | --verbose | Enable more logs\n"
<< " -t | --no-fractional | Disable fractional scaling support\n"
<< " -d | --disable-hex-preview | Disable live preview of Hex code\n"
<< " -l | --lowercase-hex | Outputs the hexcode in lowercase\n"
<< " -d | --disable-preview | Disable live preview of color\n"
<< " -V | --version | Print version info\n";
}

Expand All @@ -25,21 +24,20 @@ int main(int argc, char** argv, char** envp) {

while (true) {
int option_index = 0;
static struct option long_options[] = {{"autocopy", no_argument, nullptr, 'a'},
{"format", required_argument, nullptr, 'f'},
{"help", no_argument, nullptr, 'h'},
{"no-fancy", no_argument, nullptr, 'n'},
{"render-inactive", no_argument, nullptr, 'r'},
{"no-zoom", no_argument, nullptr, 'z'},
{"no-fractional", no_argument, nullptr, 't'},
{"quiet", no_argument, nullptr, 'q'},
{"verbose", no_argument, nullptr, 'v'},
{"disable-hex-preview", no_argument, nullptr, 'd'},
{"lowercase-hex", no_argument, nullptr, 'l'},
{"version", no_argument, nullptr, 'V'},
{nullptr, 0, nullptr, 0}};
static struct option long_options[] = {{"autocopy", no_argument, NULL, 'a'},
{"format", required_argument, NULL, 'f'},
{"help", no_argument, NULL, 'h'},
{"no-fancy", no_argument, NULL, 'n'},
{"render-inactive", no_argument, NULL, 'r'},
{"no-zoom", no_argument, NULL, 'z'},
{"no-fractional", no_argument, NULL, 't'},
{"quiet", no_argument, NULL, 'q'},
{"verbose", no_argument, NULL, 'v'},
{"disable-preview", no_argument, NULL, 'd'},
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}};

int c = getopt_long(argc, argv, ":f:hnarzqvtdlV", long_options, &option_index);
int c = getopt_long(argc, argv, ":f:hnarzqvtdV", long_options, &option_index);
if (c == -1)
break;

Expand All @@ -49,6 +47,8 @@ int main(int argc, char** argv, char** envp) {
g_pHyprpicker->m_bSelectedOutputMode = OUTPUT_CMYK;
else if (strcasecmp(optarg, "hex") == 0)
g_pHyprpicker->m_bSelectedOutputMode = OUTPUT_HEX;
else if (strcasecmp(optarg, "lhex") == 0)
g_pHyprpicker->m_bSelectedOutputMode = OUTPUT_LHEX;
else if (strcasecmp(optarg, "rgb") == 0)
g_pHyprpicker->m_bSelectedOutputMode = OUTPUT_RGB;
else if (strcasecmp(optarg, "hsl") == 0)
Expand All @@ -68,8 +68,7 @@ int main(int argc, char** argv, char** envp) {
case 't': g_pHyprpicker->m_bNoFractional = true; break;
case 'q': Debug::quiet = true; break;
case 'v': Debug::verbose = true; break;
case 'd': g_pHyprpicker->m_bDisableHexPreview = true; break;
case 'l': g_pHyprpicker->m_bUseLowerCase = true; break;
case 'd': g_pHyprpicker->m_bDisablePreview = true; break;
case 'V': {
std::cout << "hyprpicker v" << HYPRPICKER_VERSION << "\n";
exit(0);
Expand Down