Index: /branch/joao/umitMapper/Graph.py
===================================================================
--- /branch/joao/umitMapper/Graph.py (revision 605)
+++ /branch/joao/umitMapper/Graph.py (revision 617)
@@ -162,9 +162,5 @@
         @param : List of connections
         """
-        if nodeIDA > nodeIDB:
-            connection = (nodeIDB, nodeIDA)
-        else:
-            connection = (nodeIDA, nodeIDB)
-
+        connection = (nodeIDA, nodeIDB)
         self.__connections.add(connection)
 
@@ -180,11 +176,11 @@
         """
         nodeID = node.getID()
-        connections = set()
+        connections = []
 
         for (a, b) in self.__connections:
             if a == nodeID and b not in exceptNodes:
-                connections.add(b)
+                connections.append(b)
             if b == nodeID and a not in exceptNodes:
-                connections.add(a)
+                connections.append(a)
 
         return connections
Index: /branch/joao/umitMapper/RadialNet.py
===================================================================
--- /branch/joao/umitMapper/RadialNet.py (revision 604)
+++ /branch/joao/umitMapper/RadialNet.py (revision 617)
@@ -19,4 +19,8 @@
 import gtk
 import math
+import pango
+import drawing
+import geometry
+from gtk import gdk
 from Coordinate import PolarCoordinate
 from Graph import Graph, Node
@@ -42,10 +46,37 @@
         self.__centerOfWidget = (0, 0)
         """Store the center of widget"""
-
-        gtk.DrawingArea.__init__(self)
+        self.__isInAnimation = False
+
+        super(RadialNet, self).__init__()
         self.connect("expose_event", self.expose)
-
-
-    def expose(self, widget, event):
+        self.connect("button_press_event", self.button_press)
+        self.connect("button_release_event", self.button_release)
+        self.connect("motion_notify_event", self.motion_notify)
+
+        self.add_events(gdk.BUTTON_PRESS_MASK |
+                        gdk.BUTTON_RELEASE_MASK |
+                        gdk.POINTER_MOTION_MASK)
+
+
+    def __getNodeByCoordinate(self, point):
+        """
+        """
+        xc, yc = self.__centerOfWidget
+
+        for id in range(self.__graph.getNumberOfNodes()):
+
+            node = self.__graph.getNodeByID(id)
+
+            xn, yn = node.getCartesianCoordinate()
+            center = (xc + xn, yc - yn)
+            radius = node.getDrawInfo('radius')
+
+            if ( geometry.pointIsInCircle(point, radius, center) == True ):
+                return node, center
+
+        return None
+
+
+    def button_press(self, widget, event):
         """
         Drawing callback
@@ -57,8 +88,77 @@
         @return: Indicator of the event propagation
         """
+        event.window.set_cursor(gdk.Cursor(gtk.gdk.X_CURSOR))
+
+        if event.button == 3:
+
+            result = self.__getNodeByCoordinate(self.get_pointer())
+
+            if ( result != None ):
+
+                xw, yw = self.window.get_origin()
+                node, point = result
+                x, y = point
+
+                nodeView = NodeView(node, (int(xw + x), int(yw + y)), self)
+                nodeView.show_all()
+        
+        return True
+
+
+    def button_release(self, widget, event):
+        """
+        Drawing callback
+        @type  widget: GtkWidget
+        @param widget: Gtk widget superclass
+        @type  event: GtkEvent
+        @param event: Gtk event of widget
+        @rtype: boolean
+        @return: Indicator of the event propagation
+        """
+        event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
+
+        return True
+
+
+    def motion_notify(self, widget, event):
+        """
+        Drawing callback
+        @type  widget: GtkWidget
+        @param widget: Gtk widget superclass
+        @type  event: GtkEvent
+        @param event: Gtk event of widget
+        @rtype: boolean
+        @return: Indicator of the event propagation
+        """
+        xc, yc = self.__centerOfWidget
+        pointer = self.get_pointer()
+
+        for id in range(self.__graph.getNumberOfNodes()):
+            node = self.__graph.getNodeByID(id)
+            node.setDrawInfo('over', False)
+
+        result = self.__getNodeByCoordinate(self.get_pointer())
+
+        if result != None:
+            result[0].setDrawInfo('over', True)
+
+        self.queue_draw()
+        
+        return True
+
+
+    def expose(self, widget, event):
+        """
+        Drawing callback
+        @type  widget: GtkWidget
+        @param widget: Gtk widget superclass
+        @type  event: GtkEvent
+        @param event: Gtk event of widget
+        @rtype: boolean
+        @return: Indicator of the event propagation
+        """
         self.context = widget.window.cairo_create()
 
-        self.context.rectangle(event.area.x, event.area.y,
-                               event.area.width, event.area.height)
+        self.context.rectangle(*event.area)
         self.context.set_source_rgb(1.0, 1.0, 1.0)
         self.context.fill_preserve()
@@ -142,9 +242,17 @@
         @param : The node will be draw
         """
-        (x, y) = node.getCartesianCoordinate()
-        (r, g, b) = node.getDrawInfo('color')
-        (xc, yc) = self.__centerOfWidget
-
-        self.context.arc(xc + x, yc - y, 6, 0, 2 * math.pi)
+        x, y = node.getCartesianCoordinate()
+        r, g, b = node.getDrawInfo('color')
+        xc, yc = self.__centerOfWidget
+
+        radius = node.getDrawInfo('radius')
+
+        if node.getDrawInfo('over') == True:
+            self.context.arc(xc + x, yc - y, radius + 2, 0, 2 * math.pi)
+            self.context.set_source_rgba(0.0, 0.0, 1.0, 0.3)
+            self.context.fill_preserve()
+            self.context.stroke()
+
+        self.context.arc(xc + x, yc - y, radius, 0, 2 * math.pi)
         self.context.set_source_rgb(r, g, b)
         self.context.fill_preserve()
@@ -161,6 +269,6 @@
         Make some operations to determine the initial node positions
         """
-        newNodes = set([self.__graph.getMainNodeID()])
-        oldNodes = set([])
+        newNodes = [self.__graph.getMainNodeID()]
+        oldNodes = []
 
         angleRange = range(self.__graph.getNumberOfNodes())
@@ -171,9 +279,9 @@
         for i in range(self.__numberOfRings):
 
-            locNodes = set([])
+            locNodes = []
 
             for nodeID in newNodes:
 
-                oldNodes.add(nodeID)
+                oldNodes.append(nodeID)
 
                 node = self.__graph.getNodeByID(nodeID)
@@ -184,6 +292,4 @@
                 radius = self.__ringGap * (i + 2)
 
-                print connections
-
                 for j in connections:
 
@@ -203,8 +309,8 @@
                     child.setPolarCoordinate(radius, math.radians(theta))
 
-                    locNodes.add(j)
+                    locNodes.append(j)
 
             for j in locNodes:
-                newNodes.add(j)
+                newNodes.append(j)
 
             for j in oldNodes:
@@ -222,4 +328,119 @@
         """
         self.__graph = graph
+
+
+
+class NodeView(gtk.Window):
+    """
+    """
+    def __init__(self, node, position, parent):
+        """
+        """
+        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
+        self.move(position[0], position[1])
+        self.__button_press_position = self.get_pointer()
+        self.set_size_request(200, 120)
+        self.modify_bg(gtk.STATE_NORMAL, gdk.color_parse("#fbffc1"))
+
+        self.__node = node
+        self.__pressed = False
+        self.__parent = parent
+
+        self.connect("button_press_event", self.button_press)
+        self.connect("button_release_event", self.button_release)
+        self.connect("enter_notify_event", self.enter_notify)
+        self.connect("leave_notify_event", self.leave_notify)
+        self.connect("motion_notify_event", self.motion_notify)
+
+        self.add_events(gdk.BUTTON_PRESS_MASK |
+                        gdk.BUTTON_RELEASE_MASK |
+                        gdk.POINTER_MOTION_MASK |
+                        gdk.ENTER_NOTIFY |
+                        gdk.LEAVE_NOTIFY |
+                        gdk.POINTER_MOTION_HINT_MASK)
+
+        self.__draw_compact_layout()
+
+
+    def __draw_compact_layout(self):
+        """
+        """
+        self.__body = gtk.VBox()
+        self.__body.set_spacing(5)
+        self.__body.set_border_width(5)
+        self.__head = gtk.HBox()
+        self.__head.set_spacing(5)
+        self.__head.set_border_width(5)
+
+        self.__boldFont = pango.FontDescription('monospace bold 8')
+        self.__boldFont = pango.FontDescription('monospace 8')
+
+        self.__title = gtk.Label()
+        self.__title.set_markup(self.__node.getInformation('ip'))
+        self.__title.modify_font(self.__boldFont)
+
+        self.__event = gtk.EventBox()
+        self.__event.set_size_request(15, 15)
+        r, g, b = drawing.cairoToGdkColor(self.__node.getDrawInfo('color'))
+        self.__event.modify_bg(gtk.STATE_NORMAL, gdk.Color(r, g, b))
+
+        self.__head.pack_start(self.__event, False, False, 0)
+        self.__head.pack_start(self.__title, False, False, 0)
+        self.__body.pack_start(self.__head, False, False, 0)
+
+        self.add(self.__body)
+
+
+    def button_press(self, widget, event):
+        """
+        """
+        self.__pressed = True
+        self.__button_press_position = self.get_pointer()
+
+        return True
+
+
+    def button_release(self, widget, event):
+        """
+        """
+        if event.button == 3:
+            self.__node.setDrawInfo('over', False)
+            self.destroy()
+            self.__parent.queue_draw()
+
+        self.__pressed = False
+
+        return True
+
+
+    def enter_notify(self, widget, event):
+        """
+        """
+        self.__node.setDrawInfo('over', True)
+        self.__parent.queue_draw()
+
+
+    def leave_notify(self, widget, event):
+        """
+        """
+        self.__node.setDrawInfo('over', False)
+
+
+    def motion_notify(self, widget, event):
+        """
+        """
+        self.__node.setDrawInfo('over', True)
+
+        if event.is_hint == True:
+
+            x, y, button_state = event.window.get_pointer()
+
+            if button_state & gtk.gdk.BUTTON1_MASK and self.__pressed:
+
+                xw, yw = event.window.get_root_origin()
+                xd, yd = self.__button_press_position
+                self.move(x + xw - xd, y + yw - yd)
+
+        return True
 
 
@@ -235,5 +456,4 @@
         """Hash with draw information"""
         self.__coordinate = PolarCoordinate()
-        """Coordinate of node"""
 
         super(NetNode, self).__init__(id)
@@ -277,8 +497,11 @@
         @return: The requested information
         """
