graph widget added

example config:

graph gr_cpu {
  width = 80
  height = "0.8"
  fg = "#336633"
  bg = "#000000"
  bordercolor = "#669966"
  padding_left = 0
  mouse = {...}
  x = ...
  y = ...
}

Looks like here: http://www.calmar.ws/tmp/112-Sun-screen.png

I renamed lpadding to padding_left, and bcolor to bordercolor
also on the progressbar widget.

The awesomerc page would still be to write, when this patch will get accepted.

Hints are always welcomed.
This commit is contained in:
marco candrian 2008-01-06 18:23:56 +01:00 committed by Julien Danjou
parent a30579b32e
commit 37da7d0d01
8 changed files with 226 additions and 12 deletions

View File

@ -32,6 +32,7 @@ WIDGETS += widgets/iconbox.c
WIDGETS += widgets/netwmicon.c WIDGETS += widgets/netwmicon.c
WIDGETS += widgets/progressbar.c WIDGETS += widgets/progressbar.c
WIDGETS += widgets/tasklist.c WIDGETS += widgets/tasklist.c
WIDGETS += widgets/graph.c
EXTRA_DIST += awesomerc EXTRA_DIST += awesomerc

View File

@ -573,11 +573,24 @@ config_parse(const char *confpatharg)
CFG_BOOL((char *) "show_icons", cfg_true, CFGF_NONE), CFG_BOOL((char *) "show_icons", cfg_true, CFGF_NONE),
CFG_END() CFG_END()
}; };
static cfg_opt_t widget_graph_opts[] =
{
CFG_INT((char *) "x", 0xffffffff, CFGF_NONE),
CFG_INT((char *) "y", 0xffffffff, CFGF_NONE),
CFG_SEC((char *) "mouse", mouse_generic_opts, CFGF_MULTI),
CFG_INT((char *) "width", 100, CFGF_NONE),
CFG_INT((char *) "padding_left", 3, CFGF_NONE),
CFG_FLOAT((char *) "height", 0.67, CFGF_NONE),
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bordercolor", (char *) NULL, CFGF_NONE),
CFG_END()
};
static cfg_opt_t widget_progressbar_bar_opts[] = static cfg_opt_t widget_progressbar_bar_opts[] =
{ {
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE), CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bg", (char *) NULL, CFGF_NONE), CFG_STR((char *) "bg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bcolor", (char *) NULL, CFGF_NONE), CFG_STR((char *) "bordercolor", (char *) NULL, CFGF_NONE),
}; };
static cfg_opt_t widget_progressbar_opts[] = static cfg_opt_t widget_progressbar_opts[] =
{ {
@ -587,7 +600,7 @@ config_parse(const char *confpatharg)
CFG_SEC((char *) "bar", widget_progressbar_bar_opts, CFGF_MULTI), CFG_SEC((char *) "bar", widget_progressbar_bar_opts, CFGF_MULTI),
CFG_INT((char *) "width", 100, CFGF_NONE), CFG_INT((char *) "width", 100, CFGF_NONE),
CFG_INT((char *) "gap", 2, CFGF_NONE), CFG_INT((char *) "gap", 2, CFGF_NONE),
CFG_INT((char *) "lpadding", 3, CFGF_NONE), CFG_INT((char *) "padding_left", 3, CFGF_NONE),
CFG_FLOAT((char *) "height", 0.67, CFGF_NONE), CFG_FLOAT((char *) "height", 0.67, CFGF_NONE),
CFG_END() CFG_END()
}; };
@ -603,6 +616,7 @@ config_parse(const char *confpatharg)
CFG_SEC((char *) "iconbox", widget_iconbox_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES), CFG_SEC((char *) "iconbox", widget_iconbox_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES),
CFG_SEC((char *) "netwmicon", widget_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES), CFG_SEC((char *) "netwmicon", widget_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES),
CFG_SEC((char *) "progressbar", widget_progressbar_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES), CFG_SEC((char *) "progressbar", widget_progressbar_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES),
CFG_SEC((char *) "graph", widget_graph_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES),
CFG_SEC((char *) "tasklist", widget_tasklist_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES), CFG_SEC((char *) "tasklist", widget_tasklist_opts, CFGF_TITLE | CFGF_MULTI | CFGF_NO_TITLE_DUPES),
CFG_END() CFG_END()
}; };

