forked from external/yambar
particle/map: new particle; maps a tag value to a particle
This particle is basically a dictionary mapping tag values to particles.
This commit is contained in:
parent
cc457be4d8
commit
92c9593ff5
4 changed files with 129 additions and 2 deletions
|
@ -27,6 +27,7 @@ add_executable(foobar
|
||||||
|
|
||||||
particles/string.c particles/string.h
|
particles/string.c particles/string.h
|
||||||
particles/list.c particles/list.h
|
particles/list.c particles/list.h
|
||||||
|
particles/map.c particles/map.h
|
||||||
|
|
||||||
modules/label/label.c modules/label/label.h
|
modules/label/label.c modules/label/label.h
|
||||||
modules/clock/clock.c modules/clock/clock.h
|
modules/clock/clock.c modules/clock/clock.h
|
||||||
|
|
34
config.c
34
config.c
|
@ -10,6 +10,7 @@
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
#include "particles/string.h"
|
#include "particles/string.h"
|
||||||
#include "particles/list.h"
|
#include "particles/list.h"
|
||||||
|
#include "particles/map.h"
|
||||||
|
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "modules/label/label.h"
|
#include "modules/label/label.h"
|
||||||
|
@ -155,7 +156,7 @@ particle_list_from_config(const struct yml_node *node,
|
||||||
right_spacing = yml_value_as_int(right_spacing_node);
|
right_spacing = yml_value_as_int(right_spacing_node);
|
||||||
|
|
||||||
size_t count = yml_list_length(items_node);
|
size_t count = yml_list_length(items_node);
|
||||||
struct particle **parts = calloc(count, sizeof(*parts));
|
struct particle *parts[count];
|
||||||
|
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (struct yml_list_iter it = yml_list_iter(items_node);
|
for (struct yml_list_iter it = yml_list_iter(items_node);
|
||||||
|
@ -168,10 +169,37 @@ particle_list_from_config(const struct yml_node *node,
|
||||||
struct particle *list = particle_list_new(
|
struct particle *list = particle_list_new(
|
||||||
parts, count, left_spacing, right_spacing, left_margin, right_margin);
|
parts, count, left_spacing, right_spacing, left_margin, right_margin);
|
||||||
|
|
||||||
free(parts);
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct particle *
|
||||||
|
particle_map_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 *values = yml_get_value(node, "values");
|
||||||
|
|
||||||
|
assert(yml_is_scalar(tag));
|
||||||
|
assert(yml_is_dict(values));
|
||||||
|
|
||||||
|
printf("MAP tag: %s\n", yml_value_as_string(tag));
|
||||||
|
|
||||||
|
struct particle_map particle_map[yml_dict_length(values)];
|
||||||
|
|
||||||
|
size_t idx = 0;
|
||||||
|
for (struct yml_dict_iter it = yml_dict_iter(values);
|
||||||
|
it.key != NULL;
|
||||||
|
yml_dict_next(&it), idx++)
|
||||||
|
{
|
||||||
|
particle_map[idx].tag_value = yml_value_as_string(it.key);
|
||||||
|
particle_map[idx].particle = particle_from_config(it.value, parent_font);
|
||||||
|
assert(particle_map[idx].particle != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return particle_map_new(
|
||||||
|
yml_value_as_string(tag), particle_map, yml_dict_length(values),
|
||||||
|
NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static struct particle *
|
static struct particle *
|
||||||
particle_from_config(const struct yml_node *node, const struct font *parent_font)
|
particle_from_config(const struct yml_node *node, const struct font *parent_font)
|
||||||
{
|
{
|
||||||
|
@ -185,6 +213,8 @@ particle_from_config(const struct yml_node *node, const struct font *parent_font
|
||||||
return particle_string_from_config(pair.value, parent_font);
|
return particle_string_from_config(pair.value, parent_font);
|
||||||
else if (strcmp(type, "list") == 0)
|
else if (strcmp(type, "list") == 0)
|
||||||
return particle_list_from_config(pair.value, 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
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
85
particles/map.c
Normal file
85
particles/map.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
struct map {
|
||||||
|
char *tag;
|
||||||
|
struct particle *default_particle;
|
||||||
|
struct particle_map *map;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct exposable *
|
||||||
|
instantiate(const struct particle *particle, const struct tag_set *tags)
|
||||||
|
{
|
||||||
|
const struct map *map = particle->private;
|
||||||
|
const struct tag *tag = tag_for_name(tags, map->tag);
|
||||||
|
assert(tag != NULL || map->default_particle != NULL);
|
||||||
|
|
||||||
|
if (tag == NULL)
|
||||||
|
return map->default_particle->instantiate(map->default_particle, tags);
|
||||||
|
|
||||||
|
|
||||||
|
const char *tag_value = tag->as_string(tag);
|
||||||
|
for (size_t i = 0; i < map->count; i++) {
|
||||||
|
const struct particle_map *e = &map->map[i];
|
||||||
|
|
||||||
|
if (strcmp(e->tag_value, tag_value) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return e->particle->instantiate(e->particle, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(map->default_particle != NULL);
|
||||||
|
return map->default_particle->instantiate(map->default_particle, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
particle_destroy(struct particle *particle)
|
||||||
|
{
|
||||||
|
struct map *map = particle->private;
|
||||||
|
|
||||||
|
if (map->default_particle != NULL)
|
||||||
|
map->default_particle->destroy(map->default_particle);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < map->count; i++) {
|
||||||
|
struct particle *p = map->map[i].particle;
|
||||||
|
p->destroy(p);
|
||||||
|
free((char *)map->map[i].tag_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(map->map);
|
||||||
|
free(map->tag);
|
||||||
|
free(map);
|
||||||
|
free(particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct particle *
|
||||||
|
particle_map_new(const char *tag, const struct particle_map *particle_map,
|
||||||
|
size_t count, struct particle *default_particle,
|
||||||
|
int left_margin, int right_margin)
|
||||||
|
{
|
||||||
|
struct particle *particle = particle_common_new(left_margin, right_margin);
|
||||||
|
particle->destroy = &particle_destroy;
|
||||||
|
particle->instantiate = &instantiate;
|
||||||
|
|
||||||
|
struct map *map = malloc(sizeof(*map));
|
||||||
|
map->tag = strdup(tag);
|
||||||
|
map->default_particle = default_particle;
|
||||||
|
map->count = count;
|
||||||
|
map->map = malloc(count * sizeof(map->map[0]));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
map->map[i].tag_value = strdup(particle_map[i].tag_value);
|
||||||
|
map->map[i].particle = particle_map[i].particle;
|
||||||
|
map->map[i].particle->parent = particle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map->default_particle != NULL)
|
||||||
|
map->default_particle->parent = particle;
|
||||||
|
|
||||||
|
particle->private = map;
|
||||||
|
return particle;
|
||||||
|
}
|
11
particles/map.h
Normal file
11
particles/map.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
#include "../particle.h"
|
||||||
|
|
||||||
|
struct particle_map {
|
||||||
|
const char *tag_value;
|
||||||
|
struct particle *particle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct particle *particle_map_new(
|
||||||
|
const char *tag, const struct particle_map *particle_map, size_t count,
|
||||||
|
struct particle *default_particle, int left_margin, int right_margin);
|
Loading…
Add table
Reference in a new issue