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 + -
显示快捷键?