⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agbargraph.c

📁 gnome/gtk+编程宝典的源代码.
💻 C
字号:
/* agbargraph.c */#include "agbargraph.h"#include <stdio.h>#include <stdlib.h>static void ag_bargraph_class_init(AgBargraphClass *klass);static void ag_bargraph_init(AgBargraph *bargraph);static void ag_bargraph_realize(GtkWidget *widget);static void ag_bargraph_size_allocate(GtkWidget *widget,        GtkAllocation *allocation);static void ag_bargraph_send_configure(        AgBargraph *bargraph);static void ag_bargraph_draw(GtkWidget *widget,        GdkRectangle *area);static gint ag_bargraph_event(GtkWidget *widget,        GdkEvent *event);static void ag_bargraph_size_request(GtkWidget *widget,        GtkRequisition *requisition);static void ag_bargraph_destroy(GtkObject *object);static void ag_bargraph_paint(GtkWidget *widget);static void ag_bargraph_add_gc(GtkWidget *widget,        AgBargraphBar *bar);static void ag_bargraph_set_text(GtkWidget *widget,        GdkEventButton *event);static void ag_bargraph_paint_text(GtkWidget *widget);guint ag_bargraph_get_type(void){    static guint ag_bargraph_type = 0;    if(!ag_bargraph_type) {        static const GtkTypeInfo ag_bargraph_info = {            "AgBargraph",            sizeof(AgBargraph),            sizeof(AgBargraphClass),            (GtkClassInitFunc)ag_bargraph_class_init,            (GtkObjectInitFunc)ag_bargraph_init,            NULL,            NULL,            (GtkClassInitFunc)NULL        };        ag_bargraph_type = gtk_type_unique(                gtk_widget_get_type(),&ag_bargraph_info);    }    return(ag_bargraph_type);}GtkWidget *ag_bargraph_new(){    GtkWidget *widget =        GTK_WIDGET(gtk_type_new(ag_bargraph_get_type()));    return(widget);}static void ag_bargraph_class_init(AgBargraphClass *klass){    GtkWidgetClass *widget_class;    GtkObjectClass *object_class;    widget_class = (GtkWidgetClass *)klass;    object_class = (GtkObjectClass *)klass;    widget_class->realize = ag_bargraph_realize;    widget_class->draw = ag_bargraph_draw;    widget_class->event = ag_bargraph_event;    widget_class->size_request = ag_bargraph_size_request;    widget_class->size_allocate =                            ag_bargraph_size_allocate;    object_class->destroy = ag_bargraph_destroy;}static void ag_bargraph_init(AgBargraph *bargraph){    GdkColor *color;    color = g_malloc(sizeof(GdkColor));    color->red = 45000;    color->blue = 15000;    color->green = 15000;    bargraph->outside_color = color;    color = g_malloc(sizeof(GdkColor));    color->red = 45000;    color->blue = 45000;    color->green = 45000;    bargraph->inside_color = color;    bargraph->bar_count = 0;    bargraph->bars = NULL;    bargraph->maximum_value = AG_BARGRAPH_MAXIMUM;    bargraph->contains_pointer = FALSE;}static void ag_bargraph_realize(GtkWidget *widget){    AgBargraph *bargraph;    GdkWindowAttr attributes;    guint attributes_mask;    g_return_if_fail(widget != NULL);    g_return_if_fail(AG_IS_BARGRAPH(widget));    bargraph = AG_BARGRAPH(widget);    GTK_WIDGET_SET_FLAGS(widget,GTK_REALIZED);    attributes.window_type = GDK_WINDOW_CHILD;    attributes.x = widget->allocation.x;    attributes.y = widget->allocation.y;    attributes.width = widget->allocation.width;    attributes.height = widget->allocation.height;    attributes.wclass = GDK_INPUT_OUTPUT;    attributes.visual = gtk_widget_get_visual(widget);    attributes.colormap = gtk_widget_get_colormap(widget);    attributes.event_mask = gtk_widget_get_events(widget);    attributes.event_mask |= (GDK_EXPOSURE_MASK |                            GDK_BUTTON_PRESS_MASK |                            GDK_BUTTON_RELEASE_MASK |                            GDK_ENTER_NOTIFY_MASK |                            GDK_LEAVE_NOTIFY_MASK);    attributes_mask = GDK_WA_X | GDK_WA_Y            | GDK_WA_VISUAL | GDK_WA_COLORMAP;    widget->window = gdk_window_new(            gtk_widget_get_parent_window(widget),            &attributes,attributes_mask);    gdk_window_set_user_data(widget->window,widget);    widget->style = gtk_style_attach(widget->style,            widget->window);    gtk_style_set_background(widget->style,            widget->window,GTK_STATE_NORMAL);    ag_bargraph_send_configure(AG_BARGRAPH(widget));    gdk_color_alloc(gtk_widget_get_colormap(widget),            bargraph->outside_color);    gdk_color_alloc(gtk_widget_get_colormap(widget),            bargraph->inside_color);}static void ag_bargraph_destroy(GtkObject *object){    int i;    AgBargraph *bargraph;    AgBargraphClass *klass;    g_return_if_fail(object != NULL);    g_return_if_fail(AG_IS_BARGRAPH(object));    bargraph = AG_BARGRAPH(object);    g_free(bargraph->outside_color);    g_free(bargraph->inside_color);    for(i=0; i<bargraph->bar_count; i++) {        g_free(bargraph->bars[i].name);        if(bargraph->bars[i].gc != NULL)            gdk_gc_destroy(bargraph->bars[i].gc);    }    g_free(bargraph->bars);    if(bargraph->text_font != NULL)        gdk_font_unref(bargraph->text_font);    klass = gtk_type_class(gtk_widget_get_type());    if(GTK_OBJECT_CLASS(klass)->destroy)       (* GTK_OBJECT_CLASS(klass)->destroy)(object);}static void ag_bargraph_draw(GtkWidget *widget,        GdkRectangle *area){    g_return_if_fail(widget != NULL);    g_return_if_fail(AG_IS_BARGRAPH(widget));    ag_bargraph_paint(widget);}static gint ag_bargraph_event(GtkWidget *widget,        GdkEvent *event){    AgBargraph *bargraph;    g_return_val_if_fail(widget != NULL,FALSE);    g_return_val_if_fail(AG_IS_BARGRAPH(widget),FALSE);    bargraph = AG_BARGRAPH(widget);    switch(event->type) {    case GDK_ENTER_NOTIFY:        bargraph->contains_pointer = TRUE;        break;    case GDK_LEAVE_NOTIFY:        bargraph->contains_pointer = FALSE;        break;    case GDK_BUTTON_PRESS:        ag_bargraph_set_text(widget,                (GdkEventButton *)event);        break;    case GDK_BUTTON_RELEASE:        bargraph->show_text = NULL;        break;    case GDK_EXPOSE:        break;    default:        return(FALSE);    }    ag_bargraph_paint(widget);    return(TRUE);}static void ag_bargraph_set_text(GtkWidget *widget,        GdkEventButton *event){    int i;    AgBargraph *bargraph = AG_BARGRAPH(widget);    bargraph->show_text = NULL;    for(i=0; i<bargraph->bar_count; i++) {        if((event->x > bargraph->bars[i].x_left) &&          (event->x <= bargraph->bars[i].x_right)) {            bargraph->show_text = bargraph->bars[i].name;            return;        }    }}static void ag_bargraph_paint(GtkWidget *widget){    int i;    AgBargraph *bargraph = AG_BARGRAPH(widget);    float bar_percent;    float bar_width;    float bar_height;    float bar_x;    float bar_y;    if(bargraph->contains_pointer) {        gdk_window_set_background(widget->window,                bargraph->inside_color);    } else {        gdk_window_set_background(widget->window,                bargraph->outside_color);    }    gdk_window_clear(widget->window);    bar_x = 0;    bar_width = (float)widget->allocation.width /            (float)bargraph->bar_count;    for(i=0; i<bargraph->bar_count; i++) {        if(bargraph->bars[i].gc == NULL)            ag_bargraph_add_gc(widget,&bargraph->bars[i]);        bar_percent = (float)bargraph->bars[i].value /                (float)bargraph->maximum_value;        bar_height = bar_percent                        * (float)widget->allocation.height;        bar_y = (float)widget->allocation.height                        * (1.0 - bar_percent);        gdk_draw_rectangle(widget->window,                bargraph->bars[i].gc,TRUE,                (gint)bar_x,(gint)bar_y,                (gint)bar_width + 1,(gint)bar_height + 1);        bargraph->bars[i].x_left = (gint)bar_x;        bar_x += bar_width;        bargraph->bars[i].x_right = (gint)bar_x;    }    ag_bargraph_paint_text(widget);}static void ag_bargraph_paint_text(GtkWidget *widget){    AgBargraph *bargraph = AG_BARGRAPH(widget);    gint lbearing;    gint rbearing;    gint width;    gint ascent;    gint descent;    gint x;    gint y;    if(bargraph->show_text == NULL)        return;    if(bargraph->text_font == NULL) {      bargraph->text_font = gdk_font_load(      "-*-bookman-light-r-normal--18-*-*-*-p-*-iso8859-1");    }    gdk_text_extents(bargraph->text_font,                bargraph->show_text,                strlen(bargraph->show_text),                &lbearing,                &rbearing,                &width,                &ascent,                &descent);    y = ascent;    x = (widget->allocation.width / 2) - (width / 2);    gdk_draw_string(widget->window,            bargraph->text_font,            widget->style->black_gc,            x,y,            bargraph->show_text);}static void ag_bargraph_add_gc(GtkWidget *widget,        AgBargraphBar *bar){    GdkColor color;    GdkColormap *colormap;    bar->gc = gdk_gc_new(widget->window);    color.red += (((double)rand()*0xFFFF)/RAND_MAX);    color.green += (((double)rand()*0xFFFF)/RAND_MAX);    color.blue += (((double)rand()*0xFFFF)/RAND_MAX);    colormap = gtk_widget_get_colormap(widget);    gdk_color_alloc(colormap,&color);    gdk_gc_set_foreground(bar->gc,&color);}static void ag_bargraph_size_request(GtkWidget *widget,        GtkRequisition *requisition){    g_return_if_fail(widget != NULL);    g_return_if_fail(AG_IS_BARGRAPH(widget));    requisition->width = 200;    requisition->height = 100;}static void ag_bargraph_size_allocate(GtkWidget *widget,        GtkAllocation *allocation){    g_return_if_fail(widget != NULL);    g_return_if_fail(AG_IS_BARGRAPH(widget));    g_return_if_fail(allocation != NULL);    widget->allocation.x = allocation->x;    widget->allocation.y = allocation->y;    widget->allocation.width = allocation->width;    widget->allocation.height = allocation->height;    if(GTK_WIDGET_REALIZED(widget)) {        gdk_window_move_resize(widget->window,                allocation->x,allocation->y,                allocation->width,allocation->height);        ag_bargraph_send_configure(AG_BARGRAPH(widget));    }}static void ag_bargraph_send_configure(        AgBargraph *bargraph){    GtkWidget *widget;    GdkEventConfigure event;    widget = GTK_WIDGET(bargraph);    event.type = GDK_CONFIGURE;    event.window = widget->window;    event.x = widget->allocation.x;    event.y = widget->allocation.y;    event.width = widget->allocation.width;    event.height = widget->allocation.height;    gtk_widget_event(widget,(GdkEvent *)&event);}void ag_bargraph_add(AgBargraph *bargraph,gchar *name,        gint value){    AgBargraphBar *newbars;    gint newcount;    g_return_if_fail(bargraph != NULL);    g_return_if_fail(AG_IS_BARGRAPH(bargraph));    newcount = bargraph->bar_count + 1;    newbars = g_malloc(sizeof(AgBargraphBar) * newcount);    memcpy(newbars,bargraph->bars,        sizeof(AgBargraphBar) * bargraph->bar_count);    newbars[bargraph->bar_count].name = g_strdup(name);    newbars[bargraph->bar_count].value = value;    newbars[bargraph->bar_count].gc = NULL;    g_free(bargraph->bars);    bargraph->bars = newbars;    bargraph->bar_count = newcount;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -