示例#1
0
        private void UpdateNode(Node node, Network network)
        {
            try {
                lock (network) {
                    if (debug)
                    {
                        Console.Out.WriteLine("*** Updating node {0} from network {1}.", node.NickName, network.NetworkName);
                    }
                    Hashtable node2nodegroup = network.Properties["node2nodegroup"] as Hashtable;

                    if (!node2nodegroup.ContainsKey(node))
                    {
                        throw new Exception("Unable to modify node: could not find the nodegroup which contains the specified node: " + node.NickName);
                    }

                    NodeGroup ng       = node2nodegroup[node] as NodeGroup;
                    PointD    position = ng.Position;
                    DeleteNode(node, network);
                    AddNode(node, network, position);
                    if (debug)
                    {
                        Console.Out.WriteLine("### Node update complete for node {0} from network {1}.", node.NickName, network.NetworkName);
                    }
                }
            } catch (Exception ex) {
                OnError(ex);
            }
        }
示例#2
0
        public ZoomableNetworkMap()
        {
            noticeIcon = Gui.LoadIcon(24, "dialog-information");
            rng        = new Random();

            networkZOrder = ArrayList.Synchronized(new ArrayList());

            selectedGroup     = null;
            nodeDragging      = false;
            nodeDraggingLastX = 0;
            nodeDraggingLastY = 0;

            Runtime.Core.NetworkAdded   += (NetworkEventHandler)DispatchService.GuiDispatch(new NetworkEventHandler(AddNetwork));
            Runtime.Core.NetworkRemoved += (NetworkEventHandler)DispatchService.GuiDispatch(new NetworkEventHandler(DeleteNetwork));

            foreach (Network network in Runtime.Core.Networks)
            {
                AddNetwork(network);
            }

            base.ButtonPressEvent   += base_ButtonPressEvent;
            base.ButtonReleaseEvent += base_ButtonReleaseEvent;
            base.MotionNotifyEvent  += base_MotionNotifyEvent;

            this.render  = DrawContents;
            this.overlay = DrawOverlay;
            this.QueueDraw();
        }
示例#3
0
        private SizeD CalculateNodeGroupTitleTextSize(NodeGroup ng, Cairo.Context gc)
        {
            Pango.Layout layout = new Pango.Layout(this.PangoContext);
            layout.FontDescription      = this.PangoContext.FontDescription.Copy();
            layout.FontDescription.Size = Pango.Units.FromDouble(NodegroupNameFontSize);
            layout.SetText(ng.Name);

            Gdk.Size size = GetTextSize(layout);
            return(new SizeD(size.Width, size.Height));
        }
示例#4
0
        private SizeD CalculateNodeGroupSize(NodeGroup ng, Cairo.Context gc)
        {
            var titleTextSize   = CalculateNodeGroupTitleTextSize(ng, gc);
            var titleTextHeight = titleTextSize.Height + (Padding * 2.0);
            var heightNodeCount = (ng.Nodes.Count < 3) ? 1 : ng.Nodes.Count;

            var width = Math.Max(titleTextSize.Width + (Padding * 2.0),
                                 (ng.Nodes.Count * AvatarDimension) + (Padding * 2.0) + (Padding * ng.Nodes.Count));
            var height = (heightNodeCount * AvatarDimension) + titleTextHeight + (Padding * 2.0) + (Padding * heightNodeCount);

            return(new SizeD(width, height));
        }
示例#5
0
        private void DeleteNode(Node node, Network network)
        {
            lock (network) {
                if (debug)
                {
                    Console.Out.WriteLine("*** Deleting node {0} from network {1}.", node.NickName, network.NetworkName);
                }
                Hashtable nodegroups     = network.Properties["nodegroups"] as Hashtable;
                Hashtable node2nodegroup = network.Properties["node2nodegroup"] as Hashtable;
                //string nodeIP = (node.ExternalIP == string.Empty) ? node.NickName : node.ExternalIP;

                if (!node2nodegroup.ContainsKey(node))
                {
                    throw new Exception("Unable to delete node: could not find the nodegroup which contains the specified node: " + node.NickName);
                }

                NodeGroup ng = node2nodegroup[node] as NodeGroup;
                if (debug)
                {
                    Console.Out.WriteLine(" -> Found node {0} in nodegroup {1} / network {2}.", node.NickName, ng.Name, network.NetworkName);
                }
                ng.Nodes.Remove(node);
                node2nodegroup.Remove(node);
                if (debug)
                {
                    Console.Out.WriteLine(" -> Deleted node {0} in nodegroup {1} / network {2}.", node.NickName, ng.Name, network.NetworkName);
                }

                // If nodegroup is empty, delete that too.
                if (ng.Nodes.Count == 0)
                {
                    if (debug)
                    {
                        Console.Out.WriteLine(" -> Nodegroup {0} / network {1} empty, deleting.", ng.Name, network.NetworkName);
                    }
                    nodegroups.Remove(ng.Name);
                    if (debug)
                    {
                        Console.Out.WriteLine(" -> Nodegroup {0} / network {1} deleted.", ng.Name, network.NetworkName);
                    }
                }
            }
        }
示例#6
0
        private void AddNode(Node node, Network network, PointD position)
        {
            lock (network) {
                if (debug)
                {
                    Console.Out.WriteLine("*** Adding node {0} to network {1}...", node.NickName, network.NetworkName);
                }
                Hashtable nodegroups     = network.Properties["nodegroups"] as Hashtable;
                Hashtable node2nodegroup = network.Properties["node2nodegroup"] as Hashtable;

                IPAddress address = GetExternalIPv4Address(node);
                string    nodeIP  = (address.Equals(IPAddress.None)) ? node.NickName : address.ToString();

                if (nodegroups.ContainsKey(nodeIP))
                {
                    NodeGroup ng = nodegroups[nodeIP] as NodeGroup;
                    ng.Nodes.Add(node);
                    node2nodegroup.Add(node, ng);
                    if (debug)
                    {
                        Console.Out.WriteLine(" -> Added node {0} to network {1} / nodegroup {2}", node.NickName, network.NetworkName, ng.Name);
                    }
                }
                else
                {
                    NodeGroup ng = new NodeGroup(nodeIP, position);
                    ng.Nodes.Add(node);
                    node2nodegroup.Add(node, ng);
                    nodegroups.Add(nodeIP, ng);
                    if (debug)
                    {
                        Console.Out.WriteLine(" -> Added node {0} to network {1} / new nodegroup {2}", node.NickName, network.NetworkName, ng.Name);
                    }
                }
            }
        }
示例#7
0
        private void RenderNodeGroup(NodeGroup ng, Network network, Cairo.Context gc)
        {
            gc.Save();

            SizeD size = CalculateNodeGroupSize(ng, gc);

            ng.Dimension = size;
            CreateRoundedRectPath(gc, ng.Position.X, ng.Position.Y, size.Width, size.Height, 20);
            gc.Color = new Cairo.Color(0, 0, 0, 0.5);
            gc.FillPreserve();

            if (selectedGroup == ng)
            {
                gc.Save();
                gc.Color = orangeOverlay;
                gc.StrokePreserve();
                gc.Restore();
            }

            var titleTextSize = CalculateNodeGroupTitleTextSize(ng, gc);
            var titleSize     = new SizeD(size.Width, titleTextSize.Height + (Padding * 2.0));

            gc.Clip();
            gc.Rectangle(ng.Position.X, ng.Position.Y, titleSize.Width, titleSize.Height);
            gc.Fill();
            gc.ResetClip();

            gc.Color = lightGray;

            double hostTextX = ng.Position.X + (titleSize.Width / 2.0) - (titleTextSize.Width / 2.0);
            double hostTextY = ng.Position.Y + (titleSize.Height / 2.0) - (titleTextSize.Height / 2.0);

            gc.MoveTo(hostTextX, hostTextY /* + titleTextSize.Height */);

            Pango.Layout layout = new Pango.Layout(this.PangoContext);
            layout.FontDescription      = this.PangoContext.FontDescription.Copy();
            layout.FontDescription.Size = Pango.Units.FromDouble(NodegroupNameFontSize);
            layout.SetText(ng.Name);
            Pango.CairoHelper.ShowLayout(gc, layout);

            SizeD nodesSize = CalculateNodeGroupSize(ng, gc);

            if (ng.Nodes.Count == 1)
            {
                double positionY = ng.Position.Y + titleSize.Height + Padding;
                double positionX = ng.Position.X + (ng.Dimension.Width / 2.0) - HalfAvatarDimension;
                RenderNode(gc, (Node)ng.Nodes[0], positionX, positionY);
            }
            else if (ng.Nodes.Count == 2)
            {
                // position them side-by-side, separated by (padding) number of pixels, centered in the
                // space.
                double positionY  = ng.Position.Y + titleSize.Height + Padding;
                double position1X = ng.Position.X + (ng.Dimension.Width / 2.0) - (Padding / 2.0) - AvatarDimension;
                double position2X = position1X + Padding + AvatarDimension;
                RenderNode(gc, (Node)ng.Nodes[0], position1X, positionY);
                RenderNode(gc, (Node)ng.Nodes[1], position2X, positionY);
            }
            else
            {
                double deg = 0;
                double x   = 0;
                double y   = 0;

                var contentY      = ng.Position.Y + titleSize.Height;
                var contentHeight = size.Height - titleSize.Height;
                var middle        = new System.Drawing.Point(Convert.ToInt32(ng.Position.X + size.Width - (size.Width / 2.0)),
                                                             Convert.ToInt32(contentY + contentHeight - (contentHeight / 2.0)));

                int nodeSize = Convert.ToInt32(AvatarDimension);
                for (int i = 0; i < ng.Nodes.Count; i++)
                {
                    x = Math.Sin(deg) * ((size.Width / 2.0) - (nodeSize)) + middle.X - (nodeSize / 2.0);
                    y = Math.Cos(deg) * ((contentHeight / 2.0) - (nodeSize)) + middle.Y - (nodeSize / 2.0);
                    RenderNode(gc, (Node)ng.Nodes[i], x, y);
                    deg += Math.PI / (ng.Nodes.Count / 2.0);
                }
            }
            gc.Restore();
        }
示例#8
0
        private void base_ButtonPressEvent(object sender, Gtk.ButtonPressEventArgs args)
        {
            Gdk.EventButton eb     = args.Event;
            double          mouseX = eb.X;
            double          mouseY = eb.Y;

            DeviceToUser(ref mouseX, ref mouseY);
            if (debug)
            {
                Console.Out.WriteLine("Button Pressed {0}: user coords {1},{2}", eb.Button, mouseX, mouseY);
            }
            PointD    thePoint          = new PointD(mouseX, mouseY);
            NodeGroup firstNodeGroupHit = null;
            Node      firstNodeHit      = null;

            foreach (Network network in networkZOrder)
            {
                Rectangle networkRect = (Rectangle)network.Properties["rect"];
                if (Inside(thePoint, networkRect))
                {
                    if (debug)
                    {
                        Console.Out.WriteLine("Click inside network {0}", network.NetworkName);
                    }
                    Hashtable nodegroups = (Hashtable)network.Properties["nodegroups"];
                    foreach (NodeGroup ng in nodegroups.Values)
                    {
                        //PointD ngPosition = new PointD (ng.Position.X + networkRect.X,
                        //                              ng.Position.Y + networkRect.Y);
                        if (Inside(thePoint, ng.Position, ng.Dimension))
                        {
                            if (debug)
                            {
                                Console.Out.WriteLine("Click inside group {0}", ng.Name);
                            }
                            firstNodeGroupHit = ng;
                            foreach (Node n in ng.Nodes)
                            {
                                PointD np = (PointD)n.Properties["position"];
                                //	np = new PointD (np.X + ngPosition.X,
                                //	                 np.Y + ngPosition.Y);
                                if (Inside(thePoint, np, AvatarSizeD))
                                {
                                    firstNodeHit = n;
                                    if (debug)
                                    {
                                        Console.Out.WriteLine("Click inside node {0}", n);
                                    }
                                    break;
                                    // clicked node n
                                }
                            }
                            break;
                            // click in ng but not any node
                        }
                    }
                    break;
                    // click in network but not any ng
                }
            }

            if (eb.Button == 1 | eb.Button == 3)
            {
                selectedNode = firstNodeHit;

                if (SelectedNodeChanged != null)
                {
                    SelectedNodeChanged(selectedNode);
                }
            }

            switch (eb.Button)
            {
            case 1:
                selectedGroup = firstNodeGroupHit;

                if (selectedGroup != null)
                {
                    this.nodeDragging = true;
                    nodeDraggingLastX = eb.X;
                    nodeDraggingLastY = eb.Y;

                    // we're dragging...
                    this.GdkWindow.Cursor = new Gdk.Cursor(Gdk.CursorType.Plus);
                }

                if (selectedNode != null)
                {
                    if (eb.Type == Gdk.EventType.TwoButtonPress)
                    {
                        ResetDrag();
                        if (NodeDoubleClicked != null)
                        {
                            NodeDoubleClicked(selectedNode);
                        }
                    }
                }

                break;

            case 3:
                if (firstNodeGroupHit == null)
                {
                    // clicked on map background
                    Menu mapMenu = (Menu)Runtime.UIManager.GetWidget("/MapPopupMenu");
                    mapMenu.Popup();
                }
                else
                {
                    if (firstNodeHit != null)
                    {
                        UserMenu userMenu = new UserMenu(firstNodeHit.Network, firstNodeHit);
                        userMenu.Popup();
                    }
                }
                break;
            }
        }