Пример #1
0
        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);
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        /// <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;
        }
Пример #7
0
        /// <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;
        }
Пример #8
0
        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();
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
 /// <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);
                         }
                     }
                 }
             }
         }
     }
 }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
 /// <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));
     }
 }
Пример #15
0
        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);
                }
            }
        }
Пример #16
0
        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);
        }
Пример #17
0
 private string GenerateText(KmlKerbal kerbal)
 {
     return(kerbal.Name + "\n " + kerbal.Type + "\n " + kerbal.Trait);
 }
Пример #18
0
        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;
                        }
                    }
                }
            }
        }