diff options
| author | Agney Lopes Roth Ferraz <agney@debian.org> | 2006-05-22 19:43:53 -0300 | 
|---|---|---|
| committer | Simon Quigley <tsimonq2@ubuntu.com> | 2017-06-19 14:38:34 -0500 | 
| commit | 1db37ee0b1dbfebe11ff6a0eee8000392e4f3f61 (patch) | |
| tree | 02b7da09dbd8cdf8828c01f47154fc76269eb9cc /loadgraph.c | |
| parent | 1a3b201e8e94d8c07b3e0a2ce1af22293a53b506 (diff) | |
| parent | 854292407779593a401a1d5ce71add51880fa84f (diff) | |
Import Debian changes 0.4-1
hardinfo (0.4-1) unstable; urgency=low
  * new upstream release
Diffstat (limited to 'loadgraph.c')
| -rw-r--r-- | loadgraph.c | 266 | 
1 files changed, 266 insertions, 0 deletions
diff --git a/loadgraph.c b/loadgraph.c new file mode 100644 index 00000000..a15af347 --- /dev/null +++ b/loadgraph.c @@ -0,0 +1,266 @@ +/* + * Simple Load Graph + * Version 0.1 - Wed, Jan 11 2006 + *   - initial release + * Version 0.1.1 - Fri, Jan 13 2006 + *   - fixes autoscaling + *   - add color + * + * Copyright (C) 2006 Leandro A. F. Pereira <leandro@linuxmag.com.br> + * + * The Simple Load Graph is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License, version 2.1, as published by the Free Software Foundation. + * + * The Simple Load Graph 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Simple Load Graph; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA.  + */ + +#include "loadgraph.h" + +static void _draw(LoadGraph *lg); + +LoadGraph *load_graph_new(gint size) +{ +    LoadGraph *lg; +     +    lg = g_new0(LoadGraph, 1); +     +    lg->area = gtk_drawing_area_new(); +    lg->size = size; +    lg->data = g_new0(gint, size); + +    lg->scale = 1.0; +     +    lg->width  = size * 4; +    lg->height = size * 2; +     +    gtk_widget_set_size_request(lg->area, lg->width, lg->height); +    gtk_widget_show(lg->area); +     +    return lg; +} + +GtkWidget *load_graph_get_framed(LoadGraph *lg) +{ +    GtkWidget *align, *frame; +     +    align = gtk_alignment_new(0.5, 0.5, 0, 0); +    gtk_widget_show(align); +     +    frame = gtk_frame_new(NULL); +    gtk_widget_show(frame); +    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); +     +    gtk_container_add(GTK_CONTAINER(align), frame); +    gtk_container_add(GTK_CONTAINER(frame), lg->area); +     +    return align; +} + +void load_graph_clear(LoadGraph *lg) +{ +    gint i; +     +    for (i = 0; i < lg->size; i++) +        lg->data[i] = 0; + +    lg->scale = 1.0; +    _draw(lg); +} + +void load_graph_set_color(LoadGraph *lg, LoadGraphColor color) +{ +    lg->color = color; +    gdk_rgb_gc_set_foreground(lg->trace, lg->color); +} + +void load_graph_destroy(LoadGraph *lg) +{ +    g_free(lg->data); +    gtk_widget_destroy(lg->area); +    gdk_pixmap_unref(lg->buf); +    g_object_unref(lg->trace); +    g_object_unref(lg->grid); +    g_free(lg); +} + +static gboolean _expose(GtkWidget *widget, GdkEventExpose *event, +                    gpointer user_data) +{ +    LoadGraph *lg = (LoadGraph *)user_data; +    GdkDrawable *draw = GDK_DRAWABLE(lg->buf); + +    gdk_draw_drawable(lg->area->window, +                      lg->area->style->white_gc, +                      draw, +                      0, 0, +                      0, 0, +                      lg->width, lg->height); +    return FALSE; +}                     + +void load_graph_configure_expose(LoadGraph *lg) +{ +    /* creates the backing store pixmap */ +    gtk_widget_realize(lg->area); +    lg->buf = gdk_pixmap_new(lg->area->window, lg->width, lg->height, -1); + +    /* create the graphic contexts */ +    lg->grid = gdk_gc_new(GDK_DRAWABLE(lg->buf)); +    lg->trace = gdk_gc_new(GDK_DRAWABLE(lg->buf)); + +    /* the default color is green */ +    load_graph_set_color(lg, LG_COLOR_GREEN); + +    /* init graphic contexts */ +    gdk_gc_set_line_attributes(lg->grid,  +                               1, GDK_LINE_ON_OFF_DASH, +                               GDK_CAP_NOT_LAST, +                               GDK_JOIN_ROUND); +    gdk_rgb_gc_set_foreground(lg->grid, 0x707070); + +    gdk_gc_set_line_attributes(lg->trace,  +                               2, GDK_LINE_SOLID, +                               GDK_CAP_NOT_LAST, +                               GDK_JOIN_ROUND); + +    /* configures the expose event */ +    g_signal_connect(G_OBJECT(lg->area), "expose-event",  +                     (GCallback) _expose, lg); +} + +static void +_draw(LoadGraph *lg) +{ +    GdkDrawable *draw = GDK_DRAWABLE(lg->buf); +    gint i, d; +     +    /* clears the drawing area */ +    gdk_draw_rectangle(draw, lg->area->style->black_gc, +                       TRUE, 0, 0, lg->width, lg->height); +                       +    /* horizontal bars; 25%, 50% and 75% */  +    d = lg->height / 4; +    gdk_draw_line(draw, lg->grid, 0, d, lg->width, d); +    d = lg->height / 2; +    gdk_draw_line(draw, lg->grid, 0, d, lg->width, d); +    d = 3 * (lg->height / 4); +    gdk_draw_line(draw, lg->grid, 0, d, lg->width, d); + +    /* vertical bars */ +    for (i = lg->width, d = 0; i > 1; i--, d++) +        if ((d % 45) == 0 && d) +            gdk_draw_line(draw, lg->grid, i, 0, i, lg->height); + +    /* the graph */ +    for (i = 0; i < lg->size; i++) { +          gint this = lg->height - lg->data[i]; +          gint next = lg->height - lg->data[i+1]; +     +          gdk_draw_line(draw, lg->trace, i * 4, this, i * 4 + 2, +                        (this + next) / 2); +          gdk_draw_line(draw, lg->trace, i * 4 + 2, (this + next) / 2, +                        i * 4 + 4, next);  +    } +     +    gtk_widget_queue_draw(lg->area); +} + +static inline int +_max(LoadGraph *lg) +{ +    gint i; +    gint max = 0; +     +    for (i = 0; i < lg->size; i++) { +        if (lg->data[i] > max) +            max = lg->data[i]; +    } +     +    return max; +} + +void +load_graph_update(LoadGraph *lg, gint value) +{ +    gint i; +     +    if (value < 0) +        return; +    else if (value > _max(lg) && value > lg->height) { +        /* FIXME: make scale work correctly :P */ +        gfloat nscale = (gfloat)lg->height / ceilf((float)value * lg->scale); + +        while (value * nscale > lg->height) { +            nscale *= .90; +        } +         +        if (nscale < lg->scale) { +            lg->scale = nscale; + +            for (i = 0; i < lg->size; i++) { +                lg->data[i] = (int)((float)lg->data[i] * lg->scale); +            } +        } +    } + +    value = (int)ceilf((float)value * lg->scale); +     +    /* shift-right our data */ +    for (i = 0; i < lg->size; i++) { +        lg->data[i] = lg->data[i+1]; +    } +     +    /* insert the updated value */ +    lg->data[i] = value; +     +    /* redraw */ +    _draw(lg); +} + +#ifdef LOADGRAPH_UNIT_TEST +gboolean lg_update(gpointer d) +{ +    LoadGraph *lg = (LoadGraph *)d; +     +    int i = 0; +    if ((rand() % 10) == 0) { +        i = rand() % 1000 + 500; +    } + +    load_graph_update(lg, rand() % 200 + i); +   +    return TRUE; +} + +int main(int argc, char **argv) +{ +    LoadGraph *lg; +    GtkWidget *window; +     +    gtk_init(&argc, &argv); +     +    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); +    gtk_widget_show(window); +     +    lg = load_graph_new(100); +    gtk_container_add(GTK_CONTAINER(window), lg->area); +    load_graph_configure_expose(lg); +     +    lg_update(lg); +     +    g_timeout_add(100, lg_update, lg); +     +    gtk_main(); +     +    return 0; +} +#endif  | 
