private void DataNode_ToStringChanged(object sender, RoutedEventArgs e) { AssignTemplate(TemplateWithImage, TemplateWithText); BuildContextMenu(TemplateWithAddMenu, TemplateWithDeleteMenu); if (Parent is GuiVesselsPartGraphNode) { GuiVesselsPartGraphNode pgn = (GuiVesselsPartGraphNode)Parent; pgn.UpdateFromGuiTreeNode(); } }
private void DrawPartAndConnected(KmlPart part, IntPair koords, IntPair parentKoords, Brush lineBrush) { GuiVesselsPartGraphNode partNode = DrawPart(part, koords); Line l = DrawConnection(parentKoords, koords, lineBrush); partNode.Lines.Add(l); GuiVesselsPartGraphNode parentNode = PartGrid[parentKoords.X - PartGridMinX][parentKoords.Y - PartGridMinY]; parentNode.Lines.Add(l); DrawConnectedParts(partNode, koords); }
private GuiVesselsPartGraphNode DrawPart(KmlPart part, int x, int y) { GuiVesselsPartGraphNode node = new GuiVesselsPartGraphNode(part, x, y, Master); if (!InsertGrid(x, y, node)) { throw new Exception("Couldn't place GuiVesselsPartGraphNode on grid pos " + x + ", " + y + " (already occupied)"); //IntPair p = CalcKoords(new IntPair(x, y), x + 1, y); //InsertGrid(p.X, p.Y, node); } Point position = CalcPosition(x, y); Canvas.SetLeft(node, position.X); Canvas.SetTop(node, position.Y); // Have nodes on higher ZIndex than the lines Canvas.SetZIndex(node, 1); VesselsDetails.Children.Add(node); part.Visited = true; return(node); }
private void DrawConnectionAndSeachPart(KmlPart part, IntPair parentKoords, Brush lineBrush) { // Already drawn sub part with one way arrow. // Need to draw the reverse arrow only // But where is the node? Point parentPos = CalcPosition(parentKoords); GuiVesselsPartGraphNode parentNode = PartGrid[parentKoords.X - PartGridMinX][parentKoords.Y - PartGridMinY]; foreach (UIElement element in VesselsDetails.Children) { if (element is GuiVesselsPartGraphNode) { GuiVesselsPartGraphNode node = (GuiVesselsPartGraphNode)element; if (node.DataPart == part) { Line l = DrawConnection(parentPos.X, parentPos.Y, Canvas.GetLeft(node), Canvas.GetTop(node), lineBrush); node.Lines.Add(l); parentNode.Lines.Add(l); break; } } } }
/// <summary> /// Draws all parts of the given KmlVessel. /// </summary> /// <param name="vessel">The KmlVessel to read all parts from</param> public void DrawPartStructure(KmlVessel vessel) { VesselsDetails.Children.Clear(); InitGrid(); if (vessel != null) { foreach (KmlPart part in vessel.Parts) { part.Visited = false; } IntPair rootKoords = CalcKoords(new IntPair(0, 0), 0, 0); GuiVesselsPartGraphNode rootNode = DrawPart(vessel.RootPart, rootKoords); DrawConnectedParts(rootNode, rootKoords); // Draw all parts, that are not drawn yet foreach (KmlPart part in vessel.Parts) { if (!part.Visited) { IntPair koords = CalcKoords(new IntPair(0, PartGridMaxY), 0, PartGridMaxY + CountTop(part, vessel.RootPart)); GuiVesselsPartGraphNode partNode = DrawPart(part, koords); DrawConnectedParts(partNode, koords); } } double minX = 0; double minY = 0; double maxX = 0; double maxY = 0; CalcMinMax(out minX, out minY, out maxX, out maxY); VesselsDetails.Width = maxX - minX + ElementWidth * 2; VesselsDetails.Height = maxY - minY + ElementHeight; VesselsDetails.RenderTransform = new TranslateTransform(-minX, -minY); } }
private void DrawConnectedParts(GuiVesselsPartGraphNode parent, IntPair parentKoords) { KmlPart parentPart = parent.DataPart; IntPair newKoords; // Top atteched parts foreach (KmlPart sub in parentPart.AttachedPartsTop) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X, parentKoords.Y - CountBottom(sub, parentPart) - CountTop(parentPart, parentPart) + 1); for (int y = parentKoords.Y - 1; y > newKoords.Y; y--) { // Fill space with dummy nodes InsertGrid(parentKoords.X, y, new GuiVesselsPartGraphNode(parentKoords.X, y)); } DrawPartAndConnected(sub, newKoords, parentKoords, ConnectVerticalBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectVerticalBrush); } } // Bottom atteched parts foreach (KmlPart sub in parentPart.AttachedPartsBottom) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X, parentKoords.Y + CountTop(sub, parentPart) + CountBottom(parentPart, parentPart) - 1); for (int y = parentKoords.Y + 1; y < newKoords.Y; y++) { // Fill space with dummy nodes InsertGrid(parentKoords.X, y, new GuiVesselsPartGraphNode(parentKoords.X, y)); } DrawPartAndConnected(sub, newKoords, parentKoords, ConnectVerticalBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectVerticalBrush); } } // Left atteched parts foreach (KmlPart sub in parentPart.AttachedPartsLeft) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X - 2, parentKoords.Y); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Right atteched parts foreach (KmlPart sub in parentPart.AttachedPartsRight) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X + 2, parentKoords.Y); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Back atteched parts foreach (KmlPart sub in parentPart.AttachedPartsBack) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X - 2, parentKoords.Y - 1); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Front atteched parts foreach (KmlPart sub in parentPart.AttachedPartsFront) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X + 2, parentKoords.Y + 1); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Surface atteched parts int i = 0; foreach (KmlPart sub in parentPart.AttachedPartsSurface) { if (!sub.Visited) { // Arrange alternating left and right do { if (i % 4 == 0) { newKoords = new IntPair(parentKoords.X - (i / 4 + 1), parentKoords.Y - 1); } else if (i % 4 == 1) { newKoords = new IntPair(parentKoords.X + (i / 4 + 1), parentKoords.Y - 1); } else if (i % 4 == 2) { newKoords = new IntPair(parentKoords.X - (i / 4 + 1), parentKoords.Y + 1); } else { newKoords = new IntPair(parentKoords.X + (i / 4 + 1), parentKoords.Y + 1); } i++; }while (!InsertGrid(newKoords.X, newKoords.Y, null)); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSurfaceBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSurfaceBrush); i++; } } // Docked parts if (parentPart is KmlPartDock) { KmlPartDock dock = (KmlPartDock)parentPart; KmlPart sub = dock.DockedPart; if (sub != null) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X + (sub.Position.X > parentPart.Position.X ? 1 : -1), parentKoords.Y + (sub.Position.Y > parentPart.Position.Y ? 1 : -1)); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectDockBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectDockBrush); } } } }
private bool InsertGrid(int x, int y, GuiVesselsPartGraphNode node) { // Grid koords [-4][-6] will be translated in list index [-4 - minX][-6 - minY] // so index will always be >= 0 // Also keep the grid (list of lists) quadratic // On new min value create a new list, insert amount of blanks, append old list // and replace list by new list if (x < PartGridMinX) { int diffX = PartGridMinX - x; List <List <GuiVesselsPartGraphNode> > list = new List <List <GuiVesselsPartGraphNode> >(); for (int i = 0; i < diffX; i++) { List <GuiVesselsPartGraphNode> l = new List <GuiVesselsPartGraphNode>(); for (int j = PartGridMinY; j <= PartGridMaxY; j++) { l.Add(null); } list.Add(l); } list.AddRange(PartGrid); PartGrid = list; PartGridMinX = x; } if (y < PartGridMinY) { int diffY = PartGridMinY - y; for (int i = 0; i < PartGrid.Count; i++) { List <GuiVesselsPartGraphNode> list = new List <GuiVesselsPartGraphNode>(); for (int j = 0; j < diffY; j++) { list.Add(null); } list.AddRange(PartGrid[i]); PartGrid[i] = list; } PartGridMinY = y; } if (x > PartGridMaxX) { int diffX = x - PartGridMaxX; for (int i = 0; i < diffX; i++) { List <GuiVesselsPartGraphNode> list = new List <GuiVesselsPartGraphNode>(); for (int j = PartGridMinY; j <= PartGridMaxY; j++) { list.Add(null); } PartGrid.Add(list); } PartGridMaxX = x; } if (y > PartGridMaxY) { int diffY = y - PartGridMaxY; for (int i = 0; i < PartGrid.Count; i++) { for (int j = 0; j < diffY; j++) { PartGrid[i].Add(null); } } PartGridMaxY = y; } if (PartGrid[x - PartGridMinX][y - PartGridMinY] == null) { PartGrid[x - PartGridMinX][y - PartGridMinY] = node; return(true); } else { return(false); } }
private void NodeDelete_Click(object sender, RoutedEventArgs e) { KmlNode node = ((sender as MenuItem).DataContext as KmlNode); string nodeName = "node"; string specialText = ""; if (node is KmlKerbal) { nodeName = "kerbal"; if ((node as KmlKerbal).AssignedPart != null) { specialText = "\n\n- The kerbal will be removed from assigned crew part"; } } else if (node is KmlVessel) { nodeName = "vessel"; if ((node as KmlVessel).AssignedCrew.Count > 0) { specialText = "\n\n- Kerbal crew will be send home to astronaut complex\n" + "- Their state will be set to 'Available'\n" + "- Experience or contract progress may get lost"; } } else if (node is KmlPart) { nodeName = "part"; specialText = "\n\n- Part will be removed from vessel structure\n" + "- Attachment indices will be updated"; if (node.Parent is KmlVessel) { foreach (KmlKerbal kerbal in (node.Parent as KmlVessel).AssignedCrew) { if (kerbal.AssignedPart == node) { specialText += "\n- Kerbal crew will be send home to astronaut complex\n" + "- Their state will be set to 'Available'\n" + "- Experience or contract progress may get lost"; break; } } } } if (DlgConfirmation.Show("Do you really want to delete this " + nodeName + " and all its content?\n" + node + specialText, "DELETE " + nodeName, Icons.Delete)) { node.Delete(); // View will be refreshed in parent's ChildrenChanged event // Special case: PartGraph is currently shown if (Parent is GuiVesselsPartGraphNode) { GuiVesselsPartGraphNode pgn = (GuiVesselsPartGraphNode)Parent; if (pgn.Parent is Canvas) { Canvas cnv = (Canvas)pgn.Parent; foreach (var line in pgn.Lines) { cnv.Children.Remove(line); } cnv.Children.Remove(pgn); } } } }