private Image GenerateTraitImage(KmlKerbal kerbal) { Image image = new Image(); image.Height = 16; if (kerbal.Trait.ToLower() == "pilot") { image.Source = Icons16.KerbalPilot.Source; } else if (kerbal.Trait.ToLower() == "engineer") { image.Source = Icons16.KerbalEngineer.Source; } else if (kerbal.Trait.ToLower() == "scientist") { image.Source = Icons16.KerbalScience.Source; } else if (kerbal.Trait.ToLower() == "tourist") { image.Source = Icons16.KerbalCamera.Source; } else { image.Source = Icons16.Ghost.Source; } image.Margin = new Thickness(0, -24, 0, 0); return(image); }
private void KerbalsList_SelectionChanged(object sender, SelectionChangedEventArgs e) { // Store currently selected attribute, in case we just unselect + select the current item to refresh if (KerbalsList.SelectedItem == null) { // We're unselcting, this is the old data we want to restore in future call of this event GuiTreeAttrib attrib = (KerbalsDetails.SelectedItem as GuiTreeAttrib); if (attrib == null) { _oldSelectedAttrib = null; _alternativeSelectedAttrib = null; } else { _oldSelectedAttrib = attrib.DataAttrib; int i = KerbalsDetails.SelectedIndex; if (i < KerbalsDetails.Items.Count - 1) { _alternativeSelectedAttrib = (KerbalsDetails.Items[i + 1] as GuiTreeAttrib).DataAttrib; } else if (i > 0) { _alternativeSelectedAttrib = (KerbalsDetails.Items[i - 1] as GuiTreeAttrib).DataAttrib; } else { _alternativeSelectedAttrib = null; } } } KerbalsDetails.Items.Clear(); if (KerbalsList.SelectedItem != null) { GuiKerbalsNode Node = (GuiKerbalsNode)KerbalsList.SelectedItem; KerbalsDetails.ContextMenu = Node.ContextMenu; foreach (KmlAttrib attrib in Node.DataKerbal.Attribs) { KerbalsDetails.Items.Add(new GuiTreeAttrib(attrib)); } _oldSelectedKerbal = Node.DataKerbal; // Restore attrib selection if (Node.DataKerbal == _oldSelectedKerbal && _oldSelectedAttrib != null) { if (!Select(_oldSelectedAttrib)) { Select(_alternativeSelectedAttrib); } if (KerbalsDetails.SelectedItem != null) { (KerbalsDetails.SelectedItem as ListViewItem).Focus(); } } } else { KerbalsDetails.ContextMenu = null; } }
private TextBlock GenerateText(KmlKerbal kerbal) { TextBlock text = new TextBlock(); text.Inlines.Add(new Bold(new Run(kerbal.Name))); text.Inlines.Add(new Run("\n" + kerbal.Type + "\n" + kerbal.Trait)); text.Margin = new Thickness(3, 0, 0, 0); return(text); }
private void KerbalSelectAssignedPart_Click(object sender, RoutedEventArgs e) { KmlKerbal kerbal = (sender as MenuItem).DataContext as KmlKerbal; if (kerbal.AssignedPart != null) { GuiTabsManager.GetCurrent().Select(kerbal.AssignedPart); } }
private static List <KmlItem> ParseFile(System.IO.StreamReader file, KmlNode parent) { List <KmlItem> list = new List <KmlItem>(); string line; while ((line = file.ReadLine()) != null) { KmlItem newItem = ParseLine(line); if (newItem is KmlBegin) { KmlItem lastItem; int l = list.Count - 1; if (l < 0) { lastItem = new KmlItem(""); } else { lastItem = list[l]; list.RemoveAt(l); } KmlNode newNode = new KmlNode(lastItem, parent); if (newNode.Tag.ToLower() == "vessel") { newNode = new KmlVessel(newNode); } else if (newNode.Tag.ToLower() == "kerbal") { newNode = new KmlKerbal(newNode); } else if (newNode.Tag.ToLower() == "part") { newNode = new KmlPart(newNode); } else if (newNode.Tag.ToLower() == "resource") { newNode = new KmlResource(newNode); } list.Add(newNode); newNode.AddRange(ParseFile(file, newNode)); } else if (newItem is KmlEnd) { Identify(list); return(list); } else { list.Add(newItem); } } Identify(list); return(list); }
/// <summary> /// Creates a GuiKerbalsNode containing the given DataKerbal. /// To have nice icons in the tree, a GuiIcons can be /// provided. /// </summary> /// <param name="dataKerbal">The KmlKerbal to contain</param> public GuiKerbalsNode(KmlKerbal dataKerbal) { DataKerbal = dataKerbal; AssignTemplate(); BuildContextMenu(); // Get notified when KmlNode ToString() changes DataKerbal.ToStringChanged += DataKerbal_ToStringChanged; }
/// <summary> /// Creates a GuiKerbalsNode containing the given DataKerbal. /// To have nice icons in the tree, a GuiIcons can be /// provided. /// </summary> /// <param name="dataKerbal">The KmlKerbal to contain</param> public GuiKerbalsNode(KmlKerbal dataKerbal) { DataKerbal = dataKerbal; BaseGuiNode = new GuiTreeNode(DataKerbal, true, true, true, false, true, false); AssignTemplate(); BuildContextMenu(); // Get notified when KmlNode ToString() changes DataKerbal.ToStringChanged += DataKerbal_ToStringChanged; // Get notified when attributes are added / deleted DataKerbal.AttribChanged += DataKerbal_AttribChanged; }
private void KerbalSendHome_Click(object sender, RoutedEventArgs e) { KmlKerbal kerbal = (sender as MenuItem).DataContext as KmlKerbal; if (DlgConfirmation.Show("Do you really want to send " + kerbal.Name + " home to astronaut complex?\n\n" + "- The kerbal will be removed from assigned crew part\n" + "- State will be set to 'Available'\n" + "- Experience or contract progress may get lost", "Send home kerbal", (sender as MenuItem).Icon as Image)) { kerbal.SendHome(); } }
private void KerbalsChanged(object sender, RoutedEventArgs e) { // Kerbal was added or deleted KmlKerbal oldSelected = null; if (KerbalsList.SelectedItem is GuiKerbalsNode) { oldSelected = (KerbalsList.SelectedItem as GuiKerbalsNode).DataKerbal; } Load(Master.TreeManager); if (oldSelected != null) { Select(oldSelected); } }
private TextBlock GenerateStateText(KmlKerbal kerbal, TextBlock previous) { previous.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); previous.Arrange(new Rect(previous.DesiredSize)); string s = "\n" + kerbal.State; if (kerbal.AssignedVessel != null) { s += "\n" + kerbal.AssignedVessel.Name; } TextBlock text = new TextBlock(new Run(s)); text.Margin = new Thickness(-previous.ActualWidth + 100, 0, 0, 0); return(text); }
/// <summary> /// After all items are loaded, each items Finalize is called. /// The roots list will contain all loaded items in KML tree structure. /// Each item can then check for other items to get further properties. /// </summary> /// <param name="roots">The loaded root items list</param> protected override void Finalize(List <KmlItem> roots) { base.Finalize(roots); if (Origin == VesselOrigin.Flightstate) { AssignedCrew.Clear(); string[] tags = { "game", "roster" }; KmlNode rosterNode = GetNodeFromDeep(roots, tags); if (rosterNode != null) { foreach (KmlPart part in Parts) { foreach (KmlAttrib attrib in part.Attribs) { if (attrib.Name.ToLower() == "crew" && attrib.Value.Length > 0) { int oldCrewCount = AssignedCrew.Count; foreach (KmlNode kerbalNode in rosterNode.Children) { if (kerbalNode is KmlKerbal) { KmlKerbal kerbal = (KmlKerbal)kerbalNode; if (attrib.Value.ToLower() == kerbal.Name.ToLower()) { // Duplicate entries are checked on the kerbal side, // here only duplicates within one vessel could be checked, // there all vessels are checked AssignedCrew.Add(kerbal); } } } if (AssignedCrew.Count < oldCrewCount + 1) { Syntax.Warning(attrib, "Crew could not be assigned, this kerbal does not exist: " + attrib.Value); } else if (AssignedCrew.Count > oldCrewCount + 1) { Syntax.Warning(attrib, "Crew member not unique, there are multiple kerbals with name: " + attrib.Value); } } } } } } }
private Image GenerateImage(KmlKerbal kerbal) { Image image = new Image(); image.Height = 48; if (kerbal.Type.ToLower() == "applicant") { image.Source = Icons48.KerbalApplicant.Source; } else if (kerbal.Type.ToLower() == "tourist") { image.Source = Icons48.KerbalTourist.Source; } else { image.Source = Icons48.Kerbal.Source; } image.Margin = new Thickness(0, 0, 3, 0); return(image); }
private static KmlNode ParseNode(KmlItem item) { KmlNode newNode = new KmlNode(item); if (newNode.Tag.ToLower() == "vessel") { newNode = new KmlVessel(newNode); } else if (newNode.Tag.ToLower() == "kerbal") { newNode = new KmlKerbal(newNode); } else if (newNode.Tag.ToLower() == "part") { newNode = new KmlPart(newNode); } else if (newNode.Tag.ToLower() == "resource") { newNode = new KmlResource(newNode); } return(newNode); }
/// <summary> /// Selects the given item in the tree view or in the list, the item fits into. /// If called when tree is active it will switch to the list when possible. /// Otherwise when list is active it will switch to the tree view. /// </summary> /// <param name="item">The KmlItem to select</param> /// <returns>Whether item was found or not</returns> public bool Select(KmlItem item) { if (item is KmlVessel) { KmlVessel vessel = (KmlVessel)item; if (Tabs.SelectedItem == TreeTab && vessel.Origin == KmlVessel.VesselOrigin.Flightstate) { Tabs.SelectedItem = VesselsTab; return(VesselsManager.Select(vessel)); } else { Tabs.SelectedItem = TreeTab; return(TreeManager.Select(vessel)); } } else if (item is KmlKerbal) { KmlKerbal kerbal = (KmlKerbal)item; if (Tabs.SelectedItem == TreeTab && kerbal.Origin == KmlKerbal.KerbalOrigin.Roster) { Tabs.SelectedItem = KerbalsTab; return(KerbalsManager.Select(kerbal)); } else { Tabs.SelectedItem = TreeTab; return(TreeManager.Select(kerbal)); } } else { Tabs.SelectedItem = TreeTab; return(TreeManager.Select(item)); } }
private void KerbalsChanged(object sender, RoutedEventArgs e) { // Kerbal was added or deleted KmlKerbal oldSelected = null; KmlKerbal alternateSelected = null; if (KerbalsList.SelectedItem is GuiKerbalsNode) { oldSelected = (KerbalsList.SelectedItem as GuiKerbalsNode).DataKerbal; int i = KerbalsList.SelectedIndex + 1; while (i < KerbalsList.Items.Count && !(KerbalsList.Items[i] as GuiKerbalsNode).IsVisible) { i++; } if (i >= KerbalsList.Items.Count) { i = KerbalsList.SelectedIndex - 1; while (i >= 0 && !(KerbalsList.Items[i] as GuiKerbalsNode).IsVisible) { i--; } } if (i >= 0) { alternateSelected = (KerbalsList.Items[i] as GuiKerbalsNode).DataKerbal; } } Load(Master.TreeManager); if (oldSelected != null) { if (!Select(oldSelected) && alternateSelected != null) { Select(alternateSelected); } } }
private Image GenerateImage(KmlNode node) { Image image = new Image(); image.Height = 16; if (node is KmlVessel) { KmlVessel vessel = (KmlVessel)node; if (vessel.Type.ToLower() == "base") { image.Source = Icons.VesselBase.Source; } else if (vessel.Type.ToLower() == "debris") { image.Source = Icons.VesselDebris.Source; } else if (vessel.Type.ToLower() == "eva") { image.Source = Icons.VesselEVA.Source; } else if (vessel.Type.ToLower() == "flag") { image.Source = Icons.VesselFlag.Source; } else if (vessel.Type.ToLower() == "lander") { image.Source = Icons.VesselLander.Source; } else if (vessel.Type.ToLower() == "probe") { image.Source = Icons.VesselProbe.Source; } else if (vessel.Type.ToLower() == "spaceobject") { image.Source = Icons.VesselSpaceObject.Source; } else if (vessel.Type.ToLower() == "station") { image.Source = Icons.VesselStation.Source; } else if (vessel.Type.ToLower() == "rover") { image.Source = Icons.VesselRover.Source; } else { image.Source = Icons.Vessel.Source; } } else if (node is KmlPartDock) { KmlPartDock dock = (KmlPartDock)node; if (dock.DockType == KmlPartDock.DockTypes.Grapple) { image.Source = Icons.PartGrapple.Source; } else { image.Source = Icons.PartDock.Source; } } else if (node is KmlPart) { image.Source = Icons.Part.Source; } else if (node is KmlResource) { image.Source = Icons.Resource.Source; } else if (node is KmlKerbal) { KmlKerbal kerbal = (KmlKerbal)node; if (kerbal.Type.ToLower() == "applicant") { image.Source = Icons.KerbalApplicant.Source; } else if (kerbal.Type.ToLower() == "tourist") { image.Source = Icons.KerbalTorist.Source; } else { image.Source = Icons.Kerbal.Source; } } else if (node is KmlGhostNode) { image.Source = Icons.Ghost.Source; } else { image.Source = Icons.Node.Source; } image.Margin = new Thickness(0, 0, 3, 0); return(image); }
private string GenerateText(KmlKerbal kerbal) { return(kerbal.Name + "\n " + kerbal.Type + "\n " + kerbal.Trait); }
private void BuildContextMenu(bool withAddMenu, bool withDeleteMenu) { ContextMenu menu = new ContextMenu(); MenuItem title = new MenuItem(); Image img = GenerateImage(DataNode); img.Margin = new Thickness(0); title.Icon = img; title.Header = DataNode.ToString(); title.IsEnabled = false; title.Background = new SolidColorBrush(Colors.Black); title.BorderThickness = new Thickness(1); title.BorderBrush = new SolidColorBrush(Colors.Gray); menu.Items.Add(title); menu.Items.Add(new Separator()); // So far it's the default Menu, wich should not be shown if no items follow int defaultMenuCount = menu.Items.Count; // Give menu item a more descriptive name string nodeName = "node"; if (DataNode is KmlResource) { nodeName = "resource"; MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill this resource"; m.Click += ResourceRefill_Click; menu.Items.Add(m); } else if (DataNode is KmlPart) { nodeName = "part"; KmlPart node = (KmlPart)DataNode; if (node.HasResources) { MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill all resources in this part"; m.Click += PartRefill_Click; menu.Items.Add(m); foreach (string resType in node.ResourceTypes) { m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill '" + resType + "' resource in this part"; m.Tag = resType; m.Click += PartRefill_Click; menu.Items.Add(m); } } if (node is KmlPartDock) { KmlPartDock dock = (KmlPartDock)node; if (dock.NeedsRepair) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.PartDock); m.Header = "Re_pair docking connection of this and connected part"; m.Click += DockRepair_Click; menu.Items.Add(m); } } } else if (DataNode is KmlVessel) { nodeName = "vessel"; KmlVessel node = (KmlVessel)DataNode; MenuItem m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(DataNode); img.Margin = new Thickness(0); m.Icon = img; m.Header = "S_witch view"; m.Click += SwitchView_Click; menu.Items.Add(m); menu.Items.Add(new Separator()); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.VesselSpaceObject); m.Header = "Send to _low kerbin orbit"; m.Click += VesselToLKO_Click; menu.Items.Add(m); if (node.HasResources) { menu.Items.Add(new Separator()); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill all resources in all parts of this vessel"; m.Click += VesselRefill_Click; menu.Items.Add(m); foreach (string resType in node.ResourceTypes) { m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill all '" + resType + "' resources in all parts of this vessel"; m.Tag = resType; m.Click += VesselRefill_Click; menu.Items.Add(m); } } if (node.Flags.Count > 0) { menu.Items.Add(new Separator()); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.VesselFlag); m.Header = "Change _flag in all parts of this vessel..."; m.Click += VesselFlagExchange_Click; menu.Items.Add(m); } } else if (DataNode is KmlKerbal) { nodeName = "kerbal"; KmlKerbal node = (KmlKerbal)DataNode; MenuItem m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(DataNode); img.Margin = new Thickness(0); m.Icon = img; m.Header = "S_witch view"; m.Click += SwitchView_Click; menu.Items.Add(m); if (node.AssignedVessel != null || node.AssignedPart != null) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } if (node.AssignedVessel != null) { m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(node.AssignedVessel); img.Margin = new Thickness(0); m.Icon = img; m.Header = "Select assigned _vessel: " + node.AssignedVessel.Name; m.Click += KerbalSelectAssignedVessel_Click; menu.Items.Add(m); } if (node.AssignedPart != null) { m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(node.AssignedPart); img.Margin = new Thickness(0); m.Icon = img; m.Header = "Select assigned _part: " + node.AssignedPart.Name; m.Click += KerbalSelectAssignedPart_Click; menu.Items.Add(m); } } if (node.AssignedVessel != null || node.AssignedPart != null || node.State.ToLower() == "missing") { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } m = new MenuItem(); m.DataContext = DataNode; img = Icons.CreateImage(Icons.VesselSpaceObject); m.Icon = img; m.Header = "Send _home to astronaut complex"; m.Click += KerbalSendHome_Click; menu.Items.Add(m); } } // Adding / deleting if (withAddMenu) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Add); m.Header = "Add _attribute..."; m.Click += NodeAddAttrib_Click; menu.Items.Add(m); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Add); m.Header = "Add _child node..."; m.Click += NodeAddChild_Click; menu.Items.Add(m); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Add); m.Header = "_Insert node..."; m.Click += NodeInsertBefore_Click; m.IsEnabled = DataNode.Parent != null; menu.Items.Add(m); } if (withDeleteMenu) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Delete); m.Header = "_Delete this " + nodeName + "..."; m.Click += NodeDelete_Click; m.IsEnabled = DataNode.CanBeDeleted; menu.Items.Add(m); } // Need to have a seperate menu for each item, even if it is empty. // If ContextMenu is null, the parent's contextmenu will be used (WTF). // Item[0] is the menu title, Item[1] a Seperator, both always created. ContextMenu = menu; if (menu.Items.Count <= defaultMenuCount) { ContextMenu.Visibility = System.Windows.Visibility.Hidden; } else { // Apply look and feel foreach (object o in menu.Items) { if (o is MenuItem) { MenuItem m = (MenuItem)o; if (!m.IsEnabled && m.Icon != null) { (m.Icon as Image).Opacity = 0.3; } } } } }