From 713084a48649a7aa0c40ea6d6163f0def3dcd82c Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Fri, 22 Nov 2024 01:44:04 +0100 Subject: Add slider knob --- src/blocks/slider.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/display.c | 3 ++ src/event.c | 3 ++ src/util.c | 9 +++++ src/util.h | 2 ++ 5 files changed, 104 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/blocks/slider.c b/src/blocks/slider.c index b01ddb7..f80c71b 100644 --- a/src/blocks/slider.c +++ b/src/blocks/slider.c @@ -7,6 +7,17 @@ #include "../format.h" #include "../any_log.h" +typedef enum { + KNOB_NONE, + KNOB_CIRCLE, + //KNOB_CAPSULE, + KNOB_TRIANGLE, + //KNOB_TRIANGLE_UP, + //KNOB_TRIANGLE_DOWN, + //KNOB_TRIANGLE_LEFT, + //KNOB_TRIANGLE_RIGHT, +} block_slider_knob_t; + typedef struct { block_spec_t block; int value; @@ -17,6 +28,13 @@ typedef struct { gradient_t line_color; gradient_t bg_color; bool seekable; + block_slider_knob_t knob; + unsigned int knob_height; + unsigned int knob_line_width; + int knob_x_offset; + int knob_y_offset; + gradient_t knob_color; + gradient_t knob_line_color; } block_slider_t; static void block_slider_layout(block_t *block, layout_t *layout, layout_info_t info) @@ -29,7 +47,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr) { block_slider_t *slider = (block_slider_t *)layout->block; - const int radius = slider->height / 2; + int radius = slider->height / 2; int bar_y = layout->y + (layout->height - slider->height) / 2; int bar_x = layout->x + (layout->width - slider->width) / 2; @@ -66,6 +84,51 @@ static void block_slider_render(layout_t *layout, cairo_t *cr) cairo_set_line_width(cr, slider->line_width); cairo_stroke(cr); } + + if (slider->knob == KNOB_NONE) return; + + int knob_height = slider->knob_height != 0 ? slider->knob_height : slider->height; + int knob_radius = knob_height / 2; + + const double sqrt3 = 1.7320508075688772; + int knob_width = slider->knob == KNOB_TRIANGLE + ? (knob_height * sqrt3) / 2.0 + : knob_height; + + // FIXME + int current = (slider->width - knob_width) * slider->value / 100.0; + + int knob_x = bar_x + slider->knob_x_offset + current; + int knob_y = bar_y + slider->knob_y_offset + radius - knob_radius; + + pattern = slider->knob_color.pattern; + if (pattern != NULL) { + + if (slider->knob == KNOB_TRIANGLE) + render_triangle(cr, knob_x, knob_y, knob_width, knob_height); + else if (slider->knob == KNOB_CIRCLE) + render_capsule(cr, knob_x, knob_y, knob_width, knob_radius, knob_radius); + + cairo_pattern_set_matrix(pattern, &matrix); + cairo_set_source(cr, pattern); + cairo_fill(cr); + } + + pattern = slider->knob_line_color.pattern; + if (pattern != NULL) { + int line_radius = knob_radius - slider->knob_line_width / 2; + + if (slider->knob == KNOB_TRIANGLE) + render_triangle(cr, knob_x, knob_y, knob_width, knob_height); + else if (slider->knob == KNOB_CIRCLE) + render_capsule(cr, knob_x, knob_y, knob_width, knob_radius, line_radius); + + + cairo_pattern_set_matrix(pattern, &matrix); + cairo_set_source(cr, pattern); + cairo_set_line_width(cr, slider->knob_line_width); + cairo_stroke(cr); + } } static void block_slider_event(layout_t *layout, event_t event) @@ -127,16 +190,31 @@ static int block_slider_validate(block_t *block, const block_scheme_t *scheme) return errors; } +static config_enum_t knob_shape_enum[] = { + { "none", KNOB_NONE }, + { "circle", KNOB_CIRCLE }, + //{ "capsule", KNOB_CAPSULE }, + { "triangle", KNOB_TRIANGLE }, + { 0 }, +}; + static const config_entry_t block_slider_entries[] = { // TODO: Ugly names - { "bar-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, bar_color) }, - { "bar-line-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, line_color) }, - { "bar-bg-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, bg_color) }, - { "bar-height", CONFIG_UINT, NULL, offsetof(block_slider_t, height) }, - { "bar-width", CONFIG_UINT, NULL, offsetof(block_slider_t, width) }, - { "bar-line-width", CONFIG_UINT, NULL, offsetof(block_slider_t, line_width) }, - { "bar-value", CONFIG_INT, NULL, offsetof(block_slider_t, value) }, - { "seekable", CONFIG_BOOL, NULL, offsetof(block_slider_t, seekable) }, + { "bar-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, bar_color) }, + { "bar-line-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, line_color) }, + { "bar-bg-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, bg_color) }, + { "bar-height", CONFIG_UINT, NULL, offsetof(block_slider_t, height) }, + { "bar-width", CONFIG_UINT, NULL, offsetof(block_slider_t, width) }, + { "bar-line-width", CONFIG_UINT, NULL, offsetof(block_slider_t, line_width) }, + { "bar-value", CONFIG_INT, NULL, offsetof(block_slider_t, value) }, + { "seekable", CONFIG_BOOL, NULL, offsetof(block_slider_t, seekable) }, + { "knob", CONFIG_ENUM, knob_shape_enum, offsetof(block_slider_t, knob) }, + { "knob-height", CONFIG_UINT, NULL, offsetof(block_slider_t, knob_height) }, + { "knob-line-width", CONFIG_UINT, NULL, offsetof(block_slider_t, knob_line_width) }, + { "knob-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, knob_color) }, + { "knob-line-color", CONFIG_GRADIENT, NULL, offsetof(block_slider_t, knob_line_color) }, + { "knob-x-offset", CONFIG_INT, NULL, offsetof(block_slider_t, knob_x_offset) }, + { "knob-y-offset", CONFIG_INT, NULL, offsetof(block_slider_t, knob_y_offset) }, { 0 }, }; diff --git a/src/display.c b/src/display.c index df0a0e6..738e91e 100644 --- a/src/display.c +++ b/src/display.c @@ -129,6 +129,9 @@ void display_update_scale(display_t *display) return; } + // TODO: Actually use this value + // Also allow changing the screen + // display->screen_dpi = (double)display->screen_size->height * 25.4 / (double)display->screen_size->mheight; log_debug("Fallback dpi value '%.2lf'", display->screen_dpi); } diff --git a/src/event.c b/src/event.c index 4fb40d8..c07f2e8 100644 --- a/src/event.c +++ b/src/event.c @@ -53,6 +53,9 @@ static bool event_dispatch_mouse(layout_t *layout, event_t event) return true; } + // XXX + if (event_is_hover(event)) return false; + block_event_t event_fn = layout->block->type == BLOCK_SPEC ? ((block_spec_t *)layout->block)->event_fn : NULL; diff --git a/src/util.c b/src/util.c index b06fbae..580c360 100644 --- a/src/util.c +++ b/src/util.c @@ -214,6 +214,15 @@ bool iszero(const void *ptr, size_t size) return true; } +void render_triangle(cairo_t *cr, int x, int y, int w, int h) +{ + cairo_new_sub_path(cr); + cairo_line_to(cr, x, y); + cairo_line_to(cr, x, y + h); + cairo_line_to(cr, x + w, y + h / 2); + cairo_close_path(cr); +} + void render_capsule_fast(cairo_t *cr, int x, int y, int w, int r1, int r2) { const double degree = M_PI / 180.0; diff --git a/src/util.h b/src/util.h index 76c87c0..33d4991 100644 --- a/src/util.h +++ b/src/util.h @@ -85,6 +85,8 @@ void strfree(char **list); bool iszero(const void *ptr, size_t size); +void render_triangle(cairo_t *cr, int x, int y, int w, int h); + // Render a capsule shape. Cannot handle w < 2*r1 void render_capsule_fast(cairo_t *cr, int x, int y, int w, int r1, int r2); -- cgit v1.2.3