graph, progressbar: remove
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
1128f67f5d
commit
be09012c08
|
@ -77,8 +77,6 @@ set(AWE_SRCS
|
|||
${SOURCE_DIR}/common/backtrace.c
|
||||
${SOURCE_DIR}/common/luaobject.c
|
||||
${SOURCE_DIR}/common/luaclass.c
|
||||
${SOURCE_DIR}/widgets/graph.c
|
||||
${SOURCE_DIR}/widgets/progressbar.c
|
||||
${SOURCE_DIR}/widgets/textbox.c
|
||||
${SOURCE_DIR}/widgets/systray.c
|
||||
${SOURCE_DIR}/widgets/imagebox.c)
|
||||
|
|
|
@ -35,7 +35,6 @@ font_height
|
|||
fullscreen
|
||||
gap
|
||||
geometry
|
||||
graph
|
||||
group_window
|
||||
grow
|
||||
height
|
||||
|
@ -77,7 +76,6 @@ pid
|
|||
plot_data_add
|
||||
plot_properties_set
|
||||
position
|
||||
progressbar
|
||||
release
|
||||
resize
|
||||
right
|
||||
|
|
246
draw.c
246
draw.c
|
@ -208,68 +208,6 @@ draw_text(draw_context_t *ctx, draw_text_context_t *data,
|
|||
pango_cairo_show_layout(ctx->cr, ctx->layout);
|
||||
}
|
||||
|
||||
/** Setup color-source for cairo (gradient or mono).
|
||||
* \param ctx Draw context.
|
||||
* \param gradient_vector x, y to x + x_offset, y + y_offset.
|
||||
* \param pcolor Color to use at start of gradient_vector.
|
||||
* \param pcolor_center Color at center of gradient_vector.
|
||||
* \param pcolor_end Color at end of gradient_vector.
|
||||
* \return pat Pattern or NULL, needs to get cairo_pattern_destroy()'ed.
|
||||
*/
|
||||
static cairo_pattern_t *
|
||||
draw_setup_cairo_color_source(draw_context_t *ctx, vector_t gradient_vector,
|
||||
const color_t *pcolor, const color_t *pcolor_center,
|
||||
const color_t *pcolor_end)
|
||||
{
|
||||
cairo_pattern_t *pat = NULL;
|
||||
bool has_center = pcolor_center->initialized;
|
||||
bool has_end = pcolor_end->initialized;
|
||||
|
||||
/* no need for a real pattern: */
|
||||
if(!has_end && !has_center)
|
||||
cairo_set_source_rgba(ctx->cr,
|
||||
pcolor->red / 255.0,
|
||||
pcolor->green / 255.0,
|
||||
pcolor->blue / 255.0,
|
||||
pcolor->alpha / 255.0);
|
||||
else
|
||||
{
|
||||
pat = cairo_pattern_create_linear(gradient_vector.x,
|
||||
gradient_vector.y,
|
||||
gradient_vector.x + gradient_vector.x_offset,
|
||||
gradient_vector.y + gradient_vector.y_offset);
|
||||
|
||||
/* pcolor is always set (so far in awesome) */
|
||||
cairo_pattern_add_color_stop_rgba(pat, 0.0,
|
||||
pcolor->red / 255.0,
|
||||
pcolor->green / 255.0,
|
||||
pcolor->blue / 255.0,
|
||||
pcolor->alpha / 255.0);
|
||||
|
||||
if(has_center)
|
||||
cairo_pattern_add_color_stop_rgba(pat, 0.5,
|
||||
pcolor_center->red / 255.0,
|
||||
pcolor_center->green / 255.0,
|
||||
pcolor_center->blue / 255.0,
|
||||
pcolor_center->alpha / 255.0);
|
||||
|
||||
if(has_end)
|
||||
cairo_pattern_add_color_stop_rgba(pat, 1.0,
|
||||
pcolor_end->red / 255.0,
|
||||
pcolor_end->green / 255.0,
|
||||
pcolor_end->blue / 255.0,
|
||||
pcolor_end->alpha / 255.0);
|
||||
else
|
||||
cairo_pattern_add_color_stop_rgba(pat, 1.0,
|
||||
pcolor->red / 255.0,
|
||||
pcolor->green / 255.0,
|
||||
pcolor->blue / 255.0,
|
||||
pcolor->alpha / 255.0);
|
||||
cairo_set_source(ctx->cr, pat);
|
||||
}
|
||||
return pat;
|
||||
}
|
||||
|
||||
/** Draw rectangle inside the coordinates
|
||||
* \param ctx Draw context
|
||||
* \param geometry geometry
|
||||
|
@ -304,190 +242,6 @@ draw_rectangle(draw_context_t *ctx, area_t geometry,
|
|||
}
|
||||
}
|
||||
|
||||
/** Draw rectangle with gradient colors
|
||||
* \param ctx Draw context.
|
||||
* \param geometry Geometry.
|
||||
* \param line_width Line width.
|
||||
* \param filled Filled rectangle?
|
||||
* \param gradient_vector Color-gradient course.
|
||||
* \param pcolor Color at start of gradient_vector.
|
||||
* \param pcolor_center Color in the center.
|
||||
* \param pcolor_end Color at end of gradient_vector.
|
||||
*/
|
||||
void
|
||||
draw_rectangle_gradient(draw_context_t *ctx, area_t geometry, float line_width, bool filled,
|
||||
vector_t gradient_vector, const color_t *pcolor,
|
||||
const color_t *pcolor_center, const color_t *pcolor_end)
|
||||
{
|
||||
cairo_pattern_t *pat;
|
||||
|
||||
cairo_set_antialias(ctx->cr, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_line_width(ctx->cr, line_width);
|
||||
cairo_set_miter_limit(ctx->cr, 10.0);
|
||||
cairo_set_line_join(ctx->cr, CAIRO_LINE_JOIN_MITER);
|
||||
|
||||
pat = draw_setup_cairo_color_source(ctx, gradient_vector, pcolor, pcolor_center, pcolor_end);
|
||||
|
||||
if(filled)
|
||||
{
|
||||
cairo_rectangle(ctx->cr, geometry.x, geometry.y, geometry.width, geometry.height);
|
||||
cairo_fill(ctx->cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle(ctx->cr, geometry.x + 1, geometry.y, geometry.width - 1, geometry.height - 1);
|
||||
cairo_stroke(ctx->cr);
|
||||
}
|
||||
|
||||
if(pat)
|
||||
cairo_pattern_destroy(pat);
|
||||
}
|
||||
|
||||
/** Setup some cairo-things for drawing a graph
|
||||
* \param ctx Draw context
|
||||
*/
|
||||
void
|
||||
draw_graph_setup(draw_context_t *ctx)
|
||||
{
|
||||
cairo_set_antialias(ctx->cr, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_line_width(ctx->cr, 1.0);
|
||||
/* without it, it can draw over the path on sharp angles
|
||||
* ...too long lines * (...graph_line) */
|
||||
cairo_set_miter_limit(ctx->cr, 0.0);
|
||||
cairo_set_line_join(ctx->cr, CAIRO_LINE_JOIN_MITER);
|
||||
}
|
||||
|
||||
/** Draw a graph.
|
||||
* \param ctx Draw context.
|
||||
* \param rect The area to draw into.
|
||||
* \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 grow Put new values to the left or to the right.
|
||||
* \param gradient_vector Color-Gradient course.
|
||||
* \param pcolor Color at start of gradient_vector.
|
||||
* \param pcolor_center Color in the center.
|
||||
* \param pcolor_end Color at end of gradient_vector.
|
||||
*/
|
||||
void
|
||||
draw_graph(draw_context_t *ctx, area_t rect, int *from, int *to, int cur_index,
|
||||
position_t grow, vector_t gradient_vector, const color_t *pcolor,
|
||||
const color_t *pcolor_center, const color_t *pcolor_end)
|
||||
{
|
||||
int i = -1;
|
||||
float x = rect.x + 0.5; /* middle of a pixel */
|
||||
cairo_pattern_t *pat;
|
||||
|
||||
pat = draw_setup_cairo_color_source(ctx, gradient_vector,
|
||||
pcolor, pcolor_center, pcolor_end);
|
||||
|
||||
if(grow == Right) /* draw from right to left */
|
||||
{
|
||||
x += rect.width - 1;
|
||||
while(++i < rect.width)
|
||||
{
|
||||
cairo_move_to(ctx->cr, x, rect.y - from[cur_index]);
|
||||
cairo_line_to(ctx->cr, x, rect.y - to[cur_index]);
|
||||
x -= 1.0;
|
||||
|
||||
if(--cur_index < 0)
|
||||
cur_index = rect.width - 1;
|
||||
}
|
||||
}
|
||||
else /* draw from left to right */
|
||||
while(++i < rect.width)
|
||||
{
|
||||
cairo_move_to(ctx->cr, x, rect.y - from[cur_index]);
|
||||
cairo_line_to(ctx->cr, x, rect.y - to[cur_index]);
|
||||
x += 1.0;
|
||||
|
||||
if(--cur_index < 0)
|
||||
cur_index = rect.width - 1;
|
||||
}
|
||||
|
||||
cairo_stroke(ctx->cr);
|
||||
|
||||
if(pat)
|
||||
cairo_pattern_destroy(pat);
|
||||
}
|
||||
|
||||
/** Draw a line into a graph-widget.
|
||||
* \param ctx Draw context.
|
||||
* \param rect The area to draw into.
|
||||
* \param to array of offsets to draw the line through...
|
||||
* \param cur_index current position in data-array (cycles around)
|
||||
* \param grow put new values to the left or to the right
|
||||
* \param gradient_vector Color-gradient course.
|
||||
* \param pcolor Color at start of gradient_vector.
|
||||
* \param pcolor_center Color in the center.
|
||||
* \param pcolor_end Color at end of gradient_vector.
|
||||
*/
|
||||
void
|
||||
draw_graph_line(draw_context_t *ctx, area_t rect, int *to, int cur_index,
|
||||
position_t grow, vector_t gradient_vector, const color_t *pcolor,
|
||||
const color_t *pcolor_center, const color_t *pcolor_end)
|
||||
{
|
||||
int i, w;
|
||||
float x, y;
|
||||
cairo_pattern_t *pat;
|
||||
|
||||
/* NOTE: without, it sometimes won't draw to some path (centered in a pixel)
|
||||
* ... it won't fill some pixels! It also looks much nicer so.
|
||||
* (since line-drawing is the last on the graph, no need to reset to _NONE) */
|
||||
/* Not much difference to CAIRO_ANTIALIAS_DEFAULT, but recommend for LCD */
|
||||
cairo_set_antialias(ctx->cr, CAIRO_ANTIALIAS_SUBPIXEL);
|
||||
/* a nicer, better visible line compared to 1.0 */
|
||||
cairo_set_line_width(ctx->cr, 1.25);
|
||||
|
||||
pat = draw_setup_cairo_color_source(ctx, gradient_vector, pcolor, pcolor_center, pcolor_end);
|
||||
|
||||
/* path through the centers of pixels */
|
||||
x = rect.x + 0.5;
|
||||
y = rect.y + 0.5;
|
||||
w = rect.width;
|
||||
|
||||
if(grow == Right)
|
||||
{
|
||||
/* go through the values from old to new. Begin with the oldest. */
|
||||
if(++cur_index > w - 1)
|
||||
cur_index = 0;
|
||||
|
||||
cairo_move_to(ctx->cr, x, y - to[cur_index]);
|
||||
}
|
||||
else
|
||||
/* on the left border: fills a pixel also when there's only one value */
|
||||
cairo_move_to(ctx->cr, x - 1.0, y - to[cur_index]);
|
||||
|
||||
for(i = 0; i < w; i++)
|
||||
{
|
||||
cairo_line_to(ctx->cr, x, y - to[cur_index]);
|
||||
x += 1.0;
|
||||
|
||||
/* cycles around the index */
|
||||
if(grow == Right)
|
||||
{
|
||||
if(++cur_index > w - 1)
|
||||
cur_index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(--cur_index < 0)
|
||||
cur_index = w - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* onto the right border: fills a pixel also when there's only one value */
|
||||
if(grow == Right)
|
||||
cairo_line_to(ctx->cr, x, y - to[(cur_index + (w - 1)) % w]);
|
||||
|
||||
cairo_stroke(ctx->cr);
|
||||
|
||||
if(pat)
|
||||
cairo_pattern_destroy(pat);
|
||||
/* reset line-width */
|
||||
cairo_set_line_width(ctx->cr, 1.0);
|
||||
}
|
||||
|
||||
/** Draw an image from ARGB data to a draw context.
|
||||
* Data should be stored as an array of alpha, red, blue, green for each pixel
|
||||
* and the array size should be w * h elements long.
|
||||
|
|
19
draw.h
19
draw.h
|
@ -41,17 +41,6 @@ typedef enum
|
|||
AlignMiddle = (1 << 5)
|
||||
} alignment_t;
|
||||
|
||||
typedef struct vector_t vector_t;
|
||||
struct vector_t
|
||||
{
|
||||
/** Co-ords of starting point */
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
/** Offset to starting point */
|
||||
int16_t x_offset;
|
||||
int16_t y_offset;
|
||||
};
|
||||
|
||||
typedef struct area_t area_t;
|
||||
struct area_t
|
||||
{
|
||||
|
@ -139,14 +128,6 @@ typedef struct
|
|||
bool draw_text_context_init(draw_text_context_t *, const char *, ssize_t);
|
||||
void draw_text(draw_context_t *, draw_text_context_t *, PangoEllipsizeMode, PangoWrapMode, alignment_t, alignment_t, area_t);
|
||||
void draw_rectangle(draw_context_t *, area_t, float, bool, const color_t *);
|
||||
void draw_rectangle_gradient(draw_context_t *, area_t, float, bool, vector_t,
|
||||
const color_t *, const color_t *, const color_t *);
|
||||
|
||||
void draw_graph_setup(draw_context_t *);
|
||||
void draw_graph(draw_context_t *, area_t, int *, int *, int, position_t, vector_t,
|
||||
const color_t *, const color_t *, const color_t *);
|
||||
void draw_graph_line(draw_context_t *, area_t, int *, int, position_t, vector_t,
|
||||
const color_t *, const color_t *, const color_t *);
|
||||
void draw_image(draw_context_t *, int, int, double, image_t *);
|
||||
void draw_rotate(draw_context_t *, xcb_drawable_t, xcb_drawable_t, int, int, int, int, double, int, int);
|
||||
area_t draw_text_extents(draw_text_context_t *);
|
||||
|
|
6
widget.c
6
widget.c
|
@ -518,12 +518,6 @@ luaA_widget_set_type(lua_State *L, widget_t *w)
|
|||
case A_TK_TEXTBOX:
|
||||
wc = widget_textbox;
|
||||
break;
|
||||
case A_TK_PROGRESSBAR:
|
||||
wc = widget_progressbar;
|
||||
break;
|
||||
case A_TK_GRAPH:
|
||||
wc = widget_graph;
|
||||
break;
|
||||
case A_TK_SYSTRAY:
|
||||
wc = widget_systray;
|
||||
break;
|
||||
|
|
2
widget.h
2
widget.h
|
@ -75,8 +75,6 @@ lua_class_t widget_class;
|
|||
void widget_class_setup(lua_State *);
|
||||
|
||||
widget_constructor_t widget_textbox;
|
||||
widget_constructor_t widget_progressbar;
|
||||
widget_constructor_t widget_graph;
|
||||
widget_constructor_t widget_systray;
|
||||
widget_constructor_t widget_imagebox;
|
||||
|
||||
|
|
628
widgets/graph.c
628
widgets/graph.c
|
@ -1,628 +0,0 @@
|
|||
/*
|
||||
* 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 <math.h>
|
||||
|
||||
#include "widget.h"
|
||||
#include "luaa.h"
|
||||
#include "common/tokenize.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Bottom_Style = 0,
|
||||
Top_Style,
|
||||
Line_Style
|
||||
} plot_style_t;
|
||||
|
||||
/** The plot data structure. */
|
||||
typedef struct
|
||||
{
|
||||
/** Graph title of the plot sections */
|
||||
char *title;
|
||||
/** Represents a full graph */
|
||||
float max_value;
|
||||
/** Scale the graph */
|
||||
bool scale;
|
||||
|
||||
/* markers... */
|
||||
/** Index of current (new) value */
|
||||
int index;
|
||||
/** Index of the actual maximum value */
|
||||
int max_index;
|
||||
/** Pointer to current maximum value itself */
|
||||
float current_max;
|
||||
/** Draw style of according index */
|
||||
plot_style_t draw_style;
|
||||
/** Keeps the calculated values (line-length); */
|
||||
int *lines;
|
||||
/** Actual values */
|
||||
float *values;
|
||||
/** Color of them */
|
||||
color_t color_start;
|
||||
/** Color at middle of graph */
|
||||
color_t pcolor_center;
|
||||
/** Color at end of graph */
|
||||
color_t pcolor_end;
|
||||
/** Create a vertical color gradient */
|
||||
bool vertical_gradient;
|
||||
} plot_t;
|
||||
|
||||
static void
|
||||
plot_delete(plot_t *g)
|
||||
{
|
||||
p_delete(&g->title);
|
||||
p_delete(&g->lines);
|
||||
p_delete(&g->values);
|
||||
}
|
||||
|
||||
DO_ARRAY(plot_t, plot, plot_delete)
|
||||
|
||||
/** The private graph data structure */
|
||||
typedef struct
|
||||
{
|
||||
/** Width of the widget */
|
||||
int width;
|
||||
/** Height of graph (0.0-1.0; 1.0 = height of bar) */
|
||||
float height;
|
||||
/** Height of the innerbox in pixels */
|
||||
int box_height;
|
||||
/** Size of lines-array (also innerbox-length) */
|
||||
int size;
|
||||
/** Background color */
|
||||
color_t bg;
|
||||
/** Border color */
|
||||
color_t border_color;
|
||||
/** Grow: Left or Right */
|
||||
position_t grow;
|
||||
/** Preparation/tmp array for draw_graph(); */
|
||||
int *draw_from;
|
||||
/** Preparation/tmp array for draw_graph(); */
|
||||
int *draw_to;
|
||||
/** Graph list */
|
||||
plot_array_t plots;
|
||||
} graph_data_t;
|
||||
|
||||
/** Add a plot to a graph.
|
||||
* \param d The graph private data.
|
||||
* \param title The plot title.
|
||||
* \return A new plot.
|
||||
*/
|
||||
static plot_t *
|
||||
graph_plot_add(graph_data_t *d, const char *title)
|
||||
{
|
||||
plot_t plot;
|
||||
|
||||
p_clear(&plot, 1);
|
||||
|
||||
plot.title = a_strdup(title);
|
||||
plot.values = p_new(float, d->size);
|
||||
plot.lines = p_new(int, d->size);
|
||||
plot.max_value = 100.0;
|
||||
plot.vertical_gradient = true;
|
||||
|
||||
xcolor_to_color(&globalconf.colors.fg, &plot.color_start);
|
||||
|
||||
plot_array_append(&d->plots, plot);
|
||||
|
||||
return &d->plots.tab[d->plots.len - 1];
|
||||
}
|
||||
|
||||
/** Get the plot, and create one if it does not exist.
|
||||
* \param d The graph private data.
|
||||
* \param title The plot title.
|
||||
* \return A maybe new plot.
|
||||
*/
|
||||
static plot_t *
|
||||
graph_plot_get(graph_data_t *d, const char *title)
|
||||
{
|
||||
plot_t *plot;
|
||||
|
||||
/* check if this section is defined already */
|
||||
for(int j = 0; j < d->plots.len; j++)
|
||||
{
|
||||
plot = &d->plots.tab[j];
|
||||
if(!a_strcmp(title, plot->title))
|
||||
return plot;
|
||||
}
|
||||
|
||||
/* no plot found -> create one */
|
||||
return graph_plot_add(d, title);
|
||||
}
|
||||
|
||||
static area_t
|
||||
graph_geometry(widget_t *widget, int screen)
|
||||
{
|
||||
area_t geometry;
|
||||
graph_data_t *d = widget->data;
|
||||
|
||||
geometry.x = geometry.y = 0;
|
||||
geometry.height = d->width;
|
||||
geometry.width = d->width;
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
static area_t
|
||||
graph_extents(lua_State *L, widget_t *widget)
|
||||
{
|
||||
return graph_geometry(widget, 0);
|
||||
}
|
||||
|
||||
/** Draw a graph widget.
|
||||
* \param ctx The draw context.
|
||||
* \param w The widget node we are called from.
|
||||
* \param offset The offset to draw at.
|
||||
* \param used The already used width.
|
||||
* \param p A pointer to the object we're drawing onto.
|
||||
* \return The widget width.
|
||||
*/
|
||||
static void
|
||||
graph_draw(widget_t *widget, draw_context_t *ctx,
|
||||
area_t geometry, wibox_t *p)
|
||||
{
|
||||
int margin_top, y;
|
||||
graph_data_t *d = widget->data;
|
||||
area_t rectangle;
|
||||
vector_t color_gradient;
|
||||
|
||||
if(!d->plots.len)
|
||||
return;
|
||||
|
||||
/* box = the plot inside the rectangle */
|
||||
if(!d->box_height)
|
||||
d->box_height = round(ctx->height * d->height) - 2;
|
||||
|
||||
margin_top = round((ctx->height - (d->box_height + 2)) / 2) + geometry.y;
|
||||
|
||||
/* draw background */
|
||||
rectangle.x = geometry.x + 1;
|
||||
rectangle.y = margin_top + 1;
|
||||
rectangle.width = d->size;
|
||||
rectangle.height = d->box_height;
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &d->bg);
|
||||
|
||||
/* for plot drawing */
|
||||
rectangle.y = margin_top + d->box_height + 1; /* bottom left corner as starting point */
|
||||
rectangle.width = d->size; /* rectangle.height is not used */
|
||||
|
||||
draw_graph_setup(ctx); /* setup some drawing options */
|
||||
|
||||
/* gradient begin either left or on the right of the rectangle */
|
||||
if(d->grow == Right)
|
||||
color_gradient.x = rectangle.x + rectangle.width;
|
||||
else
|
||||
color_gradient.x = rectangle.x;
|
||||
|
||||
for(int i = 0; i < d->plots.len; i++)
|
||||
{
|
||||
plot_t *plot = &d->plots.tab[i];
|
||||
|
||||
switch(plot->draw_style)
|
||||
{
|
||||
case Top_Style:
|
||||
color_gradient.y = rectangle.y - rectangle.height;
|
||||
if(plot->vertical_gradient)
|
||||
{
|
||||
color_gradient.x_offset = 0;
|
||||
color_gradient.y_offset = rectangle.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
color_gradient.y_offset = 0;
|
||||
|
||||
if(d->grow == Right)
|
||||
color_gradient.x_offset = - rectangle.width;
|
||||
else
|
||||
color_gradient.x_offset = rectangle.width;
|
||||
}
|
||||
|
||||
for(y = 0; y < d->size; y++)
|
||||
{
|
||||
/* reverse values (because drawing from top) */
|
||||
d->draw_from[y] = d->box_height; /* i.e. no smaller value -> from top of box */
|
||||
d->draw_to[y] = d->box_height - plot->lines[y]; /* i.e. on full plot -> 0 = bottom */
|
||||
}
|
||||
draw_graph(ctx, rectangle , d->draw_from, d->draw_to, plot->index, d->grow, color_gradient,
|
||||
&plot->color_start, &plot->pcolor_center, &plot->pcolor_end);
|
||||
break;
|
||||
case Bottom_Style:
|
||||
color_gradient.y = rectangle.y;
|
||||
if(plot->vertical_gradient)
|
||||
{
|
||||
color_gradient.x_offset = 0;
|
||||
color_gradient.y_offset = - rectangle.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
color_gradient.y_offset = 0;
|
||||
|
||||
if(d->grow == Right)
|
||||
color_gradient.x_offset = - rectangle.width;
|
||||
else
|
||||
color_gradient.x_offset = rectangle.width;
|
||||
}
|
||||
|
||||
p_clear(d->draw_from, d->size);
|
||||
draw_graph(ctx, rectangle, d->draw_from, plot->lines, plot->index, d->grow, color_gradient,
|
||||
&plot->color_start, &plot->pcolor_center, &plot->pcolor_end);
|
||||
break;
|
||||
case Line_Style:
|
||||
color_gradient.y = rectangle.y;
|
||||
if(plot->vertical_gradient)
|
||||
{
|
||||
color_gradient.x_offset = 0;
|
||||
color_gradient.y_offset = -rectangle.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
color_gradient.y_offset = 0;
|
||||
if(d->grow == Right)
|
||||
color_gradient.x_offset = - rectangle.width;
|
||||
else
|
||||
color_gradient.x_offset = rectangle.width;
|
||||
}
|
||||
|
||||
draw_graph_line(ctx, rectangle, plot->lines, plot->index, d->grow, color_gradient,
|
||||
&plot->color_start, &plot->pcolor_center, &plot->pcolor_end);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw border (after line-drawing, what paints 0-values to the border) */
|
||||
rectangle.x = geometry.x;
|
||||
rectangle.y = margin_top;
|
||||
rectangle.width = d->size + 2;
|
||||
rectangle.height = d->box_height + 2;
|
||||
draw_rectangle(ctx, rectangle, 1.0, false, &d->border_color);
|
||||
}
|
||||
|
||||
/** Set various plot graph properties.
|
||||
* \param L The Lua VM state.
|
||||
* \return The number of elements pushed on stack.
|
||||
* \luastack
|
||||
* \lvalue A widget.
|
||||
* \lparam A plot name.
|
||||
* \lparam A table with various properties set.
|
||||
*/
|
||||
static int
|
||||
luaA_graph_plot_properties_set(lua_State *L)
|
||||
{
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
graph_data_t *d = widget->data;
|
||||
float max_value;
|
||||
const char *title, *buf;
|
||||
size_t len;
|
||||
plot_t *plot = NULL;
|
||||
color_init_cookie_t reqs[3];
|
||||
int i, reqs_nbr = -1;
|
||||
|
||||
title = luaL_checkstring(L, 2);
|
||||
luaA_checktable(L, 3);
|
||||
|
||||
plot = graph_plot_get(d, title);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&plot->color_start, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg_center", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&plot->pcolor_center, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg_end", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&plot->pcolor_end, buf, len);
|
||||
|
||||
plot->vertical_gradient = luaA_getopt_boolean(L, 3, "vertical_gradient", plot->vertical_gradient);
|
||||
plot->scale = luaA_getopt_boolean(L, 3, "scale", plot->scale);
|
||||
|
||||
max_value = luaA_getopt_number(L, 3, "max_value", plot->max_value);
|
||||
if(max_value != plot->max_value)
|
||||
plot->max_value = plot->current_max = max_value;
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "style", NULL, &len)))
|
||||
switch (a_tokenize(buf, len))
|
||||
{
|
||||
case A_TK_BOTTOM:
|
||||
plot->draw_style = Bottom_Style;
|
||||
break;
|
||||
case A_TK_LINE:
|
||||
plot->draw_style = Line_Style;
|
||||
break;
|
||||
case A_TK_TOP:
|
||||
plot->draw_style = Top_Style;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(i = 0; i <= reqs_nbr; i++)
|
||||
color_init_reply(reqs[i]);
|
||||
|
||||
widget_invalidate_bywidget(widget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Add data to a plot.
|
||||
* \param l The Lua VM state.
|
||||
* \return The number of elements pushed on stack.
|
||||
* \luastack
|
||||
* \lvalue A widget.
|
||||
* \lparam A plot name.
|
||||
* \lparam A data value.
|
||||
*/
|
||||
static int
|
||||
luaA_graph_plot_data_add(lua_State *L)
|
||||
{
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
graph_data_t *d = widget->data;
|
||||
plot_t *plot = NULL;
|
||||
const char *title = luaL_checkstring(L, 2);
|
||||
float value;
|
||||
int i;
|
||||
|
||||
if(!d->size)
|
||||
return 0;
|
||||
|
||||
plot = graph_plot_get(d, title);
|
||||
|
||||
/* assign incoming value */
|
||||
value = MAX(luaL_checknumber(L, 3), 0);
|
||||
|
||||
if(++plot->index >= d->size) /* cycle inside the array */
|
||||
plot->index = 0;
|
||||
|
||||
if(plot->scale) /* scale option is true */
|
||||
{
|
||||
plot->values[plot->index] = value;
|
||||
|
||||
if(value > plot->current_max) /* a new maximum value found */
|
||||
{
|
||||
plot->max_index = plot->index;
|
||||
plot->current_max = value;
|
||||
|
||||
/* recalculate */
|
||||
for (i = 0; i < d->size; i++)
|
||||
plot->lines[i] = round(plot->values[i] * d->box_height / plot->current_max);
|
||||
}
|
||||
/* old max_index reached + current_max > normal, re-check/generate */
|
||||
else if(plot->max_index == plot->index
|
||||
&& plot->current_max > plot->max_value)
|
||||
{
|
||||
/* find the new max */
|
||||
for(i = 0; i < d->size; i++)
|
||||
if(plot->values[i] > plot->values[plot->max_index])
|
||||
plot->max_index = i;
|
||||
|
||||
plot->current_max = MAX(plot->values[plot->max_index], plot->max_value);
|
||||
|
||||
/* recalculate */
|
||||
for(i = 0; i < d->size; i++)
|
||||
plot->lines[i] = round(plot->values[i] * d->box_height / plot->current_max);
|
||||
}
|
||||
else
|
||||
plot->lines[plot->index] = round(value * d->box_height / plot->current_max);
|
||||
}
|
||||
else /* scale option is false - limit to d->box_height */
|
||||
{
|
||||
if(value < plot->max_value)
|
||||
plot->lines[plot->index] = round(value * d->box_height / plot->max_value);
|
||||
else
|
||||
plot->lines[plot->index] = d->box_height;
|
||||
}
|
||||
|
||||
widget_invalidate_bywidget(widget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Graph widget.
|
||||
* DEPRECATED, see awful.widget.graph.
|
||||
* \param L The Lua VM state.
|
||||
* \param token The key token.
|
||||
* \return The number of elements pushed on stack.
|
||||
* \luastack
|
||||
* \lfield plot_properties_set A function to set plot properties.
|
||||
* \lfield plot_data_add A function to add data to a plot.
|
||||
* \lfield height Graph height.
|
||||
* \lfield widget Graph width.
|
||||
* \lfield bg Background color.
|
||||
* \lfield grow Direction to grow: left or right.
|
||||
*/
|
||||
static int
|
||||
luaA_graph_index(lua_State *L, awesome_token_t token)
|
||||
{
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
graph_data_t *d = widget->data;
|
||||
|
||||
switch(token)
|
||||
{
|
||||
case A_TK_PLOT_PROPERTIES_SET:
|
||||
lua_pushcfunction(L, luaA_graph_plot_properties_set);
|
||||
break;
|
||||
case A_TK_PLOT_DATA_ADD:
|
||||
lua_pushcfunction(L, luaA_graph_plot_data_add);
|
||||
break;
|
||||
case A_TK_HEIGHT:
|
||||
lua_pushnumber(L, d->height);
|
||||
break;
|
||||
case A_TK_WIDTH:
|
||||
lua_pushnumber(L, d->width);
|
||||
break;
|
||||
case A_TK_BORDER_COLOR:
|
||||
luaA_pushcolor(L, &d->border_color);
|
||||
break;
|
||||
case A_TK_BG:
|
||||
luaA_pushcolor(L, &d->bg);
|
||||
break;
|
||||
case A_TK_GROW:
|
||||
switch(d->grow)
|
||||
{
|
||||
case Left:
|
||||
lua_pushliteral(L, "left");
|
||||
break;
|
||||
case Right:
|
||||
lua_pushliteral(L, "right");
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Newindex function for graph widget.
|
||||
* \param L The Lua VM state.
|
||||
* \param token The key token.
|
||||
* \return The number of elements pushed on stack.
|
||||
*/
|
||||
static int
|
||||
luaA_graph_newindex(lua_State *L, awesome_token_t token)
|
||||
{
|
||||
size_t len;
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
graph_data_t *d = widget->data;
|
||||
const char *buf;
|
||||
int width;
|
||||
position_t pos;
|
||||
color_t color;
|
||||
|
||||
switch(token)
|
||||
{
|
||||
case A_TK_HEIGHT:
|
||||
d->height = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_WIDTH:
|
||||
width = luaL_checknumber(L, 3);
|
||||
if(width >= 2 && width != d->width)
|
||||
{
|
||||
d->width = width;
|
||||
d->size = d->width - 2;
|
||||
p_realloc(&d->draw_from, d->size);
|
||||
p_realloc(&d->draw_to, d->size);
|
||||
for(int i = 0; i < d->plots.len; i++)
|
||||
{
|
||||
plot_t *plot = &d->plots.tab[i];
|
||||
p_realloc(&plot->values, d->size);
|
||||
p_realloc(&plot->lines, d->size);
|
||||
p_clear(plot->values, d->size);
|
||||
p_clear(plot->lines, d->size);
|
||||
plot->index = 0;
|
||||
plot->current_max = 0;
|
||||
plot->max_index = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case A_TK_BG:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
{
|
||||
if(color_init_reply(color_init_unchecked(&color, buf, len)))
|
||||
d->bg = color;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case A_TK_BORDER_COLOR:
|
||||
if((buf = luaL_checklstring(L, 3, &len)))
|
||||
{
|
||||
if(color_init_reply(color_init_unchecked(&color, buf, len)))
|
||||
d->border_color = color;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case A_TK_GROW:
|
||||
buf = luaL_checklstring(L, 3, &len);
|
||||
switch((pos = position_fromstr(buf, len)))
|
||||
{
|
||||
case Left:
|
||||
case Right:
|
||||
d->grow = pos;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
widget_invalidate_bywidget(widget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Destroy definitively a graph widget.
|
||||
* \param widget Who slay.
|
||||
*/
|
||||
static void
|
||||
graph_destructor(widget_t *widget)
|
||||
{
|
||||
graph_data_t *d = widget->data;
|
||||
|
||||
plot_array_wipe(&d->plots);
|
||||
p_delete(&d->draw_from);
|
||||
p_delete(&d->draw_to);
|
||||
p_delete(&d);
|
||||
}
|
||||
|
||||
/** Create a brand new graph.
|
||||
* \param w The widget to initialize.
|
||||
* \return The same widget.
|
||||
*/
|
||||
widget_t *
|
||||
widget_graph(widget_t *w)
|
||||
{
|
||||
luaA_deprecate(globalconf.L, "awful.widget.graph");
|
||||
w->draw = graph_draw;
|
||||
w->index = luaA_graph_index;
|
||||
w->newindex = luaA_graph_newindex;
|
||||
w->destructor = graph_destructor;
|
||||
w->extents = graph_extents;
|
||||
|
||||
graph_data_t *d = w->data = p_new(graph_data_t, 1);
|
||||
|
||||
d->width = 80;
|
||||
d->height = 0.80;
|
||||
d->size = d->width - 2;
|
||||
d->grow = Left;
|
||||
d->draw_from = p_new(int, d->size);
|
||||
d->draw_to = p_new(int, d->size);
|
||||
|
||||
xcolor_to_color(&globalconf.colors.bg, &d->bg);
|
||||
xcolor_to_color(&globalconf.colors.fg, &d->border_color);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/* This is used for building documentation. */
|
||||
static const struct luaL_reg awesome_graph_meta[] __attribute__ ((unused)) =
|
||||
{
|
||||
{ "plot_properties_set", luaA_graph_plot_properties_set },
|
||||
{ "plot_data_add", luaA_graph_plot_data_add },
|
||||
};
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -1,680 +0,0 @@
|
|||
/*
|
||||
* progressbar.c - progressbar 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 "widget.h"
|
||||
#include "luaa.h"
|
||||
#include "common/tokenize.h"
|
||||
|
||||
/** Progressbar bar data structure */
|
||||
typedef struct
|
||||
{
|
||||
/** Title of the data/bar */
|
||||
char *title;
|
||||
/** These or lower values won't fill the bar at all*/
|
||||
float min_value;
|
||||
/** These or higher values fill the bar fully */
|
||||
float max_value;
|
||||
/** Pointer to value */
|
||||
float value;
|
||||
/** Reverse filling */
|
||||
bool reverse;
|
||||
/** Foreground color */
|
||||
color_t fg;
|
||||
/** Foreground color of turned-off ticks */
|
||||
color_t fg_off;
|
||||
/** Foreground color when bar is half-full */
|
||||
color_t fg_center;
|
||||
/** Foreground color when bar is full */
|
||||
color_t fg_end;
|
||||
/** Background color */
|
||||
color_t bg;
|
||||
/** Border color */
|
||||
color_t border_color;
|
||||
} bar_t;
|
||||
|
||||
/** Delete a bar.
|
||||
* \param bar The bar to annihilate.
|
||||
*/
|
||||
static void
|
||||
bar_delete(bar_t *bar)
|
||||
{
|
||||
p_delete(&bar->title);
|
||||
}
|
||||
|
||||
DO_ARRAY(bar_t, bar, bar_delete)
|
||||
|
||||
/** Progressbar private data structure */
|
||||
typedef struct
|
||||
{
|
||||
/** Width of the data_items */
|
||||
int width;
|
||||
/** Pixel between data items (bars) */
|
||||
int gap;
|
||||
/** Border width in pixels */
|
||||
int border_width;
|
||||
/** Padding between border and ticks/bar */
|
||||
int border_padding;
|
||||
/** Gap/distance between the individual ticks */
|
||||
int ticks_gap;
|
||||
/** Total number of ticks */
|
||||
int ticks_count;
|
||||
/** 90 Degree's turned */
|
||||
bool vertical;
|
||||
/** Height 0-1, where 1.0 is height of bar */
|
||||
float height;
|
||||
/** The bars */
|
||||
bar_array_t bars;
|
||||
} progressbar_data_t;
|
||||
|
||||
/** Add a new bar to the progressbar private data structure.
|
||||
* \param bars The bar array.
|
||||
* \param title The bar title.
|
||||
* \return The new bar.
|
||||
*/
|
||||
static bar_t *
|
||||
progressbar_bar_add(bar_array_t *bars, const char *title)
|
||||
{
|
||||
bar_t bar;
|
||||
|
||||
p_clear(&bar, 1);
|
||||
|
||||
bar.title = a_strdup(title);
|
||||
bar.max_value = 100.0;
|
||||
|
||||
xcolor_to_color(&globalconf.colors.fg, &bar.fg);
|
||||
xcolor_to_color(&globalconf.colors.bg, &bar.bg);
|
||||
xcolor_to_color(&globalconf.colors.bg, &bar.fg_off);
|
||||
xcolor_to_color(&globalconf.colors.fg, &bar.border_color);
|
||||
|
||||
/* append the bar in the list */
|
||||
bar_array_append(bars, bar);
|
||||
|
||||
return &bars->tab[bars->len - 1];
|
||||
}
|
||||
|
||||
/** Get the bar, and create one if it does not exist.
|
||||
* \param bars The bar array.
|
||||
* \param title The bar title.
|
||||
* \return A maybe new bar.
|
||||
*/
|
||||
static bar_t *
|
||||
progressbar_bar_get(bar_array_t *bars, const char *title)
|
||||
{
|
||||
bar_t *bar;
|
||||
|
||||
/* check if this section is defined already */
|
||||
for(int j = 0; j < bars->len; j++)
|
||||
{
|
||||
bar = &bars->tab[j];
|
||||
if(!a_strcmp(title, bar->title))
|
||||
return bar;
|
||||
}
|
||||
|
||||
/* no bar found -> create one */
|
||||
return progressbar_bar_add(bars, title);
|
||||
}
|
||||
|
||||
static area_t
|
||||
progressbar_geometry(widget_t *widget, int screen)
|
||||
{
|
||||
area_t geometry;
|
||||
progressbar_data_t *d = widget->data;
|
||||
|
||||
|
||||
if(d->vertical)
|
||||
{
|
||||
int pb_width = (int) ((d->width - 2 * (d->border_width + d->border_padding) * d->bars.len
|
||||
- d->gap * (d->bars.len - 1)) / d->bars.len);
|
||||
geometry.width = d->bars.len * (pb_width + 2 * (d->border_width + d->border_padding)
|
||||
+ d->gap) - d->gap;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pb_width = d->width - 2 * (d->border_width + d->border_padding);
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
int unit = (pb_width + d->ticks_gap) / d->ticks_count;
|
||||
pb_width = unit * d->ticks_count - d->ticks_gap; /* rounded to match ticks... */
|
||||
}
|
||||
geometry.width = pb_width + 2 * (d->border_width + d->border_padding);
|
||||
}
|
||||
geometry.height = geometry.width;
|
||||
|
||||
geometry.x = geometry.y = 0;
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
static area_t
|
||||
progressbar_extents(lua_State *L, widget_t *widget)
|
||||
{
|
||||
return progressbar_geometry(widget, 0);
|
||||
}
|
||||
|
||||
/** Draw a progressbar.
|
||||
* \param ctx The draw context.
|
||||
* \param w The widget node we're drawing for.
|
||||
* \param offset Offset to draw at.
|
||||
* \param used Space already used.
|
||||
* \param object The object pointer we're drawing onto.
|
||||
* \return The width used.
|
||||
*/
|
||||
static void
|
||||
progressbar_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p)
|
||||
{
|
||||
/* pb_.. values points to the widget inside a potential border */
|
||||
int values_ticks, pb_x, pb_y, pb_height, pb_width, pb_progress, pb_offset;
|
||||
int unit = 0; /* tick + gap */
|
||||
area_t rectangle;
|
||||
vector_t color_gradient;
|
||||
progressbar_data_t *d = widget->data;
|
||||
|
||||
if(!d->bars.len)
|
||||
return;
|
||||
|
||||
/* for a 'reversed' progressbar:
|
||||
* basic progressbar:
|
||||
* 1. the full space gets the size of the formerly empty one
|
||||
* 2. the pattern must be mirrored
|
||||
* 3. the formerly 'empty' side is drawn with fg colors, the 'full' with bg-color
|
||||
*
|
||||
* ticks:
|
||||
* 1. round the values to a full tick accordingly
|
||||
* 2. finally draw the gaps
|
||||
*/
|
||||
|
||||
pb_x = geometry.x + d->border_width + d->border_padding;
|
||||
pb_offset = 0;
|
||||
|
||||
if(d->vertical)
|
||||
{
|
||||
pb_width = (int) ((d->width - 2 * (d->border_width + d->border_padding) * d->bars.len
|
||||
- d->gap * (d->bars.len - 1)) / d->bars.len);
|
||||
|
||||
/** \todo maybe prevent to calculate that stuff below over and over again
|
||||
* (->use static-values) */
|
||||
pb_height = (int) (ctx->height * d->height + 0.5)
|
||||
- 2 * (d->border_width + d->border_padding);
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
/* '+ d->ticks_gap' because a unit includes a ticks + ticks_gap */
|
||||
unit = (pb_height + d->ticks_gap) / d->ticks_count;
|
||||
pb_height = unit * d->ticks_count - d->ticks_gap;
|
||||
}
|
||||
|
||||
pb_y = geometry.y + ((int) (ctx->height * (1 - d->height)) / 2)
|
||||
+ d->border_width + d->border_padding;
|
||||
|
||||
for(int i = 0; i < d->bars.len; i++)
|
||||
{
|
||||
bar_t *bar = &d->bars.tab[i];
|
||||
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
values_ticks = (int)(d->ticks_count * (bar->value - bar->min_value)
|
||||
/ (bar->max_value - bar->min_value) + 0.5);
|
||||
if(values_ticks)
|
||||
pb_progress = values_ticks * unit - d->ticks_gap;
|
||||
else
|
||||
pb_progress = 0;
|
||||
}
|
||||
else
|
||||
/* e.g.: min = 50; max = 56; 53 should show 50% graph
|
||||
* (53(val) - 50(min) / (56(max) - 50(min) = 3 / 5 = 0.5 = 50%
|
||||
* round that ( + 0.5 and (int)) and finally multiply with height
|
||||
*/
|
||||
pb_progress = (int) (pb_height * (bar->value - bar->min_value)
|
||||
/ (bar->max_value - bar->min_value) + 0.5);
|
||||
|
||||
if(d->border_width)
|
||||
{
|
||||
/* border rectangle */
|
||||
rectangle.x = pb_x + pb_offset - d->border_width - d->border_padding;
|
||||
rectangle.y = pb_y - d->border_width - d->border_padding;
|
||||
rectangle.width = pb_width + 2 * (d->border_padding + d->border_width);
|
||||
rectangle.height = pb_height + 2 * (d->border_padding + d->border_width);
|
||||
|
||||
if(d->border_padding)
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->bg);
|
||||
draw_rectangle(ctx, rectangle, d->border_width, false, &bar->border_color);
|
||||
}
|
||||
|
||||
color_gradient.x = pb_x;
|
||||
color_gradient.x_offset = 0;
|
||||
color_gradient.y = pb_y;
|
||||
|
||||
/* new value/progress in px + pattern setup */
|
||||
if(bar->reverse)
|
||||
{
|
||||
/* invert: top with bottom part */
|
||||
pb_progress = pb_height - pb_progress;
|
||||
color_gradient.y_offset = pb_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bottom to top */
|
||||
color_gradient.y += pb_height;
|
||||
color_gradient.y_offset = - pb_height;
|
||||
}
|
||||
|
||||
/* bottom part */
|
||||
if(pb_progress > 0)
|
||||
{
|
||||
rectangle.x = pb_x + pb_offset;
|
||||
rectangle.y = pb_y + pb_height - pb_progress;
|
||||
rectangle.width = pb_width;
|
||||
rectangle.height = pb_progress;
|
||||
|
||||
/* fg color */
|
||||
if(bar->reverse)
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->fg_off);
|
||||
else
|
||||
draw_rectangle_gradient(ctx, rectangle, 1.0, true, color_gradient,
|
||||
&bar->fg, &bar->fg_center, &bar->fg_end);
|
||||
}
|
||||
|
||||
/* top part */
|
||||
if(pb_height - pb_progress > 0) /* not filled area */
|
||||
{
|
||||
rectangle.x = pb_x + pb_offset;
|
||||
rectangle.y = pb_y;
|
||||
rectangle.width = pb_width;
|
||||
rectangle.height = pb_height - pb_progress;
|
||||
|
||||
/* bg color */
|
||||
if(bar->reverse)
|
||||
draw_rectangle_gradient(ctx, rectangle, 1.0, true, color_gradient,
|
||||
&bar->fg, &bar->fg_center, &bar->fg_end);
|
||||
else
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->fg_off);
|
||||
}
|
||||
/* draw gaps \todo improve e.g all in one */
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
rectangle.width = pb_width;
|
||||
rectangle.height = d->ticks_gap;
|
||||
rectangle.x = pb_x + pb_offset;
|
||||
for(rectangle.y = pb_y + (unit - d->ticks_gap);
|
||||
pb_y + pb_height - d->ticks_gap >= rectangle.y;
|
||||
rectangle.y += unit)
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->bg);
|
||||
}
|
||||
pb_offset += pb_width + d->gap + 2 * (d->border_width + d->border_padding);
|
||||
}
|
||||
}
|
||||
else /* a horizontal progressbar */
|
||||
{
|
||||
pb_width = d->width - 2 * (d->border_width + d->border_padding);
|
||||
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
unit = (pb_width + d->ticks_gap) / d->ticks_count;
|
||||
pb_width = unit * d->ticks_count - d->ticks_gap; /* rounded to match ticks... */
|
||||
}
|
||||
|
||||
pb_height = (int) ((ctx->height * d->height
|
||||
- d->bars.len * 2 * (d->border_width + d->border_padding)
|
||||
- (d->gap * (d->bars.len - 1))) / d->bars.len + 0.5);
|
||||
pb_y = geometry.y + ((int) (ctx->height * (1 - d->height)) / 2)
|
||||
+ d->border_width + d->border_padding;
|
||||
|
||||
for(int i = 0; i < d->bars.len; i++)
|
||||
{
|
||||
bar_t *bar = &d->bars.tab[i];
|
||||
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
/* +0.5 rounds up ticks -> turn on a tick when half of it is reached */
|
||||
values_ticks = (int)(d->ticks_count * (bar->value - bar->min_value)
|
||||
/ (bar->max_value - bar->min_value) + 0.5);
|
||||
if(values_ticks)
|
||||
pb_progress = values_ticks * unit - d->ticks_gap;
|
||||
else
|
||||
pb_progress = 0;
|
||||
}
|
||||
else
|
||||
pb_progress = (int) (pb_width * (bar->value - bar->min_value)
|
||||
/ (bar->max_value - bar->min_value) + 0.5);
|
||||
|
||||
if(d->border_width)
|
||||
{
|
||||
/* border rectangle */
|
||||
rectangle.x = pb_x - d->border_width - d->border_padding;
|
||||
rectangle.y = pb_y + pb_offset - d->border_width - d->border_padding;
|
||||
rectangle.width = pb_width + 2 * (d->border_padding + d->border_width);
|
||||
rectangle.height = pb_height + 2 * (d->border_padding + d->border_width);
|
||||
|
||||
if(d->border_padding)
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->bg);
|
||||
draw_rectangle(ctx, rectangle, d->border_width, false, &bar->border_color);
|
||||
}
|
||||
|
||||
color_gradient.y = pb_y;
|
||||
color_gradient.y_offset = 0;
|
||||
color_gradient.x = pb_x;
|
||||
|
||||
/* new value/progress in px + pattern setup */
|
||||
if(bar->reverse)
|
||||
{
|
||||
/* reverse: right to left */
|
||||
pb_progress = pb_width - pb_progress;
|
||||
color_gradient.x += pb_width;
|
||||
color_gradient.x_offset = - pb_width;
|
||||
}
|
||||
else
|
||||
/* left to right */
|
||||
color_gradient.x_offset = pb_width;
|
||||
|
||||
/* left part */
|
||||
if(pb_progress > 0)
|
||||
{
|
||||
rectangle.x = pb_x;
|
||||
rectangle.y = pb_y + pb_offset;
|
||||
rectangle.width = pb_progress;
|
||||
rectangle.height = pb_height;
|
||||
|
||||
/* fg color */
|
||||
if(bar->reverse)
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->fg_off);
|
||||
else
|
||||
draw_rectangle_gradient(ctx, rectangle, 1.0, true, color_gradient,
|
||||
&bar->fg, &bar->fg_center, &bar->fg_end);
|
||||
}
|
||||
|
||||
/* right part */
|
||||
if(pb_width - pb_progress > 0)
|
||||
{
|
||||
rectangle.x = pb_x + pb_progress;
|
||||
rectangle.y = pb_y + pb_offset;
|
||||
rectangle.width = pb_width - pb_progress;
|
||||
rectangle.height = pb_height;
|
||||
|
||||
/* bg color */
|
||||
if(bar->reverse)
|
||||
draw_rectangle_gradient(ctx, rectangle, 1.0, true, color_gradient,
|
||||
&bar->fg, &bar->fg_center, &bar->fg_end);
|
||||
else
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->fg_off);
|
||||
}
|
||||
/* draw gaps \todo improve e.g all in one */
|
||||
if(d->ticks_count && d->ticks_gap)
|
||||
{
|
||||
rectangle.width = d->ticks_gap;
|
||||
rectangle.height = pb_height;
|
||||
rectangle.y = pb_y + pb_offset;
|
||||
for(rectangle.x = pb_x + (unit - d->ticks_gap);
|
||||
pb_x + pb_width - d->ticks_gap >= rectangle.x;
|
||||
rectangle.x += unit)
|
||||
draw_rectangle(ctx, rectangle, 1.0, true, &bar->bg);
|
||||
}
|
||||
|
||||
pb_offset += pb_height + d->gap + 2 * (d->border_width + d->border_padding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Set various progressbar bars properties:
|
||||
* \param L The Lua VM state.
|
||||
* \return The number of elements pushed on the stack.
|
||||
* \luastack
|
||||
* \lvalue A widget.
|
||||
* \lparam A bar name.
|
||||
* \lparam A table with keys as properties names.
|
||||
*/
|
||||
static int
|
||||
luaA_progressbar_bar_properties_set(lua_State *L)
|
||||
{
|
||||
size_t len;
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
const char *buf, *title = luaL_checkstring(L, 2);
|
||||
bar_t *bar;
|
||||
progressbar_data_t *d = widget->data;
|
||||
color_init_cookie_t reqs[6];
|
||||
int i, reqs_nbr = -1;
|
||||
|
||||
luaA_checktable(L, 3);
|
||||
|
||||
bar = progressbar_bar_get(&d->bars, title);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&bar->fg, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg_off", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&bar->fg_off, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "bg", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&bar->bg, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "border_color", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&bar->border_color, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg_center", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&bar->fg_center, buf, len);
|
||||
|
||||
if((buf = luaA_getopt_lstring(L, 3, "fg_end", NULL, &len)))
|
||||
reqs[++reqs_nbr] = color_init_unchecked(&bar->fg_end, buf, len);
|
||||
|
||||
bar->min_value = luaA_getopt_number(L, 3, "min_value", bar->min_value);
|
||||
/* hack to prevent max_value beeing less than min_value
|
||||
* and also preventing a division by zero when both are equal */
|
||||
if(bar->max_value <= bar->min_value)
|
||||
bar->max_value = bar->max_value + 0.0001;
|
||||
/* force a actual value into the newly possible range */
|
||||
if(bar->value < bar->min_value)
|
||||
bar->value = bar->min_value;
|
||||
|
||||
bar->max_value = luaA_getopt_number(L, 3, "max_value", bar->max_value);
|
||||
if(bar->min_value >= bar->max_value)
|
||||
bar->min_value = bar->max_value - 0.0001;
|
||||
if(bar->value > bar->max_value)
|
||||
bar->value = bar->max_value;
|
||||
|
||||
bar->reverse = luaA_getopt_boolean(L, 3, "reverse", bar->reverse);
|
||||
|
||||
for(i = 0; i <= reqs_nbr; i++)
|
||||
color_init_reply(reqs[i]);
|
||||
|
||||
widget_invalidate_bywidget(widget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Add a value to a progressbar bar.
|
||||
* \param L The Lua VM state.
|
||||
* \return The number of elements pushed on the stack.
|
||||
* \luastack
|
||||
* \lvalue A widget.
|
||||
* \lparam A bar name.
|
||||
* \lparam A data value.
|
||||
*/
|
||||
static int
|
||||
luaA_progressbar_bar_data_add(lua_State *L)
|
||||
{
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
const char *title = luaL_checkstring(L, 2);
|
||||
progressbar_data_t *d = widget->data;
|
||||
bar_t *bar;
|
||||
|
||||
bar = progressbar_bar_get(&d->bars, title);
|
||||
|
||||
bar->value = luaL_checknumber(L, 3);
|
||||
bar->value = MAX(bar->min_value, MIN(bar->max_value, bar->value));
|
||||
|
||||
widget_invalidate_bywidget(widget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Progressbar widget.
|
||||
* DEPRECATED, see awful.widget.progressbar.
|
||||
* \param L The Lua VM state.
|
||||
* \param token The key token.
|
||||
* \return The number of elements pushed on the stack.
|
||||
* \luastack
|
||||
* \lfield bar_properties_set Set the properties of a bar.
|
||||
* \lfield bar_data_add Add data to a bar.
|
||||
* \lfield gap Gap betweens bars.
|
||||
* \lfield ticks_gap Gap between ticks.
|
||||
* \lfield ticks_count Number of ticks.
|
||||
* \lfield border_padding Border padding.
|
||||
* \lfield border_width Border width.
|
||||
* \lfield width Bars width.
|
||||
* \lfield height Bars height.
|
||||
* \lfield vertical True: draw bar vertically, false: horizontally.
|
||||
*/
|
||||
static int
|
||||
luaA_progressbar_index(lua_State *L, awesome_token_t token)
|
||||
{
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
progressbar_data_t *d = widget->data;
|
||||
|
||||
switch(token)
|
||||
{
|
||||
case A_TK_BAR_PROPERTIES_SET:
|
||||
lua_pushcfunction(L, luaA_progressbar_bar_properties_set);
|
||||
break;
|
||||
case A_TK_BAR_DATA_ADD:
|
||||
lua_pushcfunction(L, luaA_progressbar_bar_data_add);
|
||||
break;
|
||||
case A_TK_GAP:
|
||||
lua_pushnumber(L, d->gap);
|
||||
break;
|
||||
case A_TK_TICKS_GAP:
|
||||
lua_pushnumber(L, d->ticks_gap);
|
||||
break;
|
||||
case A_TK_TICKS_COUNT:
|
||||
lua_pushnumber(L, d->ticks_count);
|
||||
break;
|
||||
case A_TK_BORDER_PADDING:
|
||||
lua_pushnumber(L, d->border_padding);
|
||||
break;
|
||||
case A_TK_BORDER_WIDTH:
|
||||
lua_pushnumber(L, d->border_width);
|
||||
break;
|
||||
case A_TK_WIDTH:
|
||||
lua_pushnumber(L, d->width);
|
||||
break;
|
||||
case A_TK_HEIGHT:
|
||||
lua_pushnumber(L, d->height);
|
||||
break;
|
||||
case A_TK_VERTICAL:
|
||||
lua_pushboolean(L, d->vertical);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Newindex function for progressbar.
|
||||
* \param L The Lua VM state.
|
||||
* \param token The key token.
|
||||
* \return The number of elements pushed on the stack.
|
||||
*/
|
||||
static int
|
||||
luaA_progressbar_newindex(lua_State *L, awesome_token_t token)
|
||||
{
|
||||
widget_t *widget = luaA_checkudata(L, 1, &widget_class);
|
||||
progressbar_data_t *d = widget->data;
|
||||
|
||||
switch(token)
|
||||
{
|
||||
case A_TK_GAP:
|
||||
d->gap = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_TICKS_COUNT:
|
||||
d->ticks_count = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_TICKS_GAP:
|
||||
d->ticks_gap = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_BORDER_PADDING:
|
||||
d->border_padding = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_BORDER_WIDTH:
|
||||
d->border_width = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_WIDTH:
|
||||
d->width = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_HEIGHT:
|
||||
d->height = luaL_checknumber(L, 3);
|
||||
break;
|
||||
case A_TK_VERTICAL:
|
||||
d->vertical = luaA_checkboolean(L, 3);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
widget_invalidate_bywidget(widget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Destroy a progressbar.
|
||||
* \param widget The widget to kill.
|
||||
*/
|
||||
static void
|
||||
progressbar_destructor(widget_t *widget)
|
||||
{
|
||||
progressbar_data_t *d = widget->data;
|
||||
|
||||
bar_array_wipe(&d->bars);
|
||||
p_delete(&d);
|
||||
}
|
||||
|
||||
/** Create a new progressbar.
|
||||
* \param w The widget to initialize.
|
||||
* \return A brand new progressbar.
|
||||
*/
|
||||
widget_t *
|
||||
widget_progressbar(widget_t *w)
|
||||
{
|
||||
luaA_deprecate(globalconf.L, "awful.widget.progressbar");
|
||||
w->draw = progressbar_draw;
|
||||
w->index = luaA_progressbar_index;
|
||||
w->newindex = luaA_progressbar_newindex;
|
||||
w->destructor = progressbar_destructor;
|
||||
w->extents = progressbar_extents;
|
||||
|
||||
progressbar_data_t *d = w->data = p_new(progressbar_data_t, 1);
|
||||
|
||||
d->height = 0.80;
|
||||
d->width = 80;
|
||||
|
||||
d->ticks_gap = 1;
|
||||
d->border_width = 1;
|
||||
d->gap = 2;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/* This is used for building documentation. */
|
||||
static const struct luaL_reg awesome_progressbar_meta[] __attribute__ ((unused)) =
|
||||
{
|
||||
{ "bar_properties_set", luaA_progressbar_bar_properties_set },
|
||||
{ "bar_data_add", luaA_progressbar_bar_data_add },
|
||||
};
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
Loading…
Reference in New Issue