public DraggedLinkElement(ProductionGraphViewer parent, NodeElement startNode, LinkType startConnectionType, Item item) : base(parent) { if (startConnectionType == LinkType.Input) { ConsumerElement = startNode; } else { SupplierElement = startNode; } StartConnectionType = startConnectionType; Item = item; if ((Control.MouseButtons & MouseButtons.Left) != 0) { DragType = DragType.MouseDown; } else { DragType = DragType.MouseUp; } }
public void DeleteNode(NodeElement node) { if (node != null) { foreach (NodeLink link in node.DisplayedNode.InputLinks.ToList().Union(node.DisplayedNode.OutputLinks.ToList())) { Elements.RemoveWhere(le => le is LinkElement && (le as LinkElement).DisplayedLink == link); } Elements.Remove(node); node.DisplayedNode.Destroy(); UpdateNodes(); Invalidate(); } }
private void EndDrag(Point location) { if (SupplierElement != null && ConsumerElement != null) { if (StartConnectionType == LinkType.Input) { NodeLink.Create(SupplierElement.DisplayedNode, ConsumerElement.DisplayedNode, Item, ConsumerElement.DisplayedNode.GetUnsatisfiedDemand(Item)); } else { NodeLink.Create(SupplierElement.DisplayedNode, ConsumerElement.DisplayedNode, Item, SupplierElement.DisplayedNode.GetExcessOutput(Item)); } } else if (StartConnectionType == LinkType.Output && ConsumerElement == null) { using (var form = new RecipeChooserForm(DataCache.Recipes.Values.Where(r => r.Ingredients.Keys.Contains(Item)), new List<Item> { Item }, "Create output node", "Use recipe {0}")) { var result = form.ShowDialog(); if (result == DialogResult.OK) { NodeElement newElement = null; if (form.selectedRecipe != null) { newElement = new NodeElement(RecipeNode.Create(form.selectedRecipe, Parent.Graph), Parent); } else if (form.selectedItem != null) { newElement = new NodeElement(ConsumerNode.Create(form.selectedItem, Parent.Graph), Parent); } newElement.Update(); newElement.Location = Point.Add(location, new Size(-newElement.Width / 2, -newElement.Height / 2)); new LinkElement(Parent, NodeLink.Create(SupplierElement.DisplayedNode, newElement.DisplayedNode, Item)); } } } else if (StartConnectionType == LinkType.Input && SupplierElement == null) { using (var form = new RecipeChooserForm(DataCache.Recipes.Values.Where(r => r.Results.Keys.Contains(Item)), new List<Item> { Item }, "Create infinite supply node", "Use recipe {0}")) { var result = form.ShowDialog(); if (result == DialogResult.OK) { NodeElement newElement = null; if (form.selectedRecipe != null) { newElement = new NodeElement(RecipeNode.Create(form.selectedRecipe, Parent.Graph), Parent); } else if (form.selectedItem != null) { newElement = new NodeElement(SupplyNode.Create(form.selectedItem, Parent.Graph), Parent); } newElement.Update(); newElement.Location = Point.Add(location, new Size(-newElement.Width / 2, -newElement.Height / 2)); new LinkElement(Parent, NodeLink.Create(newElement.DisplayedNode, ConsumerElement.DisplayedNode, Item)); } } } Parent.AddRemoveElements(); Parent.UpdateNodes(); Dispose(); }
public void PositionNodes() { if (!Elements.Any()) { return; } var nodeOrder = Graph.GetTopologicalSort(); nodeOrder.Reverse(); List <ProductionNode>[] nodePositions = new List <ProductionNode> [nodeOrder.Count()]; for (int i = 0; i < nodePositions.Count(); i++) { nodePositions[i] = new List <ProductionNode>(); } nodePositions.First().AddRange(nodeOrder.OfType <ConsumerNode>()); foreach (RecipeNode node in nodeOrder.OfType <RecipeNode>()) { bool PositionFound = false; for (int i = nodePositions.Count() - 1; i >= 0 && !PositionFound; i--) { foreach (ProductionNode listNode in nodePositions[i]) { if (listNode.CanUltimatelyTakeFrom(node)) { nodePositions[i + 1].Add(node); PositionFound = true; break; } } } if (!PositionFound) { nodePositions.First().Add(node); } } nodePositions.Last().AddRange(nodeOrder.OfType <SupplyNode>()); int marginX = 100; int marginY = 200; int y = marginY; int[] tierWidths = new int[nodePositions.Count()]; for (int i = 0; i < nodePositions.Count(); i++) { var list = nodePositions[i]; int maxHeight = 0; int x = marginX; foreach (var node in list) { NodeElement control = GetElementForNode(node); control.X = x; control.Y = y; x += control.Width + marginX; maxHeight = Math.Max(control.Height, maxHeight); } if (maxHeight > 0) // Don't add any height for empty tiers { y += maxHeight + marginY; } tierWidths[i] = x; } int centrePoint = tierWidths.Last(i => i > marginX) / 2; for (int i = tierWidths.Count() - 1; i >= 0; i--) { int offset = centrePoint - tierWidths[i] / 2; foreach (var node in nodePositions[i]) { NodeElement element = GetElementForNode(node); element.X = element.X + offset; } } UpdateNodes(); LimitViewToBounds(); Invalidate(true); }