aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-11-20 23:11:10 +0100
committerFederico Angelilli <code@fedang.net>2024-11-20 23:11:10 +0100
commitfcd52f6db3dc9092dbd7a502e3e561ad16bf0743 (patch)
tree6f98828f03e6432b7218091712607c134a3bbf57
parent165c408de117b5f3923b945756e4ebffc5b733d7 (diff)
Fix capsule edge case
-rw-r--r--comet.conf4
-rw-r--r--src/blocks/slider.c9
-rw-r--r--src/layout.c4
-rw-r--r--src/util.c30
-rw-r--r--src/util.h4
5 files changed, 42 insertions, 9 deletions
diff --git a/comet.conf b/comet.conf
index bea53a2..3a2fd09 100644
--- a/comet.conf
+++ b/comet.conf
@@ -68,11 +68,11 @@
[block.sl]
type = slider
- bar-value = 10
+ bar-value = 88
color = #18baf2
bar-width = 100
bar-height = 10
- bar-color = #afafaf
+ bar-color = #afafaf, #f1baee
bar-line-color = #000
bar-line-width = 2
bar-bg-color = #fff
diff --git a/src/blocks/slider.c b/src/blocks/slider.c
index 3fe6e8c..8c89ddf 100644
--- a/src/blocks/slider.c
+++ b/src/blocks/slider.c
@@ -30,7 +30,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr)
const int radius = slider->height / 2;
int bar_y = layout->y + (layout->height - slider->height) / 2;
- int bar_x = layout->x + layout->height / 2;
+ int bar_x = layout->x + (layout->width - slider->width) / 2;
cairo_matrix_t matrix;
cairo_matrix_init_scale(&matrix, 1.0 / slider->width, 1.0);
@@ -38,7 +38,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr)
cairo_pattern_t *pattern = slider->bg_color.pattern;
if (pattern != NULL) {
- render_capsule(cr, bar_x, bar_y, slider->width, radius, slider->line_width);
+ render_capsule_fast(cr, bar_x, bar_y, slider->width, radius, radius);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_set_source(cr, pattern);
@@ -48,7 +48,7 @@ static void block_slider_render(layout_t *layout, cairo_t *cr)
pattern = slider->bar_color.pattern;
if (pattern != NULL) {
int current = slider->width * (slider->value / 100.0);
- render_capsule(cr, bar_x, bar_y, current, radius, slider->line_width);
+ render_capsule(cr, bar_x, bar_y, current, radius, radius);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_set_source(cr, pattern);
@@ -57,7 +57,8 @@ static void block_slider_render(layout_t *layout, cairo_t *cr)
pattern = slider->line_color.pattern;
if (pattern != NULL) {
- render_capsule(cr, bar_x, bar_y, slider->width, radius, slider->line_width);
+ int line_radius = radius - slider->line_width / 2;
+ render_capsule_fast(cr, bar_x, bar_y, slider->width, radius, line_radius);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_set_source(cr, pattern);
diff --git a/src/layout.c b/src/layout.c
index 193ebbd..bfc25c0 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -107,7 +107,7 @@ void layout_render(layout_t *layout, cairo_t *cr)
// Render background
cairo_pattern_t *pattern = layout->block->bg_color.pattern;
if (pattern != NULL) {
- render_capsule(cr, block_x, block_y, layout->width - layout->x_padding, radius, radius);
+ render_capsule_fast(cr, block_x, block_y, layout->width - layout->x_padding, radius, radius);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_set_source(cr, pattern);
@@ -118,7 +118,7 @@ void layout_render(layout_t *layout, cairo_t *cr)
pattern = layout->block->line_color.pattern;
if (pattern != NULL) {
int line_radius = radius - layout->line_width / 2;
- render_capsule(cr, block_x, block_y, layout->width - layout->x_padding, radius, line_radius);
+ render_capsule_fast(cr, block_x, block_y, layout->width - layout->x_padding, radius, line_radius);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_set_source(cr, pattern);
diff --git a/src/util.c b/src/util.c
index f9e00f2..b06fbae 100644
--- a/src/util.c
+++ b/src/util.c
@@ -214,9 +214,10 @@ bool iszero(const void *ptr, size_t size)
return true;
}
-void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2)
+void render_capsule_fast(cairo_t *cr, int x, int y, int w, int r1, int r2)
{
const double degree = M_PI / 180.0;
+ assert(w >= r1 * 2);
cairo_new_sub_path(cr);
cairo_arc(cr, x + r1, y + r1, r2, 90 * degree, 270 * degree);
@@ -224,6 +225,33 @@ void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2)
cairo_close_path(cr);
}
+void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2)
+{
+ // Fast path
+ if (w >= r1 * 2) {
+ render_capsule_fast(cr, x, y, w, r1, r2);
+ return;
+ }
+
+ if (w == 0) return;
+
+ const double degree = M_PI / 180.0;
+ int x_off = -(r1 - w);
+
+ double angle1 = acos(1.0 - (w / 2.0) / (double)r1);
+ double angle2 = acos(1.0 - (w / 2.0) / (double)r1);
+
+ double left1 = 180 * degree - angle2,
+ left2 = 180 * degree + angle1,
+ right1 = 360 * degree - angle2,
+ right2 = angle2;
+
+ cairo_new_sub_path(cr);
+ cairo_arc(cr, x + r1, y + r1, r2, left1, left2);
+ cairo_arc(cr, x + x_off, y + r1, r2, right1, right2);
+ cairo_close_path(cr);
+}
+
int snprintf_units(char *buffer, size_t max, uint64_t bytes, unit_t unit)
{
int base = unit & UNIT_SI ? 1000 : 1024;
diff --git a/src/util.h b/src/util.h
index e40a11a..76c87c0 100644
--- a/src/util.h
+++ b/src/util.h
@@ -85,6 +85,10 @@ void strfree(char **list);
bool iszero(const void *ptr, size_t size);
+// 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);
+
+// Render a capsule shape
void render_capsule(cairo_t *cr, int x, int y, int w, int r1, int r2);
typedef enum {