36
draw.c
View File

@ -166,6 +166,42 @@ draw_rectangle(DrawCtx *ctx, int x, int y, int w, int h, Bool filled, XColor col
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
} }
/* draws a graph; it takes the line-lengths from 'h' (w = size of h)
* It cycles backwards through it, beginning at position h_index, until
* h_index is reached again (wrapped around). */
void
draw_graph(DrawCtx *ctx, int x, int y, int w, int *h, int h_index, XColor color)
{
cairo_surface_t *surface;
cairo_t *cr;
int i, i_tmp;
surface = cairo_xlib_surface_create(globalconf.display, ctx->drawable, ctx->visual, ctx->width, ctx->height);
cr = cairo_create (surface);
cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
cairo_set_line_width(cr, 1.0);
cairo_set_source_rgb(cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
i_tmp = h_index;
i = -1;
while(++i < w)
{
cairo_move_to(cr, x, y);
cairo_line_to(cr, x, y - h[i_tmp]);
x++;
if (--i_tmp < 0)
i_tmp = w - 1;
}
cairo_stroke(cr);
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
void void
draw_circle(DrawCtx *ctx, int x, int y, int r, Bool filled, XColor color) draw_circle(DrawCtx *ctx, int x, int y, int r, Bool filled, XColor color)
{ {

1
draw.h
View File

@ -56,6 +56,7 @@ DrawCtx *draw_get_context(int, int, int);
void draw_free_context(DrawCtx *); void draw_free_context(DrawCtx *);
void draw_text(DrawCtx *, int, int, int, int, int, int, XftFont *, const char *, XColor fg, XColor bg); void draw_text(DrawCtx *, int, int, int, int, int, int, XftFont *, const char *, XColor fg, XColor bg);
void draw_rectangle(DrawCtx *, int, int, int, int, Bool, XColor); void draw_rectangle(DrawCtx *, int, int, int, int, Bool, XColor);
void draw_graph(DrawCtx *, int, int, int, int *, int, XColor);
void draw_circle(DrawCtx *, int, int, int, Bool, XColor); void draw_circle(DrawCtx *, int, int, int, Bool, XColor);
void draw_image(DrawCtx *, int, int, int, const char *); void draw_image(DrawCtx *, int, int, int, const char *);
void draw_image_from_argb_data(DrawCtx *, int, int, int, int, int, unsigned char *); void draw_image_from_argb_data(DrawCtx *, int, int, int, int, int, unsigned char *);

View File

@ -36,6 +36,7 @@ const NameFuncLink WidgetList[] =
{"iconbox", iconbox_new}, {"iconbox", iconbox_new},
{"netwmicon", netwmicon_new}, {"netwmicon", netwmicon_new},
{"progressbar", progressbar_new}, {"progressbar", progressbar_new},
{"graph", graph_new},
{"tasklist", tasklist_new}, {"tasklist", tasklist_new},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -40,6 +40,7 @@ WidgetConstructor focustitle_new;
WidgetConstructor iconbox_new; WidgetConstructor iconbox_new;
WidgetConstructor netwmicon_new; WidgetConstructor netwmicon_new;
WidgetConstructor progressbar_new; WidgetConstructor progressbar_new;
WidgetConstructor graph_new;
WidgetConstructor tasklist_new; WidgetConstructor tasklist_new;
Uicb uicb_widget_tell; Uicb uicb_widget_tell;

160
widgets/graph.c Normal file
View File

@ -0,0 +1,160 @@
/*
* graph.c - a graph widget
*
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
* Copyright © 2007-2008 Marco Candrian <mac@calmar.ws>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "util.h"
#include "draw.h"
#include "widget.h"
#include "xutil.h"
#include "screen.h"
extern AwesomeConf globalconf;
typedef struct
{
int percent; /* Percent 0 to 100 */
int width; /* Width of the widget */
int padding_left; /* Left padding */
float height; /* Height 0-1, where 1 is height of statusbar */
XColor fg; /* Foreground color */
XColor bg; /* Background color */
XColor bordercolor; /* Border color */
int *lines; /* keeps the calculated values (line-length); */
int lines_index; /* pointer to current val */
int lines_size; /* size of lines-array */
} Data;
static int
graph_draw(Widget *widget, DrawCtx *ctx, int offset,
int used __attribute__ ((unused)))
{
int width, height; /* width/height (pixel) to draw the outer box */
int margin_top, left_offset;
Data *d = widget->data;
width = d->lines_size + 2;
if(!widget->user_supplied_x)
widget->area.x = widget_calculate_offset(widget->statusbar->width,
d->width,
offset,
widget->alignment);
if(!widget->user_supplied_y)
widget->area.y = 0;
margin_top = (int) (widget->statusbar->height * (1 - d->height)) / 2 + 0.5 + widget->area.y;
height = (int) (widget->statusbar->height * d->height + 0.5);
left_offset = widget->area.x + d->padding_left;
draw_rectangle(ctx,
left_offset, margin_top,
width, height,
False, d->bordercolor);
draw_rectangle(ctx,
left_offset + 1, margin_top + 1,
width - 2, height - 2,
True, d->bg);
/* computes line-length to draw and store into lines[] */
d->lines[d->lines_index] = (int) (d->percent) * (height - 2 ) / 100 + 0.5;
if(d->lines[d->lines_index] < 0)
d->lines[d->lines_index] = 0;
draw_graph(ctx,
left_offset + 2, margin_top + height - 1,
d->lines_size, d->lines, d->lines_index,
d->fg);
widget->area.width = d->width;
widget->area.height = widget->statusbar->height;
return widget->area.width;
}
static void
graph_tell(Widget *widget, char *command)
{
Data *d = widget->data;
int percent;
if(!command || d->width < 1)
return;
if(++d->lines_index >= d->lines_size) /* cycle inside the array */
d->lines_index = 0;
percent = atoi(command);
if(percent <= 100 && percent >= 0)
d->percent = percent;
}
Widget *
graph_new(Statusbar *statusbar, cfg_t *config)
{
Widget *w;
Data *d;
char *color;
int phys_screen = get_phys_screen(statusbar->screen);
w = p_new(Widget, 1);
widget_common_new(w, statusbar, config);
w->draw = graph_draw;
w->tell = graph_tell;
d = w->data = p_new(Data, 1);
d->height = cfg_getfloat(config, "height");
d->width = cfg_getint(config, "width");
d->padding_left = cfg_getint(config, "padding_left");
d->lines_size = d->width - d->padding_left - 2;
d->lines_index = -1; /* graph_tell will increment it to 0 (to begin with...) */
if(d->lines_size < 1)
{
warn("graph widget needs: (width - padding_left) >= 3\n");
return w;
}
d->lines = p_new(int, d->lines_size);
if((color = cfg_getstr(config, "fg")))
d->fg = initxcolor(phys_screen, color);
else
d->fg = globalconf.screens[statusbar->screen].colors_normal[ColFG];
if((color = cfg_getstr(config, "bg")))
d->bg = initxcolor(phys_screen, color);
else
d->bg = globalconf.screens[statusbar->screen].colors_normal[ColBG];
if((color = cfg_getstr(config, "bordercolor")))
d->bordercolor = initxcolor(phys_screen, color);
else
d->bordercolor = d->fg;
return w;
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -35,7 +35,7 @@ typedef struct
/** Width of the bars */ /** Width of the bars */
int width; int width;
/** Left padding */ /** Left padding */
int lpadding; int padding_left;
/** Pixel between bars */ /** Pixel between bars */
int gap; int gap;
/** Number of bars */ /** Number of bars */
@ -47,7 +47,7 @@ typedef struct
/** Background color */ /** Background color */
XColor *bg; XColor *bg;
/** Border color */ /** Border color */
XColor *bcolor; XColor *bordercolor;
} Data; } Data;
static int static int
@ -61,7 +61,7 @@ progressbar_draw(Widget *widget, DrawCtx *ctx, int offset,
if (!(d->bars)) if (!(d->bars))
return 0; return 0;
width = d->width - d->lpadding; width = d->width - d->padding_left;
if(!widget->user_supplied_x) if(!widget->user_supplied_x)
widget->area.x = widget_calculate_offset(widget->statusbar->width, widget->area.x = widget_calculate_offset(widget->statusbar->width,
@ -74,7 +74,7 @@ progressbar_draw(Widget *widget, DrawCtx *ctx, int offset,
margin_top = (int) (widget->statusbar->height * (1 - d->height)) / 2 + 0.5 + widget->area.y; margin_top = (int) (widget->statusbar->height * (1 - d->height)) / 2 + 0.5 + widget->area.y;
pb_height = (int) (widget->statusbar->height * d->height - (d->gap * (d->bars - 1))) / d->bars + 0.5; pb_height = (int) (widget->statusbar->height * d->height - (d->gap * (d->bars - 1))) / d->bars + 0.5;
left_offset = widget->area.x + d->lpadding; left_offset = widget->area.x + d->padding_left;
for(i = 0; i < d->bars; i++) for(i = 0; i < d->bars; i++)
{ {
@ -83,7 +83,7 @@ progressbar_draw(Widget *widget, DrawCtx *ctx, int offset,
draw_rectangle(ctx, draw_rectangle(ctx,
left_offset, margin_top, left_offset, margin_top,
width, pb_height, width, pb_height,
False, d->bcolor[i]); False, d->bordercolor[i]);
if(pwidth > 0) if(pwidth > 0)
draw_rectangle(ctx, draw_rectangle(ctx,
@ -148,7 +148,7 @@ progressbar_new(Statusbar *statusbar, cfg_t *config)
d->bg = p_new(XColor, d->bars); d->bg = p_new(XColor, d->bars);
d->fg = p_new(XColor, d->bars); d->fg = p_new(XColor, d->bars);
d->bcolor = p_new(XColor, d->bars); d->bordercolor = p_new(XColor, d->bars);
d->percent = p_new(int, d->bars); d->percent = p_new(int, d->bars);
for(i = 0; i < d->bars; i++) for(i = 0; i < d->bars; i++)
@ -165,17 +165,17 @@ progressbar_new(Statusbar *statusbar, cfg_t *config)
else else
d->bg[i] = globalconf.screens[statusbar->screen].colors_normal[ColBG]; d->bg[i] = globalconf.screens[statusbar->screen].colors_normal[ColBG];
if((color = cfg_getstr(cfg, "bcolor"))) if((color = cfg_getstr(cfg, "bordercolor")))
d->bcolor[i] = initxcolor(phys_screen, color); d->bordercolor[i] = initxcolor(phys_screen, color);
else else
d->bcolor[i] = d->fg[i]; d->bordercolor[i] = d->fg[i];
} }
d->height = cfg_getfloat(config, "height"); d->height = cfg_getfloat(config, "height");
d->gap = cfg_getint(config, "gap"); d->gap = cfg_getint(config, "gap");
d->lpadding = cfg_getint(config, "lpadding"); d->padding_left = cfg_getint(config, "padding_left");
return w; return w;
} }