📄 agbargraph.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 + -