aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blocks/slider.c122
-rw-r--r--src/util.c4
2 files changed, 89 insertions, 37 deletions
diff --git a/src/blocks/slider.c b/src/blocks/slider.c
index f80c71b..98ce645 100644
--- a/src/blocks/slider.c
+++ b/src/blocks/slider.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
+#include <math.h>
#include "../block.h"
#include "../format.h"
@@ -9,13 +10,9 @@
typedef enum {
KNOB_NONE,
- KNOB_CIRCLE,
- //KNOB_CAPSULE,
+ KNOB_CAPSULE,
KNOB_TRIANGLE,
- //KNOB_TRIANGLE_UP,
- //KNOB_TRIANGLE_DOWN,
- //KNOB_TRIANGLE_LEFT,
- //KNOB_TRIANGLE_RIGHT,
+ KNOB_RECTANGLE,
} block_slider_knob_t;
typedef struct {
@@ -30,11 +27,13 @@ typedef struct {
bool seekable;
block_slider_knob_t knob;
unsigned int knob_height;
+ unsigned int knob_width;
unsigned int knob_line_width;
int knob_x_offset;
int knob_y_offset;
gradient_t knob_color;
gradient_t knob_line_color;
+ double knob_rotation;
} block_slider_t;
static void block_slider_layout(block_t *block, layout_t *layout, layout_info_t info)
@@ -66,7 +65,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);
+ int current = (slider->width * slider->value) / 100;
render_capsule(cr, bar_x, bar_y, current, radius, radius);
cairo_pattern_set_matrix(pattern, &matrix);
@@ -85,48 +84,84 @@ static void block_slider_render(layout_t *layout, cairo_t *cr)
cairo_stroke(cr);
}
- if (slider->knob == KNOB_NONE) return;
+ if (slider->knob == KNOB_NONE || slider->knob_width == 0 || slider->knob_height == 0)
+ return;
- int knob_height = slider->knob_height != 0 ? slider->knob_height : slider->height;
+ int knob_height = slider->knob_height;
+ int knob_width = slider->knob_width;
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;
+ int knob_rw = knob_width * cos(slider->knob_rotation) + knob_height * sin(slider->knob_rotation);
+ int current = (slider->value * (slider->width - knob_rw)) / 100;
- // FIXME
- int current = (slider->width - knob_width) * slider->value / 100.0;
-
- int knob_x = bar_x + slider->knob_x_offset + current;
+ int knob_x = bar_x + slider->line_width + slider->knob_x_offset + current - knob_rw / 2;
int knob_y = bar_y + slider->knob_y_offset + radius - knob_radius;
+ int t_x = knob_x + knob_width / 2;
+ int t_y = knob_y + knob_height / 2;
+
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_save(cr);
+
+ cairo_translate(cr, t_x, t_y);
+ cairo_rotate(cr, slider->knob_rotation);
+ cairo_translate(cr, -t_x, -t_y);
+
+ switch (slider->knob) {
+ case KNOB_CAPSULE:
+ render_capsule(cr, knob_x, knob_y, knob_width, knob_radius, knob_radius);
+ break;
+
+ case KNOB_TRIANGLE:
+ render_triangle(cr, knob_x, knob_y, knob_width, knob_height);
+ break;
+
+ case KNOB_RECTANGLE:
+ cairo_rectangle(cr, knob_x, knob_y, knob_width, knob_height);
+ break;
+
+ default:
+ unreachable();
+ }
+
+ cairo_restore(cr);
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_save(cr);
+
+ cairo_translate(cr, t_x, t_y);
+ cairo_rotate(cr, slider->knob_rotation);
+ cairo_translate(cr, -t_x, -t_y);
+
+ switch (slider->knob) {
+ case KNOB_CAPSULE: {
+ int line_radius = knob_radius - slider->knob_line_width / 2;
+ render_capsule(cr, knob_x, knob_y, knob_width, knob_radius, line_radius);
+ break;
+ }
+
+ case KNOB_TRIANGLE:
+ render_triangle(cr, knob_x, knob_y, knob_width, knob_height);
+ break;
+
+ case KNOB_RECTANGLE:
+ cairo_rectangle(cr, knob_x, knob_y, knob_width, knob_height);
+ break;
+
+ default:
+ unreachable();
+ }
+
+ cairo_restore(cr);
cairo_stroke(cr);
}
}
@@ -175,6 +210,8 @@ static void block_slider_clean(block_t *block)
gradient_free(&slider->bar_color);
gradient_free(&slider->line_color);
gradient_free(&slider->bg_color);
+ gradient_free(&slider->knob_color);
+ gradient_free(&slider->knob_line_color);
}
static int block_slider_validate(block_t *block, const block_scheme_t *scheme)
@@ -187,14 +224,27 @@ static int block_slider_validate(block_t *block, const block_scheme_t *scheme)
errors++;
}
+ if (slider->knob_width < slider->knob_height) {
+ log_error("Block '%s' requires '%s' greater than '%s'", block->label, "knob-width", "knob-height");
+ errors++;
+ }
+
+ if (fabs(slider->knob_rotation) > 360.0) {
+ log_error("Block '%s' requires '%s' to be at most 360", block->label, "knob-rotation");
+ errors++;
+ }
+
+ const double degree = M_PI / 180.0;
+ slider->knob_rotation *= degree;
+
return errors;
}
static config_enum_t knob_shape_enum[] = {
- { "none", KNOB_NONE },
- { "circle", KNOB_CIRCLE },
- //{ "capsule", KNOB_CAPSULE },
- { "triangle", KNOB_TRIANGLE },
+ { "none", KNOB_NONE },
+ { "capsule", KNOB_CAPSULE },
+ { "triangle", KNOB_TRIANGLE },
+ { "rectangle", KNOB_RECTANGLE },
{ 0 },
};
@@ -210,11 +260,13 @@ static const config_entry_t block_slider_entries[] = {
{ "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-width", CONFIG_UINT, NULL, offsetof(block_slider_t, knob_width) },
{ "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) },
+ { "knob-rotation", CONFIG_DOUBLE, NULL, offsetof(block_slider_t, knob_rotation) },
{ 0 },
};
diff --git a/src/util.c b/src/util.c
index 580c360..ca848ec 100644
--- a/src/util.c
+++ b/src/util.c
@@ -217,9 +217,9 @@ bool iszero(const void *ptr, size_t size)
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_line_to(cr, x + w, y + h);
+ cairo_line_to(cr, x + w / 2, y);
cairo_close_path(cr);
}