diff --git a/config.c b/config.c index 1ccc026..c38f8d6 100644 --- a/config.c +++ b/config.c @@ -149,17 +149,22 @@ particle_simple_list_from_config(const struct yml_node *node, /* Lazy-loaded function pointer to particle_list_new() */ static struct particle *(*particle_list_new)( + struct particle *common, struct particle *particles[], size_t count, - int left_spacing, int right_spacing, int left_margin, int right_margin, - const char *on_click_template) = NULL; + int left_spacing, int right_spacing) = NULL; if (particle_list_new == NULL) { const struct plugin *plug = plugin_load("list", PLUGIN_PARTICLE); + particle_list_new = dlsym(plug->lib, "particle_list_new"); assert(particle_list_new != NULL); } - return particle_list_new(parts, count, 0, 2, 0, 0, NULL); + struct particle *common = particle_common_new( + 0, 0, NULL, font_clone(parent_font), + (struct rgba){1.0, 1.0, 1.0, 1.0}, NULL); + + return particle_list_new(common, parts, count, 0, 2); } struct particle * @@ -175,6 +180,9 @@ conf_to_particle(const struct yml_node *node, const struct font *parent_font) const struct yml_node *left_margin = yml_get_value(pair.value, "left-margin"); const struct yml_node *right_margin = yml_get_value(pair.value, "right-margin"); const struct yml_node *on_click = yml_get_value(pair.value, "on-click"); + const struct yml_node *font_node = yml_get_value(pair.value, "font"); + const struct yml_node *foreground_node = yml_get_value(pair.value, "foreground"); + const struct yml_node *deco_node = yml_get_value(pair.value, "deco"); int left = margin != NULL ? yml_value_as_int(margin) : left_margin != NULL ? yml_value_as_int(left_margin) : 0; @@ -183,19 +191,19 @@ conf_to_particle(const struct yml_node *node, const struct font *parent_font) const char *on_click_template = on_click != NULL ? yml_value_as_string(on_click) : NULL; + struct font *font = font_node != NULL + ? conf_to_font(font_node) : font_clone(parent_font); + struct rgba foreground = foreground_node != NULL + ? conf_to_color(foreground_node) : (struct rgba){1.0, 1.0, 1.0, 1.0}; + struct deco *deco = deco_node != NULL ? deco_from_config(deco_node) : NULL; + + struct particle *common = particle_common_new( + left, right, on_click_template, font, foreground, deco); const struct particle_info *info = plugin_load_particle(type); assert(info != NULL); - struct particle *ret = info->from_conf( - pair.value, parent_font, left, right, on_click_template); - - const struct yml_node *deco_node = yml_get_value(pair.value, "deco"); - - if (deco_node != NULL) - ret->deco = deco_from_config(deco_node); - - return ret; + return info->from_conf(pair.value, common); } struct bar * diff --git a/particle.c b/particle.c index 514740b..0c926bc 100644 --- a/particle.c +++ b/particle.c @@ -17,19 +17,25 @@ particle_default_destroy(struct particle *particle) { if (particle->deco != NULL) particle->deco->destroy(particle->deco); + font_destroy(particle->font); free(particle->on_click_template); free(particle); } struct particle * particle_common_new(int left_margin, int right_margin, - const char *on_click_template) + const char *on_click_template, + struct font *font, struct rgba foreground, + struct deco *deco) { struct particle *p = malloc(sizeof(*p)); p->left_margin = left_margin; p->right_margin = right_margin; - p->on_click_template = on_click_template != NULL ? strdup(on_click_template) : NULL; - p->deco = NULL; + p->on_click_template = + on_click_template != NULL ? strdup(on_click_template) : NULL; + p->foreground = foreground; + p->font = font; + p->deco = deco; return p; } diff --git a/particle.h b/particle.h index f867578..7518374 100644 --- a/particle.h +++ b/particle.h @@ -1,5 +1,4 @@ #pragma once - #include #include "color.h" @@ -15,10 +14,7 @@ struct exposable; struct particle_info { bool (*verify_conf)(keychain_t *chain, const struct yml_node *node); - struct particle *(*from_conf)(const struct yml_node *node, - const struct font *parent_font, - int left_margin, int right_margin, - const char *on_click_template); + struct particle *(*from_conf)(const struct yml_node *node, struct particle *common); #define PARTICLE_COMMON_ATTRS_COUNT 5 #define PARTICLE_COMMON_ATTRS \ @@ -26,6 +22,8 @@ struct particle_info { {"left-margin", false, &conf_verify_int}, \ {"right-margin", false, &conf_verify_int}, \ {"on-click", false, &conf_verify_string}, \ + {"font", false, &conf_verify_font}, \ + {"foreground", false, &conf_verify_color}, \ {"deco", false, &conf_verify_decoration}, \ {NULL, false, NULL} @@ -35,9 +33,12 @@ struct particle { void *private; int left_margin, right_margin; - struct deco *deco; char *on_click_template; + struct rgba foreground; + struct font *font; + struct deco *deco; + void (*destroy)(struct particle *particle); struct exposable *(*instantiate)(const struct particle *particle, const struct tag_set *tags); @@ -64,8 +65,10 @@ struct exposable { enum mouse_event event, int x, int y); }; -struct particle *particle_common_new(int left_margin, int right_margin, - const char *on_click_template); +struct particle *particle_common_new( + int left_margin, int right_margin, const char *on_click_template, + struct font *font, struct rgba foreground, struct deco *deco); + void particle_default_destroy(struct particle *particle); struct exposable *exposable_common_new( diff --git a/particles/empty.c b/particles/empty.c index dde25d0..12151f3 100644 --- a/particles/empty.c +++ b/particles/empty.c @@ -32,20 +32,17 @@ instantiate(const struct particle *particle, const struct tag_set *tags) } static struct particle * -empty_new(int left_margin, int right_margin, const char *on_click_template) +empty_new(struct particle *common) { - struct particle *particle = particle_common_new( - left_margin, right_margin, on_click_template); - particle->destroy = &particle_default_destroy; - particle->instantiate = &instantiate; - return particle; + common->destroy = &particle_default_destroy; + common->instantiate = &instantiate; + return common; } static struct particle * -from_conf(const struct yml_node *node, const struct font *parent_font, - int left_margin, int right_margin, const char *on_click_template) +from_conf(const struct yml_node *node, struct particle *common) { - return empty_new(left_margin, right_margin, on_click_template); + return empty_new(common); } static bool diff --git a/particles/list.c b/particles/list.c index fadac6f..10da4b4 100644 --- a/particles/list.c +++ b/particles/list.c @@ -143,10 +143,9 @@ particle_destroy(struct particle *particle) } struct particle * -particle_list_new( - struct particle *particles[], size_t count, - int left_spacing, int right_spacing, int left_margin, int right_margin, - const char *on_click_template) +particle_list_new(struct particle *common, + struct particle *particles[], size_t count, + int left_spacing, int right_spacing) { struct private *p = malloc(sizeof(*p)); p->particles = malloc(count * sizeof(p->particles[0])); @@ -157,22 +156,16 @@ particle_list_new( for (size_t i = 0; i < count; i++) p->particles[i] = particles[i]; - struct particle *particle = particle_common_new( - left_margin, right_margin, on_click_template); - - particle->private = p; - particle->destroy = &particle_destroy; - particle->instantiate = &instantiate; - - return particle; + common->private = p; + common->destroy = &particle_destroy; + common->instantiate = &instantiate; + return common; } static struct particle * -from_conf(const struct yml_node *node, const struct font *parent_font, - int left_margin, int right_margin, const char *on_click_template) +from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *items = yml_get_value(node, "items"); - const struct yml_node *spacing = yml_get_value(node, "spacing"); const struct yml_node *_left_spacing = yml_get_value(node, "left-spacing"); const struct yml_node *_right_spacing = yml_get_value(node, "right-spacing"); @@ -190,12 +183,10 @@ from_conf(const struct yml_node *node, const struct font *parent_font, it.node != NULL; yml_list_next(&it), idx++) { - parts[idx] = conf_to_particle(it.node, parent_font); + parts[idx] = conf_to_particle(it.node, common->font); } - return particle_list_new( - parts, count, left_spacing, right_spacing, left_margin, right_margin, - on_click_template); + return particle_list_new(common, parts, count, left_spacing, right_spacing); } static bool diff --git a/particles/list.h b/particles/list.h index 01dabb4..3ac9768 100644 --- a/particles/list.h +++ b/particles/list.h @@ -2,8 +2,8 @@ #include "../particle.h" struct particle *particle_list_new( + struct particle *common, struct particle *particles[], size_t count, - int left_spacing, int right_spacing, int left_margin, int right_margin, - const char *on_click_template); + int left_spacing, int right_spacing); extern const struct particle_info particle_list; diff --git a/particles/map.c b/particles/map.c index fda5a02..e9bf03b 100644 --- a/particles/map.c +++ b/particles/map.c @@ -146,16 +146,10 @@ particle_destroy(struct particle *particle) } static struct 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, - const char *on_click_template) +map_new(struct particle *common, const char *tag, + const struct particle_map particle_map[], size_t count, + struct particle *default_particle) { - struct particle *particle = particle_common_new( - left_margin, right_margin, on_click_template); - particle->destroy = &particle_destroy; - particle->instantiate = &instantiate; - struct private *priv = malloc(sizeof(*priv)); priv->tag = strdup(tag); priv->default_particle = default_particle; @@ -167,8 +161,10 @@ map_new(const char *tag, const struct particle_map *particle_map, priv->map[i].particle = particle_map[i].particle; } - particle->private = priv; - return particle; + common->private = priv; + common->destroy = &particle_destroy; + common->instantiate = &instantiate; + return common; } static bool @@ -201,8 +197,7 @@ verify_map_values(keychain_t *chain, const struct yml_node *node) } static struct particle * -from_conf(const struct yml_node *node, const struct font *parent_font, - int left_margin, int right_margin, const char *on_click_template) +from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); const struct yml_node *values = yml_get_value(node, "values"); @@ -216,16 +211,15 @@ from_conf(const struct yml_node *node, const struct font *parent_font, yml_dict_next(&it), idx++) { particle_map[idx].tag_value = yml_value_as_string(it.key); - particle_map[idx].particle = conf_to_particle(it.value, parent_font); + particle_map[idx].particle = conf_to_particle(it.value, common->font); } struct particle *default_particle = def != NULL - ? conf_to_particle(def, parent_font) - : NULL; + ? conf_to_particle(def, common->font) : NULL; return map_new( - yml_value_as_string(tag), particle_map, yml_dict_length(values), - default_particle, left_margin, right_margin, on_click_template); + common, yml_value_as_string(tag), particle_map, yml_dict_length(values), + default_particle); } static bool diff --git a/particles/progress-bar.c b/particles/progress-bar.c index 2f110fd..169592a 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -208,13 +208,10 @@ instantiate(const struct particle *particle, const struct tag_set *tags) } static struct particle * -progress_bar_new(const char *tag, int width, - struct particle *start_marker, - struct particle *end_marker, +progress_bar_new(struct particle *common, const char *tag, int width, + struct particle *start_marker, struct particle *end_marker, struct particle *fill, struct particle *empty, - struct particle *indicator, - int left_margin, int right_margin, - const char *on_click_template) + struct particle *indicator) { struct private *priv = malloc(sizeof(*priv)); priv->tag = strdup(tag); @@ -225,18 +222,14 @@ progress_bar_new(const char *tag, int width, priv->empty = empty; priv->indicator = indicator; - struct particle *particle = particle_common_new( - left_margin, right_margin, on_click_template); - particle->private = priv; - particle->destroy = &particle_destroy; - particle->instantiate = &instantiate; - - return particle; + common->private = priv; + common->destroy = &particle_destroy; + common->instantiate = &instantiate; + return common; } static struct particle * -from_conf(const struct yml_node *node, const struct font *parent_font, - int left_margin, int right_margin, const char *on_click_template) +from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); const struct yml_node *length = yml_get_value(node, "length"); @@ -247,14 +240,14 @@ from_conf(const struct yml_node *node, const struct font *parent_font, const struct yml_node *indicator = yml_get_value(node, "indicator"); return progress_bar_new( + common, yml_value_as_string(tag), yml_value_as_int(length), - conf_to_particle(start, parent_font), - conf_to_particle(end, parent_font), - conf_to_particle(fill, parent_font), - conf_to_particle(empty, parent_font), - conf_to_particle(indicator, parent_font), - left_margin, right_margin, on_click_template); + conf_to_particle(start, common->font), + conf_to_particle(end, common->font), + conf_to_particle(fill, common->font), + conf_to_particle(empty, common->font), + conf_to_particle(indicator, common->font)); } static bool diff --git a/particles/ramp.c b/particles/ramp.c index e7ecaf3..3d912ed 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -135,13 +135,9 @@ instantiate(const struct particle *particle, const struct tag_set *tags) } static struct particle * -ramp_new(const char *tag, struct particle *particles[], size_t count, - int left_margin, int right_margin, const char *on_click_template) +ramp_new(struct particle *common, const char *tag, + struct particle *particles[], size_t count) { - struct particle *particle = particle_common_new( - left_margin, right_margin, on_click_template); - particle->destroy = &particle_destroy; - particle->instantiate = &instantiate; struct private *priv = malloc(sizeof(*priv)); priv->tag = strdup(tag); @@ -151,13 +147,14 @@ ramp_new(const char *tag, struct particle *particles[], size_t count, for (size_t i = 0; i < count; i++) priv->particles[i] = particles[i]; - particle->private = priv; - return particle; + common->private = priv; + common->destroy = &particle_destroy; + common->instantiate = &instantiate; + return common; } static struct particle * -from_conf(const struct yml_node *node, const struct font *parent_font, - int left_margin, int right_margin, const char *on_click_template) +from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); const struct yml_node *items = yml_get_value(node, "items"); @@ -170,12 +167,10 @@ from_conf(const struct yml_node *node, const struct font *parent_font, it.node != NULL; yml_list_next(&it), idx++) { - parts[idx] = conf_to_particle(it.node, parent_font); + parts[idx] = conf_to_particle(it.node, common->font); } - return ramp_new( - yml_value_as_string(tag), parts, count, left_margin, right_margin, - on_click_template); + return ramp_new(common, yml_value_as_string(tag), parts, count); } static bool diff --git a/particles/string.c b/particles/string.c index b008805..152ca57 100644 --- a/particles/string.c +++ b/particles/string.c @@ -12,17 +12,10 @@ struct private { char *text; size_t max_len; - - struct font *font; - struct rgba foreground; }; struct eprivate { char *text; - - const struct font *font; - struct rgba foreground; - cairo_text_extents_t extents; }; @@ -40,7 +33,7 @@ begin_expose(struct exposable *exposable) { struct eprivate *e = exposable->private; - cairo_scaled_font_t *scaled = font_scaled_font(e->font); + cairo_scaled_font_t *scaled = font_scaled_font(exposable->particle->font); cairo_scaled_font_text_extents(scaled, e->text, &e->extents); exposable->width = (exposable->particle->left_margin + @@ -58,7 +51,7 @@ expose(const struct exposable *exposable, cairo_t *cr, int x, int y, int height) const struct eprivate *e = exposable->private; const size_t text_len = strlen(e->text); - cairo_scaled_font_t *scaled = font_scaled_font(e->font); + cairo_scaled_font_t *scaled = font_scaled_font(exposable->particle->font); cairo_glyph_t *glyphs = NULL; cairo_text_cluster_t *clusters = NULL; @@ -73,10 +66,10 @@ expose(const struct exposable *exposable, cairo_t *cr, int x, int y, int height) cairo_set_scaled_font(cr, scaled); cairo_set_source_rgba(cr, - e->foreground.red, - e->foreground.green, - e->foreground.blue, - e->foreground.alpha); + exposable->particle->foreground.red, + exposable->particle->foreground.green, + exposable->particle->foreground.blue, + exposable->particle->foreground.alpha); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_show_text_glyphs( @@ -94,8 +87,6 @@ instantiate(const struct particle *particle, const struct tag_set *tags) struct eprivate *e = malloc(sizeof(*e)); e->text = tags_expand_template(p->text, tags); - e->font = p->font; - e->foreground = p->foreground; memset(&e->extents, 0, sizeof(e->extents)); if (p->max_len > 0) { @@ -125,50 +116,34 @@ static void particle_destroy(struct particle *particle) { struct private *p = particle->private; - font_destroy(p->font); free(p->text); free(p); particle_default_destroy(particle); } static struct particle * -string_new(const char *text, size_t max_len, struct font *font, - struct rgba foreground, int left_margin, int right_margin, - const char *on_click_template) +string_new(struct particle *common, const char *text, size_t max_len) { struct private *p = malloc(sizeof(*p)); p->text = strdup(text); p->max_len = max_len; - p->font = font; - p->foreground = foreground; - struct particle *particle = particle_common_new( - left_margin, right_margin, on_click_template); - - particle->private = p; - particle->destroy = &particle_destroy; - particle->instantiate = &instantiate; - - return particle; + common->private = p; + common->destroy = &particle_destroy; + common->instantiate = &instantiate; + return common; } static struct particle * -from_conf(const struct yml_node *node, const struct font *parent_font, - int left_margin, int right_margin, const char *on_click_template) +from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *text = yml_get_value(node, "text"); const struct yml_node *max = yml_get_value(node, "max"); - const struct yml_node *font = yml_get_value(node, "font"); - const struct yml_node *foreground = yml_get_value(node, "foreground"); - - struct rgba fg_color = foreground != NULL - ? conf_to_color(foreground) : (struct rgba){1.0, 1.0, 1.0, 1.0}; return string_new( + common, yml_value_as_string(text), - max != NULL ? yml_value_as_int(max) : 0, - font != NULL ? conf_to_font(font) : font_clone(parent_font), - fg_color, left_margin, right_margin, on_click_template); + max != NULL ? yml_value_as_int(max) : 0); } static bool @@ -177,8 +152,6 @@ verify_conf(keychain_t *chain, const struct yml_node *node) static const struct attr_info attrs[] = { {"text", true, &conf_verify_string}, {"max", false, &conf_verify_int}, - {"font", false, &conf_verify_font}, - {"foreground", false, &conf_verify_color}, PARTICLE_COMMON_ATTRS, };