From 47b36bdd35921a7cddf692405542c04d8bfcd416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Dec 2018 16:20:45 +0100 Subject: [PATCH] particle/ramp: new particle, selects one particle from a list The ramp particle is configured with a tag name and a list of particles. At instantiation time, a single particle is selected from the list, depending on the tag value and it's minimum and maximum values. I.e. this particle acts kind of like a progress bar. --- CMakeLists.txt | 1 + config.c | 30 ++++++++++++++++++--- particles/ramp.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ particles/ramp.h | 5 ++++ 4 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 particles/ramp.c create mode 100644 particles/ramp.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 872b267..11ea46e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ add_executable(f00bar particles/string.c particles/string.h particles/list.c particles/list.h particles/map.c particles/map.h + particles/ramp.c particles/ramp.h modules/battery/battery.c modules/battery/battery.h modules/i3/i3.c modules/i3/i3.h diff --git a/config.c b/config.c index db87562..51d07d8 100644 --- a/config.c +++ b/config.c @@ -11,6 +11,7 @@ #include "particles/string.h" #include "particles/list.h" #include "particles/map.h" +#include "particles/ramp.h" #include "module.h" #include "modules/battery/battery.h" @@ -168,10 +169,8 @@ particle_list_from_config(const struct yml_node *node, parts[idx] = particle_from_config(it.node, parent_font); } - struct particle *list = particle_list_new( + return particle_list_new( parts, count, left_spacing, right_spacing, left_margin, right_margin); - - return list; } static struct particle * @@ -205,6 +204,29 @@ particle_map_from_config(const struct yml_node *node, const struct font *parent_ default_particle); } +static struct particle * +particle_ramp_from_config(const struct yml_node *node, const struct font *parent_font) +{ + const struct yml_node *tag = yml_get_value(node, "tag"); + const struct yml_node *items = yml_get_value(node, "items"); + + assert(yml_is_scalar(tag)); + assert(yml_is_list(items)); + + size_t count = yml_list_length(items); + struct particle *parts[count]; + + size_t idx = 0; + for (struct yml_list_iter it = yml_list_iter(items); + it.node != NULL; + yml_list_next(&it), idx++) + { + parts[idx] = particle_from_config(it.node, parent_font); + } + + return particle_ramp_new(yml_value_as_string(tag), parts, count); +} + static struct particle * particle_from_config(const struct yml_node *node, const struct font *parent_font) { @@ -220,6 +242,8 @@ particle_from_config(const struct yml_node *node, const struct font *parent_font return particle_list_from_config(pair.value, parent_font); else if (strcmp(type, "map") == 0) return particle_map_from_config(pair.value, parent_font); + else if (strcmp(type, "ramp") == 0) + return particle_ramp_from_config(pair.value, parent_font); else assert(false); } diff --git a/particles/ramp.c b/particles/ramp.c new file mode 100644 index 0000000..c9c3c24 --- /dev/null +++ b/particles/ramp.c @@ -0,0 +1,68 @@ +#include "ramp.h" + +#include +#include +#include + +#include + +struct ramp { + char *tag; + struct particle **particles; + size_t count; +}; + +static void +particle_destroy(struct particle *particle) +{ + struct ramp *ramp = particle->private; + + for (size_t i = 0; i < ramp->count; i++) + ramp->particles[i]->destroy(ramp->particles[i]); + + free(ramp->tag); + free(ramp->particles); + free(ramp); + free(particle); +} + +static struct exposable * +instantiate(const struct particle *particle, const struct tag_set *tags) +{ + const struct ramp *ramp = particle->private; + const struct tag *tag = tag_for_name(tags, ramp->tag); + assert(tag != NULL); + + long value = tag->as_int(tag); + long min = tag->min(tag); + long max = tag->max(tag); + + double progress = (double)value / (max - min); + + size_t idx = progress * ramp->count; + printf("value: %lu, min: %lu, max: %lu, progress: %f, idx: %zu\n", + value, min, max, progress, idx); + assert(idx >= 0 && idx < ramp->count); + + struct particle *p = ramp->particles[idx]; + return p->instantiate(p, tags); +} + +struct particle * +particle_ramp_new(const char *tag, struct particle *particles[], size_t count) +{ + struct particle *particle = particle_common_new(0, 0); + particle->destroy = &particle_destroy; + particle->instantiate = &instantiate; + + struct ramp *ramp = malloc(sizeof(*ramp)); + ramp->tag = strdup(tag); + ramp->particles = calloc(count, sizeof(ramp->particles[0])); + ramp->count = count; + + for (size_t i = 0; i < count; i++) + ramp->particles[i] = particles[i]; + + particle->private = ramp; + return particle; +} diff --git a/particles/ramp.h b/particles/ramp.h new file mode 100644 index 0000000..1bfa094 --- /dev/null +++ b/particles/ramp.h @@ -0,0 +1,5 @@ +#pragma once +#include "../particle.h" + +struct particle *particle_ramp_new( + const char *tag, struct particle *particles[], size_t count);