-        return self.__drawInfo[ info ]
-
-
-    def setDrawInfo(self, info):
+        try:
+            return self.__drawInfo[ info ]
+        except:
+            return None
+
+
+    def setDrawInfo(self, info, value=None):
         """
         Set draw information
@@ -286,5 +509,8 @@
         @param : Draw information dictionary
         """
-        self.__drawInfo = info
+        if value == None:
+            self.__drawInfo = info
+        else:
+            self.__drawInfo[info] = value
 
 
@@ -296,4 +522,5 @@
 
     window = gtk.Window()
+    radialnet = RadialNet(5)
 
     # Creating nodes
@@ -301,41 +528,41 @@
 
     nodes[0] = NetNode(0)
-    nodes[0].setDrawInfo({"color":(0,1,0)})
+    nodes[0].setDrawInfo({"color":(0,1,0), "radius":10})
     nodes[0].setInformation({"ip":"192.168.1.1", "host":"joao.test.net"})
 
     nodes[1] = NetNode(1)
-    nodes[1].setDrawInfo({"color":(1,1,0)})
+    nodes[1].setDrawInfo({"color":(1,1,0), "radius":8})
     nodes[1].setInformation({"ip":"192.168.1.2", "host":"luis.test.net"})
 
     nodes[2] = NetNode(2)
-    nodes[2].setDrawInfo({"color":(1,0,0)})
+    nodes[2].setDrawInfo({"color":(1,0,0), "radius":6})
     nodes[2].setInformation({"ip":"192.168.1.3", "host":"polo.test.net"})
 
     nodes[3] = NetNode(3)
-    nodes[3].setDrawInfo({"color":(0,1,0)})
+    nodes[3].setDrawInfo({"color":(0,1,0), "radius":10})
     nodes[3].setInformation({"ip":"192.168.2.5", "host":"mara.test.net"})
 
     nodes[4] = NetNode(4)
-    nodes[4].setDrawInfo({"color":(1,0,0)})
+    nodes[4].setDrawInfo({"color":(1,0,0), "radius":12})
     nodes[4].setInformation({"ip":"192.168.3.2", "host":"nara.test.net"})
 
     nodes[5] = NetNode(5)
-    nodes[5].setDrawInfo({"color":(0,1,0)})
+    nodes[5].setDrawInfo({"color":(0,1,0), "radius":8})
     nodes[5].setInformation({"ip":"192.168.3.3", "host":"luca.test.net"})
 
     nodes[6] = NetNode(6)
-    nodes[6].setDrawInfo({"color":(1,1,0)})
+    nodes[6].setDrawInfo({"color":(1,1,0), "radius":8})
     nodes[6].setInformation({"ip":"192.168.3.1", "host":"jose.test.net"})
 
     nodes[7] = NetNode(7)
-    nodes[7].setDrawInfo({"color":(1,1,0)})
+    nodes[7].setDrawInfo({"color":(1,1,0), "radius":10})
     nodes[7].setInformation({"ip":"192.168.1.8", "host":"mark.test.net"})
 
     nodes[8] = NetNode(8)
-    nodes[8].setDrawInfo({"color":(1,1,0)})
+    nodes[8].setDrawInfo({"color":(1,1,0), "radius":8})
     nodes[8].setInformation({"ip":"192.168.1.7", "host":"mama.test.net"})
 
     nodes[9] = NetNode(9)
-    nodes[9].setDrawInfo({"color":(1,0,0)})
+    nodes[9].setDrawInfo({"color":(1,0,0), "radius":6})
     nodes[9].setInformation({"ip":"192.168.4.7", "host":"papa.test.net"})
 
@@ -352,5 +579,4 @@
     graph.setConnections(5, 9)
 
-    radialnet = RadialNet(5)
     radialnet.setGraph(graph)
     radialnet.set_size_request(400, 400)
