10 #include <gtk/gtksignal.h>
11 #include <gtk/gtkmain.h>
19 static gboolean pie_menu_expose (GtkWidget *pie, GdkEventExpose *event);
20 static void pie_menu_dispose (GObject *
self);
38 unsigned int bg_red, bg_green, bg_blue;
41 #define PIE_MENU_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PIE_MENU_TYPE, PieMenuPrivate))
45 GObjectClass *obj_class;
46 GtkWidgetClass *widget_class;
48 obj_class = G_OBJECT_CLASS (cls);
49 widget_class = GTK_WIDGET_CLASS (cls);
51 widget_class->expose_event = pie_menu_expose;
52 obj_class->dispose = pie_menu_dispose;
71 static void pie_draw (GtkWidget *pie, cairo_t *cr)
78 double width = pie->allocation.width;
79 double height = pie->allocation.height;
80 double center_x = width/2;
81 double center_y = height/2;
82 double radius_normal = MIN (width / 2,height / 2) * .9;
92 double color_red = .5;
93 double color_green = .5;
94 double color_blue = 1;
96 double color_turn = 3;
115 color_step = .2 - (.01*(((vars->
nSegments-1))%10));
120 double inner_radius_normal = radius_normal/1.7;
121 double inner_radius = inner_radius_normal;
122 double radius = radius_normal;
123 double radius_selected = radius_normal*1.1;
124 double inner_radius_selected = radius_normal/2.5;
132 double bar_width = inner_radius/(15+nSegments);
133 double poly_radius = inner_radius/10;
136 cairo_set_source_rgb(cr,
137 (
double)vars->
bg_red/65535,
141 cairo_move_to(cr,0,0);
142 cairo_line_to(cr,width,0);
143 cairo_line_to(cr,width,height);
144 cairo_line_to(cr,0,height);
145 cairo_line_to(cr,0,0);
146 cairo_fill_preserve (cr);
149 for(i=1;i<=nSegments;i++)
151 double next_theta = 2*M_PI * (double)i/nSegments;
152 double mid_theta = (next_theta + theta)/2.0;
156 cairo_set_source_rgba(cr,color_red * 2, color_green*2, color_blue*1,1);
161 cairo_set_source_rgba(cr,color_red, color_green, color_blue, 1);
163 cairo_set_line_width(cr,1);
167 radius = radius_selected;
168 inner_radius = inner_radius_selected;
170 cairo_move_to(cr,center_x+inner_radius*cos(theta),center_y+inner_radius*sin(theta));
171 cairo_line_to(cr,center_x + radius * cos(theta),center_y + radius*sin(theta));
172 cairo_line_to(cr,center_x + radius * cos(next_theta),center_y + radius*sin(next_theta));
173 cairo_line_to(cr,center_x+inner_radius*cos(next_theta),center_y+inner_radius*sin(next_theta));
176 cairo_fill_preserve (cr);
180 cairo_arc (cr, center_x, center_y, radius, theta, next_theta);
181 cairo_fill_preserve (cr);
190 cairo_set_source_rgb(cr,
191 (
double)vars->
bg_red/65535,
196 cairo_move_to(cr,center_x,center_y);
197 cairo_line_to(cr,center_x + inner_radius * cos(theta), center_y + inner_radius*sin(theta));
198 cairo_line_to(cr,center_x + inner_radius * cos(next_theta),center_y + inner_radius*sin(next_theta));
199 cairo_line_to(cr,center_x,center_y);
200 cairo_fill_preserve (cr);
204 cairo_arc (cr, center_x, center_y, inner_radius, theta, next_theta);
205 cairo_fill_preserve (cr);
217 bar_height= inner_radius;
226 double costheta = cos(mid_theta);
227 double sintheta = sin(mid_theta);
229 double origin1x = center_x - bar_width * sintheta;
230 double origin1y = center_y + bar_width * costheta;
231 double origin2x = center_x + bar_width * sintheta;
232 double origin2y = center_y - bar_width * costheta;
234 cairo_set_source_rgba(cr,color_red, color_green, color_blue, 1);
236 cairo_set_line_width(cr,1);
241 , origin1x + bar_height * costheta
242 , origin1y + bar_height * sintheta);
244 , origin2x + bar_height * costheta
245 , origin2y + bar_height * sintheta);
253 cairo_fill_preserve (cr);
260 radius = radius_normal;
261 inner_radius = inner_radius_normal;
268 color_red = color_red - color_step;
269 color_green = color_green + color_step;
270 if(color_green >= .99)
276 else if(color_turn == 2)
279 color_green = color_green - color_step;
280 color_blue = color_blue + color_step;
281 if(color_blue >= .99)
289 color_blue = color_blue - color_step;
290 color_red = color_red + color_step;
308 cairo_set_source_rgba(cr,0,0,0,1);
309 for(i=0;i<nSegments;i++)
311 x = center_x + cos(theta) * poly_radius;
312 y = center_y + sin(theta) * poly_radius;
315 cairo_move_to(cr,x,y);
320 cairo_line_to(cr,x,y);
322 theta += 2.0 * M_PI / nSegments;
325 x = center_x + cos(theta) * poly_radius;
326 y = center_y + sin(theta) * poly_radius;
327 cairo_line_to(cr,x,y);
328 cairo_fill_preserve (cr);
334 for(i=0;i<nSegments;i++)
337 theta = 2*M_PI * (double)i/nSegments;
338 double next_theta = 2*M_PI * (double)(i+1)/(nSegments);
339 double mid_theta = (next_theta + theta)/2.0;
342 double text_x = center_x + (radius*.7) * cos(mid_theta);
343 double text_y = center_y + (radius*.7) * sin(mid_theta);
347 cairo_text_extents_t ext;
348 double text_start_x, text_start_y;
349 if(vars->
labels.size() <= unsigned(i))
351 sprintf(buffer,
"Class %d",i);
355 strncpy(buffer, vars->
labels[i].c_str(), 254);
360 strncpy(buffer, l.c_str(), 254);
363 int font_size = int(18 / (vars->
nSegments) + width/300);
364 int length_factor = 10-(strlen(buffer)/5);
365 if(length_factor >= 0)
366 font_size+= length_factor;
367 cairo_set_font_size(cr,font_size);
369 cairo_text_extents(cr, buffer, &ext);
370 text_start_x = text_x-ext.width/2;
371 text_start_y = text_y;
373 double tl_x = text_start_x-padding;
374 double tl_y = text_start_y+padding;
376 double bl_y = tl_y - ext.height - padding*2;
377 double tr_x = tl_x + ext.width + padding*2;
382 cairo_move_to(cr,tl_x, tl_y);
383 cairo_line_to(cr,bl_x, bl_y);
384 cairo_line_to(cr,br_x, br_y);
385 cairo_line_to(cr,tr_x, tr_y);
386 cairo_line_to(cr,tl_x, tl_y);
387 cairo_set_source_rgba(cr,1,1,1,.7);
388 cairo_fill_preserve (cr);
389 cairo_set_source_rgb(cr,0,0,0);
392 cairo_set_source_rgba(cr,0,0,0, 1);
393 cairo_move_to(cr,text_start_x, text_start_y);
394 cairo_show_text(cr,buffer);
420 static gboolean pie_menu_expose (GtkWidget *pie, GdkEventExpose *event)
422 g_return_val_if_fail (pie != NULL,
false);
429 cr = gdk_cairo_create (pie->window);
432 event->area.x, event->area.y,
433 event->area.width, event->area.height);
444 static void pie_menu_redraw_canvas(
PieMenu *pie)
449 g_return_if_fail (pie != NULL);
456 widget = GTK_WIDGET (pie);
458 if (!widget->window)
return;
460 region = gdk_drawable_get_clip_region (widget->window);
461 gdk_window_invalidate_region (widget->window, region, TRUE);
462 gdk_window_process_updates (widget->window, TRUE);
464 gdk_region_destroy (region);
468 static gboolean pie_menu_update(gpointer data)
471 g_return_val_if_fail (data != NULL,
false);
480 pie_menu_redraw_canvas (pie);
484 static void pie_menu_final(gpointer g_class, gpointer class_data)
487 static void pie_menu_dispose (GObject *
self)
489 g_return_if_fail (
self != NULL);
498 static void pie_menu_init (
PieMenu *pie)
524 pie_menu_update(pie);
527 g_timeout_add(200, pie_menu_update, pie);
548 void pie_set_bg(GtkWidget *pie,
unsigned int red,
unsigned int green,
unsigned int blue)
573 pie_menu_update(pie);
623 pie_menu_update(pie);
636 pie_menu_update(pie);
646 cerr <<
"ERROR pie is NULL\n";
661 cerr <<
"ERROR pie is NULL\n";
669 if(
unsigned(vars->
nSegments) > proportions.size())
671 cerr <<
"ERROR vector is of wrong size in pie_set_class_proportions\n";