gui_topo.c

来自「MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis」· C语言 代码 · 共 486 行

C
486
字号
//  This file is part of MANTIS OS, Operating System//  See http://mantis.cs.colorado.edu/////  Copyright (C) 2003-2005 University of Colorado, Boulder////  This program is free software; you can redistribute it and/or//  modify it under the terms of the mos license (see file LICENSE)#include <libgnomecanvas/libgnomecanvas.h>#include <math.h>#include <glib/gprintf.h>#include "gui_gtk.h"#include "gui_topo.h"#include "cortex.h"extern gint num_nodes;gint max_x, max_y;gint item_event_handler(GnomeCanvasItem *item, GdkEvent *event, topo_node_t *node);gui_topo_t *gui_topo_new(GtkWidget *container){   GnomeCanvas *canvas;   gui_topo_t *topo = g_new(gui_topo_t, 1);   GdkPixbuf *bg_pixbuf;   topo->selected = 0;   topo->widget = gnome_canvas_new_aa();   canvas = GNOME_CANVAS(topo->widget);   gnome_canvas_set_pixels_per_unit(canvas, 1);      topo->nodes = g_hash_table_new(g_direct_hash, g_direct_equal);   topo->unconf_nodes = g_hash_table_new (g_direct_hash, g_direct_equal);      bg_pixbuf = gdk_pixbuf_new_from_file (TOPO_BG_FILENAME, NULL);   if (bg_pixbuf == NULL) {      printf ("Could not load image '%s'\n", TOPO_BG_FILENAME);      exit (-1);   }   max_x = gdk_pixbuf_get_width (bg_pixbuf);   max_y = gdk_pixbuf_get_height (bg_pixbuf);      // set the size of the widget   gtk_widget_set_size_request(container, max_x, max_y + TOPO_BG_OFFSET);   gtk_widget_set_size_request(topo->widget, max_x, max_y + TOPO_BG_OFFSET);   // Create the background by drawing a white square   gnome_canvas_item_new(gnome_canvas_root(canvas),			 gnome_canvas_rect_get_type(),			 "x1", 0.0,			 "y1", 0.0,			 "x2", 10.0 * (gdouble)max_x,			 "y2", 10.0 * (gdouble)max_y + TOPO_BG_OFFSET,			 "fill-color", "white",			 NULL);   topo->bg = gnome_canvas_item_new (gnome_canvas_root (canvas),				     gnome_canvas_pixbuf_get_type (),				     "x", 0.0,				     "y", (gdouble)TOPO_BG_OFFSET,				     "height-set", FALSE,				     "width-set", FALSE,				     "pixbuf", bg_pixbuf, NULL);   // set where can the canvas scroll (our usable area)   gnome_canvas_set_scroll_region(canvas, 0.0, 0.0, max_x, max_y + TOPO_BG_OFFSET);   gnome_canvas_set_center_scroll_region(canvas, FALSE);      gtk_widget_show(topo->widget);   GnomeCanvasPoints *points = gnome_canvas_points_new (2);   points->coords[0] = 5.0;   points->coords[1] = (gdouble)TOPO_BG_OFFSET - 5.0;   int widget_w;   gtk_widget_get_size_request (topo->widget, &widget_w, NULL);   points->coords[2] = (gdouble)widget_w - 5.0;   points->coords[3] = (gdouble)TOPO_BG_OFFSET - 5.0;   gnome_canvas_item_new (gnome_canvas_root (canvas),			  gnome_canvas_line_get_type (),			  "width-pixels", TOPO_BG_LINE_WIDTH,			  "fill-color", TOPO_BG_LINE_COLOR,			  "points", points, NULL);   gnome_canvas_points_unref (points);      gnome_canvas_update_now (canvas);      return topo;}void gui_topo_node_new_full (gui_topo_t *topo, gint id, gint light, gint temp,			     gdouble x, gdouble y, gdouble z){}static gint temp_get_color (uint8_t temp){   gint color = 0;   color |= temp;   color = color << 8;   color |= temp;   color = color << 8;   color |= temp;   color = color << 8;   color |= 0xff;   return color;}void gui_topo_node_new_pos (gui_topo_t *topo, gint id, gdouble x, gdouble y, gdouble z){   GnomeCanvas *canvas;   topo_node_t *new_node = g_new(topo_node_t, 1);   gdouble node_radius = (gdouble)TOPO_NODE_SIZE / 2.0;   new_node->gui_topo = topo;   canvas = GNOME_CANVAS(topo->widget);   new_node->group = gnome_canvas_item_new(gnome_canvas_root(canvas),					   gnome_canvas_group_get_type(),					   "x", x,					   "y", y,					   NULL);   new_node->x = x;   new_node->y = y;   new_node->z = z;   new_node->id = id;   if (id == 0)      new_node->type = TOPO_NODE_BASE_STATION;   else      new_node->type = TOPO_NODE_INACTIVE;   gtk_signal_connect(GTK_OBJECT(new_node->group), "event",		      (GtkSignalFunc)item_event_handler,		      new_node);   if (id == 0)      new_node->node = gnome_canvas_item_new(GNOME_CANVAS_GROUP(new_node->group),					     gnome_canvas_ellipse_get_type(),					     "x1", 0.0,					     "y1", 0.0,					     "x2", (gdouble)TOPO_NODE_SIZE,					     "y2", (gdouble)TOPO_NODE_SIZE,					     "fill-color", "blue",					     "outline-color", "black",					     NULL);   else      new_node->node = gnome_canvas_item_new(GNOME_CANVAS_GROUP(new_node->group),					     gnome_canvas_ellipse_get_type(),					     "x1", 0.0,					     "y1", 0.0,					     "x2", (gdouble)TOPO_NODE_SIZE,					     "y2", (gdouble)TOPO_NODE_SIZE,					     "fill-color", "yellow",					     "outline-color", "black",					     NULL);   new_node->text = g_malloc(TOPO_LABEL_SIZE);   g_sprintf(new_node->text, "%d", id);     new_node->label = gnome_canvas_item_new(GNOME_CANVAS_GROUP(new_node->group),					   gnome_canvas_text_get_type(),					   "x", node_radius,					   "y", node_radius,					   "anchor", GTK_ANCHOR_CENTER,					   "font", "fixed",					   "fill-color-rgba", 0xff00ffff,					   "text", new_node->text,					   NULL);      /* Add the topo_node to the hash table so we can edit it later. */   g_hash_table_insert(topo->nodes, GINT_TO_POINTER(id), new_node);   g_hash_table_remove(topo->unconf_nodes, GINT_TO_POINTER(id));      /* Force a redraw. */   //gnome_canvas_update_now(canvas);}/* Add a new node to a topology. */void gui_topo_node_new(gui_topo_t *topo, gint id, gint light, gint temp){   if (g_hash_table_lookup (topo->unconf_nodes, GINT_TO_POINTER(id)))      return;   if (g_hash_table_lookup (topo->nodes, GINT_TO_POINTER (id)))      return;   GnomeCanvas *canvas;   gdouble x, y;   int int_x, int_y;   topo_node_t *new_node = g_new(topo_node_t, 1);   gdouble node_radius = (gdouble)TOPO_NODE_SIZE / 2.0;   gtk_widget_get_size_request (topo->widget, &int_x, &int_y);   x = int_x;   y = int_y;   //gdouble half_topo_x = x / 2.0;   //gdouble half_topo_y = y / 2.0;   gint type;   debug ("blasting a new topo node");   new_node->gui_topo = topo;   if (id == 0)      type = TOPO_NODE_BASE_STATION;   else      type = TOPO_NODE_UNCONFIGURED;   canvas = GNOME_CANVAS(topo->widget);   /* We hard code node zero as the relay in the middle of a star. */   /*   if(type == TOPO_NODE_BASE_STATION) {      x = half_topo_x;      y = half_topo_y;   } else   {      x = half_topo_x +	 cos((gdouble)(num_nodes-1) * (2*M_PI) /	     (gdouble)TOPO_NUM_NODES) * (gdouble)TOPO_RADIUS;      y = half_topo_y +	 sin((gdouble)(num_nodes-1) * (2*M_PI) /	 (gdouble)TOPO_NUM_NODES) * (gdouble)TOPO_RADIUS;	 }   */   if (type == TOPO_NODE_UNCONFIGURED || type == TOPO_NODE_BASE_STATION) {      g_hash_table_insert(topo->unconf_nodes, GINT_TO_POINTER(id), new_node);      gint pos = g_hash_table_size (topo->unconf_nodes) - 1;      x = (pos / TOPO_UNCONF_ROWS) * TOPO_SPACING + TOPO_SPACING_OFFSET;      y = (pos % TOPO_UNCONF_ROWS) * TOPO_SPACING + TOPO_SPACING_OFFSET;   }      /* Create a new group for all the objects associated with this node. */   new_node->group = gnome_canvas_item_new(gnome_canvas_root(canvas),					   gnome_canvas_group_get_type(),					   "x", x,					   "y", y,					   NULL);   new_node->x = x;   new_node->y = y;   new_node->z = 0;   gtk_signal_connect(GTK_OBJECT(new_node->group), "event",		      (GtkSignalFunc)item_event_handler,		      new_node);   gint color = temp_get_color (light);      if(type == TOPO_NODE_BASE_STATION)      new_node->node = gnome_canvas_item_new(GNOME_CANVAS_GROUP(new_node->group),					     gnome_canvas_ellipse_get_type(),					     "x1", 0.0,					     "y1", 0.0,					     "x2", (gdouble)TOPO_NODE_SIZE,					     "y2", (gdouble)TOPO_NODE_SIZE,					     "fill-color-rgba", 0x0000ffff,					     "outline-color", "black",					     NULL);   else   {      new_node->node = gnome_canvas_item_new(GNOME_CANVAS_GROUP(new_node->group),					     gnome_canvas_ellipse_get_type(),					     "x1", 0.0,					     "y1", 0.0,					     "x2", (gdouble)TOPO_NODE_SIZE,					     "y2", (gdouble)TOPO_NODE_SIZE,					     "fill-color-rgba", color/*0xff0000ff*/,					     "outline-color", "black",					     NULL);/*      new_node->points = gnome_canvas_points_new(2);      new_node->points->coords[0] = half_topo_x + node_radius;      new_node->points->coords[1] = half_topo_y + node_radius;      new_node->points->coords[2] = x + node_radius;      new_node->points->coords[3] = y + node_radius;      new_node->edge = gnome_canvas_item_new(gnome_canvas_root(canvas),					     gnome_canvas_line_get_type(),					     "points", new_node->points,					     "fill-color", "purple",					     "width-units", 2.4,					     NULL);      gnome_canvas_item_lower_to_bottom(new_node->edge);      gnome_canvas_item_raise(new_node->edge, 2);*/   }      new_node->id = id;   new_node->type = type;   new_node->text = g_malloc(TOPO_LABEL_SIZE);   g_sprintf(new_node->text, "%d", id);     new_node->label = gnome_canvas_item_new(GNOME_CANVAS_GROUP(new_node->group),					   gnome_canvas_text_get_type(),					   "x", node_radius,					   "y", node_radius,					   "anchor", GTK_ANCHOR_CENTER,					   "font", "fixed",					   "fill-color-rgba", 0xff00ffff,					   "text", new_node->text,					   NULL);      /* Add the topo_node to the hash table so we can edit it later. */   g_hash_table_insert(topo->nodes, GINT_TO_POINTER(id), new_node);   /* Force a redraw. */   gnome_canvas_update_now(canvas);}/* Update a node in a topology. */void gui_topo_node_update(gui_topo_t *topo, gint id, gint light, gint temp){   debug ("looking up %d", id);      topo_node_t *node = g_hash_table_lookup (topo->nodes, GINT_TO_POINTER (id));   if (node == NULL) {      node = g_hash_table_lookup (topo->unconf_nodes, GINT_TO_POINTER (id));      if (node == NULL) {	 debug ("couldn't find node %d", id);	 return;      }   }   gint color;   color = temp_get_color (light);   if (node->type != TOPO_NODE_BASE_STATION &&       topo->selected != id) {      node->type = TOPO_NODE_REGULAR;      gnome_canvas_item_set (node->node, "fill-color-rgba", color, NULL);   }}void gui_topo_node_update_pos (gui_topo_t *topo, gint id, gdouble x, gdouble y, gdouble z){   topo_node_t *snode;   if (id != -1) {      snode = g_hash_table_lookup (topo->nodes, GINT_TO_POINTER (id));      gnome_canvas_item_move (snode->group, x - snode->x, y - snode->y);      //gnome_canvas_item_set (snode->group, "x", x, "y", y, NULL);      //gnome_canvas_item_set (snode->label, "x", x, "y", y, NULL);      snode->x = x;      snode->y = y;   }   g_hash_table_remove(topo->unconf_nodes, GINT_TO_POINTER(id));}/* Highlight the currently selected node. */void gui_topo_set_current_node(gui_topo_t *topo, gint id){   topo_node_t *snode;   if (id != -1) {            /* First change back the old one to the correct color. */      snode = g_hash_table_lookup(topo->nodes, GINT_TO_POINTER(topo->selected));      if(snode)      {	 if(topo->selected == 0)	    gnome_canvas_item_set(snode->node, "fill-color", "blue", NULL);	 else {	    debug("need to get sensor resources here");	 }      }            if(id != GUI_SELECT_NONE)      {	 /* If this is selecting a new node set the new color. */	 snode = g_hash_table_lookup(topo->nodes, GINT_TO_POINTER(id));	 gnome_canvas_item_set(snode->node, "fill-color", "green", NULL);	 	 topo->selected = id;      }   }}/*** Functions private to this file. ***/gint item_event_handler(GnomeCanvasItem *item, GdkEvent *event, topo_node_t *node){   static gboolean dragging = FALSE; // Is mouse button being held down for dragging   static gdouble x, y;   gdouble new_x, new_y;   gdouble item_x, item_y, mouse_x, mouse_y;   GdkCursor *fleur;      /* We need to convert to item coordinates because some transormation      could have happened on this item... */   mouse_x = event->button.x;   mouse_y = event->button.y;   g_object_get (item, "x", &item_x, "y", &item_y, NULL);   gnome_canvas_item_w2i(item->parent, &item_x, &item_y);      switch (event->type)   {   case GDK_BUTTON_PRESS:      /* We deselect if the control key is down. */      if(event->button.state & GDK_CONTROL_MASK)	 gui_gtk_set_current_node(GUI_SELECT_NONE, TRUE);      else	 gui_gtk_set_current_node(node->id, TRUE);            /* We don't want to move the basestation... If we do we will	 have to move all the lines to other nodes too. */      //if(node->id == 0)      // break;            x = item_x;      y = item_y;      fleur = gdk_cursor_new(GDK_FLEUR);      gnome_canvas_item_grab(item,			     GDK_POINTER_MOTION_MASK | 			     GDK_BUTTON_RELEASE_MASK,			     fleur,			     event->button.time);      gdk_cursor_destroy(fleur);      dragging = TRUE;      gui_gtk_set_status(g_strdup_printf("Node %d -- x: %5.0f  y: %5.0f",					 node->id, x, y));            break;   case GDK_MOTION_NOTIFY:      if(dragging && (event->motion.state & GDK_BUTTON1_MASK))       {	 gdouble node_radius = (gdouble)TOPO_NODE_SIZE / 2.0;	 new_x = mouse_x - node_radius;	 new_y = mouse_y - node_radius;	 /* force the dragging to within the image area */	 if (new_x < node_radius)	    new_x = node_radius;	 if (new_y < TOPO_BG_OFFSET + node_radius)	    new_y = TOPO_BG_OFFSET + node_radius;	 if (new_x > max_x - node_radius)	    new_x = max_x - node_radius;	 if (new_y > max_y + TOPO_BG_OFFSET - node_radius)	    new_y = max_y + TOPO_BG_OFFSET - node_radius;	 if (node->id == 0)	    node->type = TOPO_NODE_BASE_STATION;	 if (node->type != TOPO_NODE_INACTIVE)	    node->type = TOPO_NODE_REGULAR;	 g_hash_table_remove (node->gui_topo->unconf_nodes, GINT_TO_POINTER (node->id));	 	 /* First move the node's group. */	 gnome_canvas_item_move(item, new_x - x, new_y - y);	 node->x = new_x;	 node->y = new_y;	 /* Now redraw the line too. */	 /*	 node->points->coords[2] = node->points->coords[2] + new_x - x;	 node->points->coords[3] = node->points->coords[3] + new_y - y;	 gnome_canvas_item_set(node->edge,			       "points", node->points,			       NULL);	 */	 x = new_x;	 y = new_y;	 gui_gtk_set_status(g_strdup_printf("Node %d -- x: %5.0f  y: %5.0f",					    node->id, x, y));      }      break;   case GDK_BUTTON_RELEASE:      gnome_canvas_item_ungrab(item, event->button.time);      dragging = FALSE;      gui_gtk_set_status(g_strdup_printf("Selected Node: %d", node->id));      break;   default:      break;   }   return FALSE;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?