aboutsummaryrefslogtreecommitdiff
path: root/src/blocks/slider.c
blob: 708fdcaf88d8fc00ec3cac5dd1cd4196235f5f8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

#include "../block.h"
#include "../format.h"
#include "../any_log.h"

typedef struct {
    block_spec_t block;
    unsigned int value;
    unsigned int height;
    unsigned int width;
    unsigned int line_width;
    gradient_t bar_color;
    gradient_t line_color;
    gradient_t bg_color;
} block_slider_t;

static void block_slider_layout(block_t *block, layout_t *layout, layout_info_t info)
{
    block_slider_t *slider = (block_slider_t *)block;
    layout->width = info.height + slider->width;
}

static void block_slider_render(layout_t *layout, cairo_t *cr)
{
    block_slider_t *slider = (block_slider_t *)layout->block;

    int bar_y = layout->y + (layout->height - slider->height) / 2;
    int bar_x = layout->x + layout->height / 2;

    cairo_matrix_t matrix;
    cairo_matrix_init_scale(&matrix, 1.0 / slider->width, 1.0);
    cairo_matrix_translate(&matrix, -bar_x, 0.0);

    cairo_pattern_t *pattern = slider->bg_color.pattern;
    if (pattern != NULL) {
        cairo_rectangle(cr, bar_x, bar_y, slider->width, slider->height);

        cairo_pattern_set_matrix(pattern, &matrix);
        cairo_set_source(cr, pattern);
        cairo_fill(cr);
    }

    pattern = slider->bar_color.pattern;
    if (pattern != NULL) {
        cairo_rectangle(cr, bar_x, bar_y, slider->width * (slider->value / 100.0), slider->height);

        cairo_pattern_set_matrix(pattern, &matrix);
        cairo_set_source(cr, pattern);
        cairo_fill(cr);
    }

    pattern = slider->line_color.pattern;
    if (pattern != NULL) {
        cairo_rectangle(cr, bar_x, bar_y, slider->width, slider->height);

        cairo_pattern_set_matrix(pattern, &matrix);
        cairo_set_source(cr, pattern);
        cairo_set_line_width(cr, slider->line_width);
        cairo_stroke(cr);
    }
}

static void block_slider_event(layout_t *layout, event_t event)
{
    block_slider_t *slider = (block_slider_t *)layout->block;

    int bar_x = layout->x + layout->height / 2;
    int bar_y = layout->y + (layout->height - slider->height) / 2;

    log_value_debug("Clicked slider",
                    "i:bar_x", bar_x,
                    "i:bar_y", bar_y,
                    "i:bar_width", slider->width,
                    "i:bar_height", slider->height,
                    "i:value", slider->value);
}

static void block_slider_init(block_t *block, const block_scheme_t *scheme)
{
    block->type = BLOCK_SPEC;

    block_spec_t *spec = (block_spec_t *)block;
    spec->layout_fn = block_slider_layout;
    spec->render_fn = block_slider_render;
    spec->event_fn = block_slider_event;
}

static void block_slider_clean(block_t *block)
{
    block_slider_t *slider = (block_slider_t *)block;
    gradient_free(&slider->bar_color);
    gradient_free(&slider->line_color);
    gradient_free(&slider->bg_color);
}

static int block_slider_validate(block_t *block, const block_scheme_t *scheme)
{
    //block_slider_t *slider = (block_slider_t *)block;
    int errors = 0;
    // TODO

    return errors;
}

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_UINT,     NULL, offsetof(block_slider_t, value) },
    { 0 },
};

const block_scheme_t block_slider_scheme = {
    .name = "slider",
    .entries = block_slider_entries,
    .size = sizeof(block_slider_t),
    .init_fn = block_slider_init,
    .clean_fn = block_slider_clean,
    .validate_fn = block_slider_validate,
};