📄 vis.c
字号:
gtk_widget_show (in); gtk_widget_show (dump_to_file); gtk_widget_show (geo); gtk_widget_show (refresh); gtk_widget_show (quit); gtk_widget_show (sep); gtk_widget_show (hsep1); gtk_widget_show (hsep2); gtk_widget_show (hsep3); gtk_widget_show (hbox); gtk_widget_show (vbox); gtk_widget_show (window); init_color_list (color_file); if (!gdk_color_parse (highlight, &highlight_color) || !gdk_colormap_alloc_color (cmap, &highlight_color, FALSE, TRUE)) fatal << "Couldn't allocate highlight color " << highlight << "\n"; if (!gdk_color_parse ("green", &search_color) || !gdk_colormap_alloc_color (cmap, &search_color, FALSE, TRUE)) fatal << "Couldn't allocate search color maroon\n";}voiddump_cb (GtkWidget *widget, gpointer data){ GdkPixbuf *pbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0,0, 0,0, -1, -1); gdk_pixbuf_save (pbuf, "vis.jpeg", "jpeg", NULL, "quality", "100", (void *) NULL);}voidgeo_cb (GtkWidget *widget, gpointer data){ ggeo = !ggeo; redraw ();}voidzoom_in_cb (GtkWidget *widget, gpointer data){ recenter (); redraw ();}voidredraw_cb (GtkWidget *widget, gpointer data){ draw_ring ();}void quit_cb (GtkWidget *widget, gpointer data){ f_node *c = nodes.first (); f_node *n; while (c) { n = nodes.next (c); delete c; c = n; } gtk_exit (0);}unsigned intcheck_get_state (void){ unsigned int state = 0; for (size_t i = 0; i < NELEM (handlers); i++) if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (handlers[i].widget))) state |= handlers[i].flag; return state;}voidcheck_set_state (unsigned int newstate){ // ONLY set the state of the buttons, do NOT actually toggle anything. for (size_t i = 0; i < NELEM (handlers); i++) { gtk_signal_handler_block_by_func (GTK_OBJECT (handlers[i].widget), GTK_SIGNAL_FUNC (handlers[i].handler), NULL); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (handlers[i].widget), (newstate & handlers[i].flag)); gtk_signal_handler_unblock_by_func (GTK_OBJECT (handlers[i].widget), GTK_SIGNAL_FUNC (handlers[i].handler), NULL); }}voiddraw_toggle_cb (GtkWidget *widget, gpointer data){ // Set the state of all the selected nodes to match what the button says. bool active = false; unsigned int flag = 0; // xxx Shouldn't we be comparing "widget" to "check_immed_succ"? // Empircally, no, this is what works. Weird. for (size_t i = 0; i < NELEM (handlers); i++) if (data == handlers[i].widget) { active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (handlers[i].widget)); flag = handlers[i].flag; break; } f_node *n = nodes.first (); while (n) { if (n->selected) { if (active) n->draw |= flag; else n->draw &= ~flag; } n = nodes.next (n); } draw_ring ();}void select_all_cb (GtkWidget *widget, gpointer data) { f_node *n = nodes.first (); while (n) { n->selected = true; n = nodes.next (n); } draw_ring ();}void select_none_cb (GtkWidget *widget, gpointer data) { f_node *n = nodes.first (); while (n) { n->selected = false; n = nodes.next (n); } draw_ring ();}voidupdate_cb (GtkWidget *widget, gpointer data){ update ();}voiddraw_nothing_cb (GtkWidget *widget, gpointer data){ f_node *n = nodes.first (); while (n) { n->selected = false; n->highlight = false; n->draw = 0; n = nodes.next (n); } check_set_state (0); // search_key = 0; last_clicked[0] = 0; annotations.clear (); draw_ring ();}gintkey_release_event (GtkWidget *widget, GdkEventKey *event, gpointer data){ // warnx << "key pressed " << event->keyval << "\n"; switch (event->keyval) { case '1': xindex = 0; yindex = 1; break; case '2': xindex = 1; yindex = 2; break; case '3': xindex = 0; yindex = 2; break; case 'g': update_highlighted (); break; case 'n': { break; } case 'q': case 'Q': quit_cb (NULL, NULL); break; case 'z': zoomx = zoomx * 1.2; zoomy = zoomy * 1.2; break; case 'Z': zoomx = zoomx / 1.2; zoomy = zoomy / 1.2; break; default: break; } return (TRUE);}gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data ){ gtk_exit (0); return (FALSE);}/* Create a new backing pixmap of the appropriate size */static gintconfigure_event (GtkWidget *widget, GdkEventConfigure *event){ if (pixmap) gdk_pixmap_unref(pixmap); pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle (pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); return TRUE;}/* Redraw the screen from the backing pixmap */static gintexpose_event (GtkWidget *widget, GdkEventExpose *event){ gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE;}static gint button_down_event (GtkWidget *widget, GdkEventButton *event, gpointer data) { chordID ID = xy_to_ID ((int)event->x,(int)event->y); f_node *n = nodes[ID]; assert (n); bool update_name = true; switch (event->button) { case 2: n->highlight = !n->highlight; break; case 3: if (ggeo) xy_to_coord ((int)event->x, (int)event->y, ¢erx, ¢ery); update_name = false; break; default: n->selected = !n->selected; if (n->selected) check_set_state (n->draw); break; } if (update_name) { char hosts[512]; strcpy (hosts, n->hostname); strcat (hosts, ":"); strcat (hosts, ID.cstr ()); strncpy (last_clicked, hosts, sizeof (last_clicked)); } draw_ring (); return TRUE;}chordIDxy_to_ID (int sx, int sy){ f_node *n = nodes.first (); int min = RAND_MAX; chordID closest = n->ID; while (n) { int x,y; ID_to_xy (n->ID, &x, &y); int dist = (sx - x)*(sx - x) + (sy - y)*(sy - y); if (dist < min) { closest = n->ID; min = dist; } n = nodes.next (n); } return closest;}voidinit_color_list (char *filename){ GdkColor c; color_pair p; draw_gc = NULL; draw_gc = gdk_gc_new (drawing_area->window); assert (draw_gc); gdk_gc_set_line_attributes (draw_gc, 3, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER); cmap = gdk_colormap_get_system (); FILE *cf = fopen (filename, "r"); if (!cf) { warn << "couldn't open " << filename << " using default color map\n"; if (!gdk_color_parse ("red", &c) || !gdk_colormap_alloc_color (cmap, &c, FALSE, TRUE)) fatal << "couldn't get the color I wanted\n"; p.c = c; p.lat = RAND_MAX; lat_map.push_back (p); return; } char color[1024]; unsigned long lat; while (fscanf (cf, "%ld %s\n", &lat, color) == 2) { if (!gdk_color_parse (color, &c) || !gdk_colormap_alloc_color (cmap, &c, FALSE, TRUE)) fatal << "couldn't get the color I wanted\n"; p.c = c; p.lat = lat * 1000; //convert from ms to microsec lat_map.push_back (p); } assert (lat_map.size () != 0);}voiddraw_arc (chordID from, chordID to, GdkGC *draw_gc){ double from_angle = ID_to_angle (from); double to_angle = ID_to_angle (to); double median = (from_angle + to_angle) / 2; if (to_angle < from_angle) median -= PI; double theta; if (to_angle > from_angle) theta = to_angle - from_angle; else theta = 2*PI - (from_angle - to_angle); double rad = ((WINX)/2 - 10)*cos(theta/2)*0.8; int fromx, tox; int fromy, toy; ID_to_xy (from, &fromx, &fromy); ID_to_xy (to, &tox, &toy); if (theta < 0.1) { draw_arrow( (gint)fromx, (gint)fromy, (gint)tox, (gint)toy, draw_gc); return; } double c1x, c2x; double c1y, c2y; c1x = 5 + (int)((WINX - 5)/2 + sin (median + 0.1)*rad); c1y = 5 + (int)((WINY - 5)/2 - cos (median + 0.1)*rad); c2x = 5 + (int)((WINX - 5)/2 + sin (median - 0.1)*rad); c2y = 5 + (int)((WINY - 5)/2 - cos (median - 0.1)*rad);#ifdef DEBUG_BEZ gdk_draw_arc (pixmap, widget->style->black_gc, TRUE, (gint)c1x,(gint)c1y, 4,4, (gint16)0, (gint16)64*360); gdk_draw_arc (pixmap, widget->style->black_gc, TRUE, (gint)c2x,(gint)c2y, 4,4, (gint16)0, (gint16)64*360);#endif int oldx = fromx; int oldy = fromy; for (float t=0.0; t < 0.99; t += 0.15) { float a = t; float b = 1 - t; float px = fromx*(b*b*b) + 3*c1x*b*b*a + 3*c2x*b*a*a + tox*a*a*a; float py = fromy*(b*b*b) + 3*c1y*b*b*a + 3*c2y*b*a*a + toy*a*a*a; gdk_draw_line (pixmap,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -