Adds fg_middle + fg_end color option for the graph widget
Draws a color-gradient beginning from fg and if either fg_middle or fg_end is set, through them. example config: graph gr_cpu { data { scale = false max = 100 style = bottom fg = "#cc6666" fg_half = "#cc6666" fg_full = "#998888"} ... ... } Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
b7e379c2d0
commit
ff753f1f14
|
@ -134,6 +134,8 @@ cfg_opt_t widget_graph_data_opts[] =
|
|||
CFG_FLOAT((char *) "max", 100.0f, CFGF_NONE),
|
||||
CFG_BOOL((char *) "scale", cfg_false, CFGF_NONE),
|
||||
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
|
||||
CFG_STR((char *) "fg_middle", (char *) NULL, CFGF_NONE),
|
||||
CFG_STR((char *) "fg_end", (char *) NULL, CFGF_NONE),
|
||||
CFG_STR((char *) "style", (char *) "bottom", CFGF_NONE),
|
||||
CFG_END()
|
||||
};
|
||||
|
|
116
common/draw.c
116
common/draw.c
|
@ -182,6 +182,47 @@ draw_text(DrawCtx *ctx,
|
|||
cairo_font_face_destroy(font_face);
|
||||
}
|
||||
|
||||
/** Setup color-source for cairo (gradient or mono)
|
||||
* \param ctx Draw context
|
||||
* \param x x-offset of widget
|
||||
* \param y y-offset of widget
|
||||
* \param width width in pixels
|
||||
* \param color color to use from 0%
|
||||
* \param pcolor_middle color at 50% of width
|
||||
* \param pcolor_end color at 100% of width
|
||||
* \return pat pattern or NULL; needs to get cairo_pattern_destroy()'ed;
|
||||
*/
|
||||
cairo_pattern_t *
|
||||
setup_cairo_color_source(DrawCtx *ctx, int x, int y, int width,
|
||||
XColor color, XColor *pcolor_middle, XColor *pcolor_end)
|
||||
{
|
||||
cairo_pattern_t *pat;
|
||||
|
||||
if(pcolor_middle || pcolor_end) /* draw a gradient */
|
||||
{
|
||||
pat = cairo_pattern_create_linear(x, y, x + width, y);
|
||||
|
||||
cairo_pattern_add_color_stop_rgb(pat, 0, color.red / 65535.0,
|
||||
color.green / 65535.0, color.blue / 65535.0);
|
||||
if(pcolor_middle)
|
||||
cairo_pattern_add_color_stop_rgb(pat, 0.5, pcolor_middle->red / 65535.0,
|
||||
pcolor_middle->green / 65535.0, pcolor_middle->blue / 65535.0);
|
||||
if(pcolor_end)
|
||||
cairo_pattern_add_color_stop_rgb(pat, 1, pcolor_end->red / 65535.0,
|
||||
pcolor_end->green / 65535.0, pcolor_end->blue / 65535.0);
|
||||
else
|
||||
cairo_pattern_add_color_stop_rgb(pat, 1, color.red / 65535.0,
|
||||
color.green / 65535.0, color.blue / 65535.0);
|
||||
cairo_set_source(ctx->cr, pat);
|
||||
return pat;
|
||||
}
|
||||
else /* no gradient */
|
||||
{
|
||||
cairo_set_source_rgb(ctx->cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw rectangle
|
||||
* \param ctx Draw context
|
||||
* \param geometry geometry
|
||||
|
@ -205,39 +246,26 @@ draw_rectangle(DrawCtx *ctx, Area geometry, Bool filled, XColor color)
|
|||
cairo_stroke(ctx->cr);
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw rectangle with gradient colors
|
||||
* \param ctx Draw context
|
||||
* \param geometry geometry
|
||||
* \param fullwidth width of full bar in pixels
|
||||
* \param filled filled rectangle?
|
||||
* \param color color to use from 0%
|
||||
* \param color_half color at 50%
|
||||
* \param color_full color at 100%
|
||||
* \param pcolor_half color at 50%
|
||||
* \param pcolor_full color at 100%
|
||||
*/
|
||||
void
|
||||
draw_rectangle_gradient(DrawCtx *ctx, Area geometry, int fullwidth, Bool filled,
|
||||
XColor color, XColor * color_half, XColor * color_full)
|
||||
XColor color, XColor *pcolor_half, XColor *pcolor_full)
|
||||
{
|
||||
cairo_pattern_t *pat;
|
||||
|
||||
cairo_set_antialias(ctx->cr, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_line_width(ctx->cr, 1.0);
|
||||
|
||||
pat = cairo_pattern_create_linear(geometry.x, geometry.y, geometry.x + fullwidth, geometry.y);
|
||||
cairo_pattern_add_color_stop_rgb(pat, 0, color.red / 65535.0,
|
||||
color.green / 65535.0, color.blue / 65535.0);
|
||||
if(color_half)
|
||||
cairo_pattern_add_color_stop_rgb(pat, 0.5, color_half->red / 65535.0,
|
||||
color_half->green / 65535.0, color_half->blue / 65535.0);
|
||||
if(color_full)
|
||||
cairo_pattern_add_color_stop_rgb(pat, 1, color_full->red / 65535.0,
|
||||
color_full->green / 65535.0, color_full->blue / 65535.0);
|
||||
else
|
||||
cairo_pattern_add_color_stop_rgb(pat, 1, color.red / 65535.0,
|
||||
color.green / 65535.0, color.blue / 65535.0);
|
||||
|
||||
cairo_set_source(ctx->cr, pat);
|
||||
pat = setup_cairo_color_source(ctx, geometry.x, geometry.y, fullwidth,
|
||||
color, pcolor_half, pcolor_full);
|
||||
|
||||
if(filled)
|
||||
{
|
||||
|
@ -250,10 +278,13 @@ draw_rectangle_gradient(DrawCtx *ctx, Area geometry, int fullwidth, Bool filled,
|
|||
cairo_stroke(ctx->cr);
|
||||
}
|
||||
|
||||
if(pat)
|
||||
cairo_pattern_destroy(pat);
|
||||
}
|
||||
|
||||
/* draw_graph functions */
|
||||
/** Setup some cairo-things for drawing a graph
|
||||
* \param ctx Draw context
|
||||
*/
|
||||
void
|
||||
draw_graph_setup(DrawCtx *ctx)
|
||||
{
|
||||
|
@ -262,16 +293,25 @@ draw_graph_setup(DrawCtx *ctx)
|
|||
/* without it, it can draw over the path on sharp angles (...too long lines) */
|
||||
cairo_set_line_join (ctx->cr, CAIRO_LINE_JOIN_ROUND);
|
||||
}
|
||||
|
||||
/* draws a graph; it takes the line-lengths from *from and *to. It cycles
|
||||
* backwards through those arrays (what have the length of w), beginning at
|
||||
* position cur_index, until cur_index is reached again (wrapped around). */
|
||||
/** Draw a graph
|
||||
* \param ctx Draw context
|
||||
* \param x x-offset of widget
|
||||
* \param y y-offset of widget
|
||||
* \param w width in pixels
|
||||
* \param from array of starting-point offsets to draw a graph-lines
|
||||
* \param to array of end-point offsets to draw a graph-lines
|
||||
* \param cur_index current position in data-array (cycles around)
|
||||
* \param color color to use from 0%
|
||||
* \param pcolor_middle color at 50%
|
||||
* \param pcolor_end color at 100%
|
||||
*/
|
||||
void
|
||||
draw_graph(DrawCtx *ctx, int x, int y, int w, int *from, int *to, int cur_index, XColor color)
|
||||
draw_graph(DrawCtx *ctx, int x, int y, int w, int *from, int *to, int cur_index,
|
||||
XColor color, XColor *pcolor_middle, XColor *pcolor_end)
|
||||
{
|
||||
int i;
|
||||
|
||||
cairo_set_source_rgb(ctx->cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
|
||||
cairo_pattern_t *pat;
|
||||
pat = setup_cairo_color_source(ctx, x, y, w, color, pcolor_middle, pcolor_end);
|
||||
|
||||
i = -1;
|
||||
while(++i < w)
|
||||
|
@ -285,13 +325,30 @@ draw_graph(DrawCtx *ctx, int x, int y, int w, int *from, int *to, int cur_index,
|
|||
}
|
||||
|
||||
cairo_stroke(ctx->cr);
|
||||
|
||||
if(pat)
|
||||
cairo_pattern_destroy(pat);
|
||||
}
|
||||
/** Draw a line into a graph-widget
|
||||
* \param ctx Draw context
|
||||
* \param x x-offset of widget
|
||||
* \param y y-offset of widget
|
||||
* \param w width in pixels
|
||||
* \param to array of offsets to draw the line through...
|
||||
* \param cur_index current position in data-array (cycles around)
|
||||
* \param color color to use from 0%
|
||||
* \param pcolor_middle color at 50%
|
||||
* \param pcolor_end color at 100%
|
||||
*/
|
||||
void
|
||||
draw_graph_line(DrawCtx *ctx, int x, int y, int w, int *to, int cur_index, XColor color)
|
||||
draw_graph_line(DrawCtx *ctx, int x, int y, int w, int *to, int cur_index,
|
||||
XColor color, XColor *pcolor_middle, XColor *pcolor_end)
|
||||
{
|
||||
int i;
|
||||
int flag = 0; /* used to prevent drawing a line from 0 to 0 values */
|
||||
cairo_set_source_rgb(ctx->cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
|
||||
cairo_pattern_t *pat;
|
||||
|
||||
pat = setup_cairo_color_source(ctx, x, y, w, color, pcolor_middle, pcolor_end);
|
||||
|
||||
/* x-1 (on the border), paints *from* the last point (... not included itself) */
|
||||
/* makes sense when you assume there is already some line drawn to it. */
|
||||
|
@ -320,6 +377,9 @@ draw_graph_line(DrawCtx *ctx, int x, int y, int w, int *to, int cur_index, XColo
|
|||
x++;
|
||||
}
|
||||
cairo_stroke(ctx->cr);
|
||||
|
||||
if(pat)
|
||||
cairo_pattern_destroy(pat);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -97,10 +97,10 @@ void draw_text(DrawCtx *, Area, Alignment, int, XftFont *, char *, XColor fg, XC
|
|||
void draw_rectangle(DrawCtx *, Area, Bool, XColor);
|
||||
void draw_rectangle_gradient(DrawCtx *, Area, int, Bool, XColor, XColor *, XColor *);
|
||||
|
||||
cairo_pattern_t * setup_cairo_color_source(DrawCtx *, int, int, int, XColor, XColor *, XColor *);
|
||||
void draw_graph_setup(DrawCtx *);
|
||||
void draw_graph(DrawCtx *, int, int, int, int *, int *, int, XColor);
|
||||
void draw_graph_line(DrawCtx *, int, int, int, int *, int, XColor);
|
||||
|
||||
void draw_graph(DrawCtx *, int, int, int, int *, int *, int, XColor, XColor *, XColor *);
|
||||
void draw_graph_line(DrawCtx *, int, int, int, int *, int, XColor, XColor *, XColor *);
|
||||
void draw_circle(DrawCtx *, int, int, int, Bool, XColor);
|
||||
void draw_image(DrawCtx *, int, int, int, const char *);
|
||||
void draw_image_from_argb_data(DrawCtx *, int, int, int, int, int, unsigned char *);
|
||||
|
|
|
@ -30,38 +30,44 @@ extern AwesomeConf globalconf;
|
|||
typedef struct
|
||||
{
|
||||
/* general layout */
|
||||
float *max; /* Represents a full graph */
|
||||
int width; /* Width of the widget */
|
||||
float height; /* Height of graph (0-1, where 1 is height of statusbar) */
|
||||
int box_height; /* Height of the innerbox in pixels */
|
||||
int padding_left; /* Left padding */
|
||||
int size; /* Size of lines-array (also innerbox-lenght) */
|
||||
XColor bg; /* Background color */
|
||||
XColor bordercolor; /* Border color */
|
||||
float *max; /** Represents a full graph */
|
||||
int width; /** Width of the widget */
|
||||
float height; /** Height of graph (0-1; 1 = height of statusbar) */
|
||||
int box_height; /** Height of the innerbox in pixels */
|
||||
int padding_left; /** Left padding */
|
||||
int size; /** Size of lines-array (also innerbox-lenght) */
|
||||
XColor bg; /** Background color */
|
||||
XColor bordercolor; /** Border color */
|
||||
|
||||
/* markers... */
|
||||
int index; /* Index of current (new) value */
|
||||
int *max_index; /* Index of the actual maximum value */
|
||||
float *current_max; /* Pointer to current maximum value itself */
|
||||
int index; /** Index of current (new) value */
|
||||
int *max_index; /** Index of the actual maximum value */
|
||||
float *current_max; /** Pointer to current maximum value itself */
|
||||
|
||||
/* all data is stored here */
|
||||
int data_items; /* Number of data-input items */
|
||||
int **lines; /* Keeps the calculated values (line-length); */
|
||||
float **values; /* Actual values */
|
||||
int data_items; /** Number of data-input items */
|
||||
int **lines; /** Keeps the calculated values (line-length); */
|
||||
float **values; /** Actual values */
|
||||
|
||||
/* additional data + a pointer to **lines accordingly */
|
||||
int **fillbottom; /* datatypes holder (same as some **lines pointer) */
|
||||
int fillbottom_total; /* total of them */
|
||||
XColor *fillbottom_color; /* color of them */
|
||||
int **filltop; /* datatypes holder */
|
||||
int filltop_total; /* total of them */
|
||||
XColor *filltop_color; /* color of them */
|
||||
int **drawline; /* datatypes holder */
|
||||
int drawline_total; /* total of them */
|
||||
XColor *drawline_color; /* color of them */
|
||||
int **fillbottom; /** Datatypes holder (data equal to **lines) */
|
||||
int fillbottom_total; /** Total of them */
|
||||
XColor *fillbottom_color; /** Color of them */
|
||||
XColor **fillbottom_pcolor_middle; /** Color at middle of graph */
|
||||
XColor **fillbottom_pcolor_end; /** Color at end of graph */
|
||||
int **filltop; /** Datatypes holder */
|
||||
int filltop_total; /** Total of them */
|
||||
XColor *filltop_color; /** Color of them */
|
||||
XColor **filltop_pcolor_middle; /** Color at middle of graph */
|
||||
XColor **filltop_pcolor_end; /** Color at end of graph */
|
||||
int **drawline; /** Datatypes holder */
|
||||
int drawline_total; /** Total of them */
|
||||
XColor *drawline_color; /** Color of them */
|
||||
XColor **drawline_pcolor_middle; /** Color at middle of graph */
|
||||
XColor **drawline_pcolor_end; /** Color at end of graph */
|
||||
|
||||
int *draw_from; /* Preparation/tmp array for draw_graph(); */
|
||||
int *draw_to; /* Preparation/tmp array for draw_graph(); */
|
||||
int *draw_from; /** Preparation/tmp array for draw_graph(); */
|
||||
int *draw_to; /** Preparation/tmp array for draw_graph(); */
|
||||
|
||||
} Data;
|
||||
|
||||
|
@ -124,7 +130,7 @@ graph_draw(Widget *widget, DrawCtx *ctx, int offset,
|
|||
draw_graph(ctx,
|
||||
left_offset + 2, margin_top + d->box_height + 1,
|
||||
d->size, d->draw_from, d->draw_to, d->index,
|
||||
d->filltop_color[z]);
|
||||
d->filltop_color[z], d->filltop_pcolor_middle[z], d->filltop_pcolor_end[z]);
|
||||
}
|
||||
|
||||
/* draw style = bottom */
|
||||
|
@ -146,7 +152,7 @@ graph_draw(Widget *widget, DrawCtx *ctx, int offset,
|
|||
draw_graph(ctx,
|
||||
left_offset + 2, margin_top + d->box_height + 1,
|
||||
d->size, d->draw_from, d->fillbottom[z], d->index,
|
||||
d->fillbottom_color[z]);
|
||||
d->fillbottom_color[z], d->fillbottom_pcolor_middle[z], d->fillbottom_pcolor_end[z]);
|
||||
}
|
||||
|
||||
/* draw style = line */
|
||||
|
@ -155,7 +161,7 @@ graph_draw(Widget *widget, DrawCtx *ctx, int offset,
|
|||
draw_graph_line(ctx,
|
||||
left_offset + 2, margin_top + d->box_height + 1,
|
||||
d->size, d->drawline[z], d->index,
|
||||
d->drawline_color[z]);
|
||||
d->drawline_color[z], d->drawline_pcolor_middle[z], d->drawline_pcolor_end[z]);
|
||||
}
|
||||
|
||||
widget->area.width = d->width;
|
||||
|
@ -236,6 +242,8 @@ graph_new(Statusbar *statusbar, cfg_t *config)
|
|||
int i;
|
||||
char *type;
|
||||
XColor tmp_color;
|
||||
XColor *ptmp_color_middle;
|
||||
XColor *ptmp_color_end;
|
||||
|
||||
w = p_new(Widget, 1);
|
||||
widget_common_new(w, statusbar, config);
|
||||
|
@ -272,18 +280,24 @@ graph_new(Statusbar *statusbar, cfg_t *config)
|
|||
d->lines = p_new(int *, d->data_items);
|
||||
|
||||
d->filltop_color = p_new(XColor, d->data_items);
|
||||
d->filltop_pcolor_middle = p_new(XColor *, d->data_items);
|
||||
d->filltop_pcolor_end = p_new(XColor *, d->data_items);
|
||||
d->fillbottom_color = p_new(XColor, d->data_items);
|
||||
d->fillbottom_pcolor_middle = p_new(XColor *, d->data_items);
|
||||
d->fillbottom_pcolor_end = p_new(XColor *, d->data_items);
|
||||
d->drawline_color = p_new(XColor, d->data_items);
|
||||
d->drawline_pcolor_middle = p_new(XColor *, d->data_items);
|
||||
d->drawline_pcolor_end = p_new(XColor *, d->data_items);
|
||||
|
||||
d->max_index = p_new(int, d->data_items);
|
||||
|
||||
d->current_max = p_new(float, d->data_items);
|
||||
d->max = p_new(float, d->data_items);
|
||||
|
||||
tmp_color = globalconf.screens[statusbar->screen].colors_normal[ColFG];
|
||||
|
||||
for(i = 0; i < d->data_items; i++)
|
||||
{
|
||||
ptmp_color_middle = ptmp_color_end = NULL;
|
||||
|
||||
cfg = cfg_getnsec(config, "data", i);
|
||||
|
||||
if((color = cfg_getstr(cfg, "fg")))
|
||||
|
@ -291,6 +305,18 @@ graph_new(Statusbar *statusbar, cfg_t *config)
|
|||
else
|
||||
tmp_color = globalconf.screens[statusbar->screen].colors_normal[ColFG];
|
||||
|
||||
if((color = cfg_getstr(cfg, "fg_middle")))
|
||||
{
|
||||
ptmp_color_middle = p_new(XColor, 1);
|
||||
*ptmp_color_middle = draw_color_new(globalconf.display, phys_screen, color);
|
||||
}
|
||||
|
||||
if((color = cfg_getstr(cfg, "fg_end")))
|
||||
{
|
||||
ptmp_color_end = p_new(XColor, 1);
|
||||
*ptmp_color_end = draw_color_new(globalconf.display, phys_screen, color);
|
||||
}
|
||||
|
||||
if (cfg_getbool(cfg, "scale"))
|
||||
d->values[i] = p_new(float, d->size); /* not null -> scale = true */
|
||||
|
||||
|
@ -313,18 +339,24 @@ graph_new(Statusbar *statusbar, cfg_t *config)
|
|||
{
|
||||
d->fillbottom[d->fillbottom_total] = d->lines[i];
|
||||
d->fillbottom_color[d->fillbottom_total] = tmp_color;
|
||||
d->fillbottom_pcolor_middle[d->fillbottom_total] = ptmp_color_middle;
|
||||
d->fillbottom_pcolor_end[d->fillbottom_total] = ptmp_color_end;
|
||||
d->fillbottom_total++;
|
||||
}
|
||||
else if (!a_strncmp(type, "top", sizeof("top")))
|
||||
{
|
||||
d->filltop[d->filltop_total] = d->lines[i];
|
||||
d->filltop_color[d->filltop_total] = tmp_color;
|
||||
d->filltop_pcolor_middle[d->fillbottom_total] = ptmp_color_middle;
|
||||
d->filltop_pcolor_end[d->fillbottom_total] = ptmp_color_end;
|
||||
d->filltop_total++;
|
||||
}
|
||||
else if (!a_strncmp(type, "line", sizeof("line")))
|
||||
{
|
||||
d->drawline[d->drawline_total] = d->lines[i];
|
||||
d->drawline_color[d->drawline_total] = tmp_color;
|
||||
d->drawline_pcolor_middle[d->fillbottom_total] = ptmp_color_middle;
|
||||
d->drawline_pcolor_end[d->fillbottom_total] = ptmp_color_end;
|
||||
d->drawline_total++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue