Merge lp://staging/~dnax88/upnp-router-control/network-graph into lp://staging/~dnax88/upnp-router-control/devel

Proposed by Daniele Napolitano
Status: Merged
Approved by: Daniele Napolitano
Approved revision: 52
Merged at revision: 49
Proposed branch: lp://staging/~dnax88/upnp-router-control/network-graph
Merge into: lp://staging/~dnax88/upnp-router-control/devel
Diff against target: 423 lines (+341/-6)
3 files modified
.bzrignore (+16/-0)
data/upnp-router-control.glade (+10/-0)
src/urc-gui.c (+315/-6)
To merge this branch: bzr merge lp://staging/~dnax88/upnp-router-control/network-graph
Reviewer Review Type Date Requested Status
Daniele Napolitano Approve
Review via email: mp+20385@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Daniele Napolitano (dnax88) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2010-03-01 17:53:14 +0000
4@@ -0,0 +1,16 @@
5+_build_
6+aclocal.m4
7+missing
8+Makefile.in
9+.lock-wscript
10+.waf-1.5.8-82618d9ddb24b59a4b121a86ef888bbb
11+configure
12+INSTALL
13+depcomp
14+config.h.in
15+data/Makefile.in
16+data/apps_scalable2_upnp-router-control.svg
17+src/Makefile.in
18+autom4te.cache
19+install-sh
20+NEWS
21
22=== modified file 'data/upnp-router-control.glade'
23--- data/upnp-router-control.glade 2010-02-09 16:17:44 +0000
24+++ data/upnp-router-control.glade 2010-03-01 17:53:14 +0000
25@@ -346,6 +346,16 @@
26 <property name="position">2</property>
27 </packing>
28 </child>
29+ <child>
30+ <object class="GtkDrawingArea" id="network_graph">
31+ <property name="height_request">100</property>
32+ <property name="visible">True</property>
33+ <property name="app_paintable">True</property>
34+ </object>
35+ <packing>
36+ <property name="position">3</property>
37+ </packing>
38+ </child>
39 </object>
40 </child>
41 </object>
42
43=== modified file 'src/urc-gui.c'
44--- src/urc-gui.c 2010-02-09 16:55:32 +0000
45+++ src/urc-gui.c 2010-03-01 17:53:14 +0000
46@@ -69,7 +69,8 @@
47 *down_rate_label,
48 *up_rate_label,
49 *button_remove,
50- *button_add;
51+ *button_add,
52+ *network_drawing_area;
53
54 AddPortWindow* add_port_window;
55
56@@ -77,6 +78,18 @@
57
58 static GuiContext* gui;
59
60+static GList *downspeed_values = NULL;
61+static GList *upspeed_values = NULL;
62+
63+#define GRAPH_POINTS 90
64+
65+
66+typedef struct
67+{
68+ gdouble speed;
69+ gboolean valid;
70+} SpeedValue;
71+
72 static void gui_add_port_window_close(GtkWidget *button,
73 gpointer user_data)
74 {
75@@ -440,10 +453,24 @@
76 gchar* str;
77 gchar* unit;
78 gfloat value;
79- /* Method of divisions is too expensive? */
80-
81-
82-
83+ GList *tmp_elem;
84+ SpeedValue *speed;
85+
86+ speed = g_malloc (sizeof(SpeedValue));
87+
88+ speed->speed = down_speed;
89+ speed->valid = TRUE;
90+
91+ downspeed_values = g_list_prepend(downspeed_values, speed);
92+
93+ tmp_elem = g_list_nth(downspeed_values, GRAPH_POINTS+1);
94+ if(tmp_elem) {
95+ g_free(tmp_elem->data);
96+ downspeed_values = g_list_delete_link(downspeed_values, tmp_elem);
97+ }
98+
99+
100+ /* Method of divisions is too expensive? */
101 /* Down speed */
102 if(down_speed >= 1024)
103 {
104@@ -488,8 +515,25 @@
105 gchar* str;
106 gchar* unit;
107 gfloat value;
108+ GList *tmp_elem;
109+ SpeedValue *speed;
110+
111+ speed = g_malloc (sizeof(SpeedValue));
112+
113+ speed->speed = up_speed;
114+ speed->valid = TRUE;
115+
116+ upspeed_values = g_list_prepend(upspeed_values, speed);
117+
118+ tmp_elem = g_list_nth(upspeed_values, GRAPH_POINTS+1);
119+ if(tmp_elem) {
120+ g_free(tmp_elem->data);
121+ upspeed_values = g_list_delete_link(upspeed_values, tmp_elem);
122+ }
123+
124+ gtk_widget_queue_draw(gui->network_drawing_area);
125+
126 /* Method of divisions is too expensive? */
127-
128 /* Up speed */
129 if(up_speed >= 1024)
130 {
131@@ -792,10 +836,255 @@
132 gtk_main_quit();
133 }
134
135+#define FRAME_WIDTH 4
136+
137+cairo_surface_t *background;
138+
139+void clear_graph_background()
140+{
141+ if (background) {
142+ cairo_surface_destroy(background);
143+ background = NULL;
144+ }
145+}
146+
147+void
148+speed_graph_draw (GtkWidget *widget)
149+{
150+ /* repaint */
151+ gtk_widget_queue_draw (widget);
152+}
153+
154+void
155+speed_graph_draw_background (GtkWidget *widget)
156+{
157+ cairo_t *cr;
158+ cairo_pattern_t *pat;
159+ cairo_text_extents_t extents;
160+ gchar *label;
161+ double draw_width, draw_height;
162+
163+ const double fontsize = 8.0;
164+ const double rmargin = 3.5 * fontsize;
165+ const guint indent = 24;
166+ const guint x_frame_count = 6;
167+ guint y_frame_count = 3;
168+ double dash[2] = { 1.0, 2.0 };
169+ double x_frame_size, y_frame_size;
170+ double x, y;
171+ gint i;
172+ guint net_max = 100;
173+
174+ background = cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
175+ widget->allocation.width,
176+ widget->allocation.height);
177+ cr = cairo_create(background);
178+
179+ draw_width = widget->allocation.width - 2 * FRAME_WIDTH;
180+ draw_height = widget->allocation.height - 2 * FRAME_WIDTH;
181+
182+ cairo_translate (cr, FRAME_WIDTH, FRAME_WIDTH);
183+
184+ // determines the number of grids based on height
185+ switch ( (int) (draw_height) / 30 )
186+ {
187+ case 0:
188+ case 1:
189+ y_frame_count = 1;
190+ break;
191+ case 2:
192+ case 3:
193+ y_frame_count = 2;
194+ break;
195+ case 4:
196+ y_frame_count = 4;
197+ break;
198+ default:
199+ y_frame_count = 5;
200+
201+ }
202+
203+ cairo_select_font_face (cr, "sans",
204+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
205+ cairo_set_font_size (cr, fontsize);
206+
207+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
208+ cairo_set_line_width (cr, 1);
209+
210+ // white to gray faded background
211+ pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, draw_height - 15.0);
212+ cairo_pattern_add_color_stop_rgb (pat, 0, 1, 1, 1);
213+ cairo_pattern_add_color_stop_rgb (pat, 1, 0.9, 0.9, 0.9);
214+ cairo_rectangle (cr, rmargin + indent, 0, draw_width - rmargin - indent, draw_height - 15.0);
215+ cairo_set_source (cr, pat);
216+ cairo_fill(cr);
217+ cairo_pattern_destroy (pat);
218+
219+ // draw grid
220+ cairo_set_dash (cr, dash, 2, 0);
221+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.75);
222+
223+ // drawing vertical grid
224+ x_frame_size = (draw_width - rmargin - indent) / x_frame_count;
225+ for(i = 0; i <= x_frame_count; i++) {
226+
227+ x = rmargin + indent + (x_frame_size * i);
228+
229+ if(i == 0)
230+ label = g_strdup_printf("%u seconds", GRAPH_POINTS - (GRAPH_POINTS / x_frame_count) * i);
231+
232+ else
233+ label = g_strdup_printf("%u", GRAPH_POINTS - (GRAPH_POINTS / x_frame_count) * i);
234+
235+ cairo_text_extents (cr, label, &extents);
236+ cairo_move_to (cr, x - extents.width/2 , draw_height+2);
237+ cairo_show_text (cr, label);
238+ g_free(label);
239+
240+ cairo_move_to (cr, x, 0);
241+ cairo_line_to (cr, x, draw_height - 10.0);
242+
243+ }
244+
245+ // drawing horizontal grid
246+ y_frame_size = (draw_height - 15.0) / y_frame_count;
247+ for(i = 0; i <= y_frame_count; i++) {
248+ y = y_frame_size * i;
249+
250+ label = g_strdup_printf("%u KiB/s", net_max - net_max / y_frame_count * i);
251+ cairo_text_extents (cr, label, &extents);
252+ cairo_move_to (cr, rmargin + indent - extents.width - 10 , y + extents.height/2);
253+ cairo_show_text (cr, label);
254+ g_free(label);
255+
256+ cairo_move_to (cr, rmargin + indent - 5, y);
257+ cairo_line_to (cr, draw_width - rmargin + indent + 5, y);
258+
259+ }
260+
261+ cairo_stroke(cr);
262+}
263+
264+static gboolean
265+on_drawing_area_configure_event (GtkWidget *widget,
266+ GdkEventConfigure *event,
267+ gpointer data_ptr)
268+{
269+ clear_graph_background();
270+
271+ speed_graph_draw (widget);
272+
273+ return TRUE;
274+}
275+
276+
277+static gboolean
278+on_drawing_area_expose_event (GtkWidget *widget,
279+ GdkEventExpose *event,
280+ gpointer user_data)
281+{
282+ cairo_t *cr;
283+
284+ double draw_width, draw_height;
285+ const double fontsize = 8.0;
286+ const double rmargin = 3.5 * fontsize;
287+ const guint indent = 24;
288+ double x, y;
289+ gint i;
290+ GList *list;
291+ guint net_max = 100;
292+ SpeedValue *speed_value;
293+
294+ if(background == NULL)
295+ speed_graph_draw_background (widget);
296+
297+ draw_width = widget->allocation.width - 2 * FRAME_WIDTH;
298+ draw_height = widget->allocation.height - 2 * FRAME_WIDTH;
299+
300+ cr = gdk_cairo_create (widget->window);
301+
302+ cairo_rectangle (cr,
303+ event->area.x, event->area.y,
304+ event->area.width, event->area.height);
305+ cairo_clip (cr);
306+
307+ // draw background
308+ cairo_set_source_surface(cr, background, 0.0, 0.0);
309+ cairo_paint(cr);
310+
311+ cairo_translate (cr, FRAME_WIDTH, FRAME_WIDTH);
312+
313+ /* draw load lines */
314+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
315+ cairo_set_dash (cr, NULL, 0, 0);
316+ cairo_set_line_width (cr, 1.00);
317+
318+ /* upload speed */
319+ list = upspeed_values;
320+ speed_value = list->data;
321+
322+ if(speed_value->valid == TRUE) {
323+ y = draw_height - 15 - speed_value->speed * (draw_height - 15) / net_max;
324+ x = draw_width;
325+ cairo_move_to (cr, x, y + 0.5);
326+ }
327+
328+ for(i = GRAPH_POINTS; i >= 0; i--) {
329+
330+ speed_value = list->data;
331+
332+ if(speed_value->valid == TRUE) {
333+ y = draw_height - 15 - speed_value->speed * (draw_height - 15) / net_max;
334+ x = rmargin + indent + ((draw_width - rmargin - indent) / GRAPH_POINTS) * i;
335+
336+ cairo_line_to (cr, x, y + 0.5);
337+ }
338+
339+ list = list->next;
340+ }
341+
342+ cairo_set_source_rgb (cr, 0.52, 0.28, 0.60);
343+ cairo_stroke(cr);
344+
345+ /* download speed */
346+ list = downspeed_values;
347+ speed_value = list->data;
348+
349+ if(speed_value->valid == TRUE) {
350+ y = draw_height - 15 - speed_value->speed * (draw_height - 15) / 100;
351+ x = draw_width;
352+ cairo_move_to (cr, x, y + 0.5);
353+ }
354+
355+ for(i = GRAPH_POINTS; i >= 0; i--) {
356+
357+ speed_value = list->data;
358+
359+ if(speed_value->valid == TRUE) {
360+ y = draw_height - 15 - speed_value->speed * (draw_height - 15) / 100;
361+ x = rmargin + indent + ((draw_width - rmargin - indent) / GRAPH_POINTS) * i;
362+
363+ cairo_line_to (cr, x, y + 0.5);
364+ }
365+
366+ list = list->next;
367+ }
368+
369+ cairo_set_source_rgb (cr, 0.18, 0.49, 0.70);
370+ cairo_stroke(cr);
371+
372+ cairo_destroy (cr);
373+
374+ return FALSE;
375+}
376+
377+
378 void gui_init()
379 {
380 GtkBuilder* builder;
381 GError* error = NULL;
382+ SpeedValue *speed;
383+ gint i;
384
385 g_print("* Initializing GUI...\n");
386
387@@ -821,10 +1110,25 @@
388 gui->down_rate_label = GTK_WIDGET (gtk_builder_get_object (builder, "down_rate_label"));
389 gui->up_rate_label = GTK_WIDGET (gtk_builder_get_object (builder, "up_rate_label"));
390 gui->router_url_eventbox = GTK_WIDGET (gtk_builder_get_object (builder, "router_url_eventbox"));
391+ gui->network_drawing_area = GTK_WIDGET (gtk_builder_get_object (builder, "network_graph"));
392
393 gui->button_add = GTK_WIDGET (gtk_builder_get_object (builder, "button_add"));
394 gui->button_remove = GTK_WIDGET (gtk_builder_get_object (builder, "button_remove"));
395
396+ // fill speed graph lists
397+ for(i = 0; i <= GRAPH_POINTS; i++) {
398+ speed = g_malloc(sizeof(SpeedValue));
399+ speed->speed = 0;
400+ speed->valid = FALSE;
401+ upspeed_values = g_list_prepend(upspeed_values, speed);
402+ }
403+
404+ for(i = 0; i <= GRAPH_POINTS; i++) {
405+ speed = g_malloc(sizeof(SpeedValue));
406+ speed->speed = 0;
407+ speed->valid = FALSE;
408+ downspeed_values = g_list_prepend(downspeed_values, speed);
409+ }
410
411 g_signal_connect(gtk_builder_get_object (builder, "menuitem_about"), "activate",
412 G_CALLBACK(on_about_activate_cb), NULL);
413@@ -834,6 +1138,11 @@
414
415 g_signal_connect(G_OBJECT(gui->main_window), "delete-event",
416 G_CALLBACK(gui_destroy), NULL);
417+
418+ g_signal_connect(G_OBJECT(gui->network_drawing_area), "expose-event",
419+ G_CALLBACK(on_drawing_area_expose_event), NULL);
420+ g_signal_connect(G_OBJECT(gui->network_drawing_area), "configure-event",
421+ G_CALLBACK(on_drawing_area_configure_event), NULL);
422
423 gui_create_add_port_window(builder);
424

Subscribers

People subscribed via source and target branches