📄 hxbandwidthgraph.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: hxbandwidthgraph.cpp,v 1.3.4.3 2004/07/09 01:48:55 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include "hxbandwidthgraph.h"#include <string.h>#include <stdio.h>/* 10 squares + 1 for head room */#define VERTICAL_GRID_COUNT 11 /* Number of squares to display vertically */#define HEAD_ROOM 1 /* Number of squares over 100% to display */#define SECONDS_PER_TICK 0.5 /* Seconds per horizontal tick */static void hx_bandwidth_graph_class_init (HXBandwidthGraphClass* klass);static void hx_bandwidth_graph_init (HXBandwidthGraph* graph, HXBandwidthGraphClass* klass);static void hx_bandwidth_graph_realize (GtkWidget* widget);static void hx_bandwidth_graph_unrealize (GtkWidget* widget);static gboolean hx_bandwidth_graph_expose (GtkWidget* widget, GdkEventExpose* event);static void hx_bandwidth_graph_size_allocate(GtkWidget* widget, GtkAllocation* allocation);static void hx_bandwidth_graph_size_request (GtkWidget* widget, GtkRequisition* requisition);typedef struct _HXBandwidthData{ gdouble percent; gdouble time;} HXBandwidthData;static GtkWidgetClass *parent_class = NULL;GTypehx_bandwidth_graph_get_type (void){ static GType hx_bandwidth_graph_type = 0; if (!hx_bandwidth_graph_type) { static const GTypeInfo hx_bandwidth_graph_info = { sizeof (HXBandwidthGraphClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) hx_bandwidth_graph_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (HXBandwidthGraph), 0, /* n_preallocs */ (GInstanceInitFunc) hx_bandwidth_graph_init, NULL, /* value_table */ }; hx_bandwidth_graph_type = g_type_register_static (GTK_TYPE_WIDGET, "HXBandwidthGraph", &hx_bandwidth_graph_info, (GTypeFlags)0); } return hx_bandwidth_graph_type;}GtkWidget*hx_bandwidth_graph_new(void){ HXBandwidthGraph* graph = (HXBandwidthGraph*)g_object_new(HX_TYPE_BANDWIDTH_GRAPH, NULL); graph->y_tick_count = VERTICAL_GRID_COUNT; graph->head_room = HEAD_ROOM; graph->seconds_per_tick = SECONDS_PER_TICK; graph->ideal_bandwidth = 0; return GTK_WIDGET(graph);}static voidhx_bandwidth_graph_init(HXBandwidthGraph* graph, HXBandwidthGraphClass* /* klass */){ graph->y_tick_count = 0; graph->head_room = 0; graph->seconds_per_tick = 0.0; graph->points = NULL; graph->gc = NULL; graph->pixmap = NULL;}static voidhx_bandwidth_graph_class_init (HXBandwidthGraphClass* klass){ GtkWidgetClass *widget_class; widget_class = GTK_WIDGET_CLASS (klass); parent_class = (GtkWidgetClass*) g_type_class_peek_parent (klass); widget_class->expose_event = hx_bandwidth_graph_expose; widget_class->realize = hx_bandwidth_graph_realize; widget_class->unrealize = hx_bandwidth_graph_unrealize; widget_class->size_allocate = hx_bandwidth_graph_size_allocate; widget_class->size_request = hx_bandwidth_graph_size_request;}voidhx_bandwidth_graph_draw(HXBandwidthGraph* graph){ GtkWidget* widget; gint width; gint height; gdouble y_pixels_per_tick; gdouble x_pixels_per_tick; g_return_if_fail(graph != NULL); widget = GTK_WIDGET(graph); if(!widget->window || !graph->gc) { return; } if(!graph->pixmap) { graph->pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); } gdk_drawable_get_size(GDK_DRAWABLE(graph->pixmap), &width, &height); gdk_gc_set_foreground (graph->gc, &graph->background_color); gdk_draw_rectangle(graph->pixmap, graph->gc, TRUE, 0, 0, width, height); y_pixels_per_tick = (gdouble)height / (gdouble)graph->y_tick_count; /* Draw the horizontal lines */ gdouble y; guint rounded_y; gdk_gc_set_foreground (graph->gc, &graph->grid_color); for(y = y_pixels_per_tick; y < height; y += y_pixels_per_tick) { rounded_y = (guint)(y + 0.5); gdk_draw_line (graph->pixmap, graph->gc, 0, rounded_y, width, rounded_y); } /* No x lines */ x_pixels_per_tick = y_pixels_per_tick; if(graph->ideal_bandwidth > 0) { /* Draw the bandwidth series */ GList* iter; GList* first = NULL; GList* last = NULL; HXBandwidthData* point; HXBandwidthData* a; HXBandwidthData* b; /* Step 0: See if we have space for the whole series */ first = g_list_first(graph->points); /* Step 1: Skip all points newer than our cut-off */ iter = g_list_last(graph->points); while(iter) { point = (HXBandwidthData*) iter->data; if(point->time <= graph->cutoff_time) { last = iter; break; } iter = g_list_previous(iter); } if(first && last) { gdouble delta; gdouble graph_time; gboolean draw_left_to_right; gint x1 = -1; gint x2 = -1; gint y1 = -1; gint y2 = -1; gdk_gc_set_foreground (graph->gc, &graph->line_color); a = (HXBandwidthData*)first->data; b = (HXBandwidthData*)last->data; delta = b->time - a->time; graph_time = (graph->seconds_per_tick * (width / x_pixels_per_tick)); if(delta < graph_time) { /* We can draw the whole shebang -- draw left to right */ draw_left_to_right = TRUE; } else { /* More data than graph -- draw right to left */ draw_left_to_right = FALSE; } /* Step 2: Draw until we get to the end of the graph */ gdouble base_time; gdouble graph_percent = 0.0; gboolean done = FALSE; graph_percent = (gdouble)(graph->y_tick_count + graph->head_room) / graph->y_tick_count; if(draw_left_to_right) { point = (HXBandwidthData*) first->data; base_time = point->time; iter = first; } else { point = (HXBandwidthData*) last->data; base_time = point->time; iter = last; } while(iter && !done) { gdouble bandwidth_percent_ideal; gdouble bandwidth_percent_graph; gdouble time_percent_graph; point = (HXBandwidthData*) iter->data; bandwidth_percent_ideal = point->percent; bandwidth_percent_graph = bandwidth_percent_ideal / graph_percent; if(bandwidth_percent_graph > 1.0) { bandwidth_percent_graph = 1.0; } time_percent_graph = (point->time - base_time) / graph_time; if(time_percent_graph > 1.0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -