private async Task RefreshLimitModifiers(NotifyCollectionChangedEventArgs e = null)
        {
            string strSelectedId = (await treLimit.DoThreadSafeFuncAsync(x => x.SelectedNode?.Tag) as IHasInternalId)?.InternalId ?? string.Empty;

            TreeNode[] aobjLimitNodes = new TreeNode[(int)LimitType.NumLimitTypes];

            if (e == null)
            {
                await treLimit.DoThreadSafeAsync(x => x.Nodes.Clear());

                // Add Limit Modifiers.
                foreach (LimitModifier objLimitModifier in _objCharacter.LimitModifiers)
                {
                    int      intTargetLimit = (int)Enum.Parse(typeof(LimitType), objLimitModifier.Limit);
                    TreeNode objParentNode  = await GetLimitModifierParentNode(intTargetLimit);

                    await treLimit.DoThreadSafeAsync(() =>
                    {
                        if (!objParentNode.Nodes.ContainsKey(objLimitModifier.CurrentDisplayName))
                        {
                            objParentNode.Nodes.Add(objLimitModifier.CreateTreeNode(
                                                        objLimitModifier.CanDelete
                                                            ? cmsLimitModifier
                                                            : cmsLimitModifierNotesOnly));
                        }
                    });
                }

                // Add Limit Modifiers from Improvements
                foreach (Improvement objImprovement in _objCharacter.Improvements.Where(objImprovement => objImprovement.ImproveSource == Improvement.ImprovementSource.Custom))
                {
                    int intTargetLimit = -1;
                    switch (objImprovement.ImproveType)
                    {
                    case Improvement.ImprovementType.LimitModifier:
                        intTargetLimit = (int)Enum.Parse(typeof(LimitType), objImprovement.ImprovedName);
                        break;

                    case Improvement.ImprovementType.PhysicalLimit:
                        intTargetLimit = (int)LimitType.Physical;
                        break;

                    case Improvement.ImprovementType.MentalLimit:
                        intTargetLimit = (int)LimitType.Mental;
                        break;

                    case Improvement.ImprovementType.SocialLimit:
                        intTargetLimit = (int)LimitType.Social;
                        break;
                    }

                    if (intTargetLimit != -1)
                    {
                        TreeNode objParentNode = await GetLimitModifierParentNode(intTargetLimit);

                        string strName = objImprovement.UniqueName
                                         + await LanguageManager.GetStringAsync("String_Colon")
                                         + await LanguageManager.GetStringAsync("String_Space");

                        if (objImprovement.Value > 0)
                        {
                            strName += '+';
                        }
                        strName += objImprovement.Value.ToString(GlobalSettings.CultureInfo);
                        if (!string.IsNullOrEmpty(objImprovement.Condition))
                        {
                            strName += ',' + await LanguageManager.GetStringAsync("String_Space")
                                       + objImprovement.Condition;
                        }
                        await treLimit.DoThreadSafeAsync(() =>
                        {
                            if (!objParentNode.Nodes.ContainsKey(strName))
                            {
                                TreeNode objNode = new TreeNode
                                {
                                    Name             = strName,
                                    Text             = strName,
                                    Tag              = objImprovement.SourceName,
                                    ContextMenuStrip = cmsLimitModifierNotesOnly,
                                    ForeColor        = objImprovement.PreferredColor,
                                    ToolTipText      = objImprovement.Notes.WordWrap()
                                };
                                if (string.IsNullOrEmpty(objImprovement.ImprovedName))
                                {
                                    switch (objImprovement.ImproveType)
                                    {
                                    case Improvement.ImprovementType.SocialLimit:
                                        objImprovement.ImprovedName = "Social";
                                        break;

                                    case Improvement.ImprovementType.MentalLimit:
                                        objImprovement.ImprovedName = "Mental";
                                        break;

                                    default:
                                        objImprovement.ImprovedName = "Physical";
                                        break;
                                    }
                                }

                                objParentNode.Nodes.Add(objNode);
                            }
                        });
                    }
                }

                await treLimit.DoThreadSafeAsync(x => x.SortCustomAlphabetically(strSelectedId));
            }
            else
            {
                await treLimit.DoThreadSafeAsync(x =>
                {
                    aobjLimitNodes[0] = x.FindNode("Node_Physical", false);
                    aobjLimitNodes[1] = x.FindNode("Node_Mental", false);
                    aobjLimitNodes[2] = x.FindNode("Node_Social", false);
                    aobjLimitNodes[3] = x.FindNode("Node_Astral", false);
                });

                switch (e.Action)
                {
                case NotifyCollectionChangedAction.Add:
                {
                    foreach (LimitModifier objLimitModifier in e.NewItems)
                    {
                        int      intTargetLimit = (int)Enum.Parse(typeof(LimitType), objLimitModifier.Limit);
                        TreeNode objParentNode  = await GetLimitModifierParentNode(intTargetLimit);

                        await treLimit.DoThreadSafeAsync(x =>
                            {
                                TreeNodeCollection lstParentNodeChildren = objParentNode.Nodes;
                                if (!lstParentNodeChildren.ContainsKey(objLimitModifier.CurrentDisplayName))
                                {
                                    TreeNode objNode = objLimitModifier.CreateTreeNode(
                                        objLimitModifier.CanDelete ? cmsLimitModifier : cmsLimitModifierNotesOnly);
                                    int intNodesCount  = lstParentNodeChildren.Count;
                                    int intTargetIndex = 0;
                                    for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                                    {
                                        if (CompareTreeNodes.CompareText(
                                                lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                                        {
                                            break;
                                        }
                                    }

                                    lstParentNodeChildren.Insert(intTargetIndex, objNode);
                                    objParentNode.Expand();
                                    x.SelectedNode = objNode;
                                }
                            });
                    }

                    break;
                }

                case NotifyCollectionChangedAction.Remove:
                {
                    await treLimit.DoThreadSafeAsync(x =>
                        {
                            foreach (LimitModifier objLimitModifier in e.OldItems)
                            {
                                TreeNode objNode = x.FindNodeByTag(objLimitModifier);
                                if (objNode != null)
                                {
                                    TreeNode objParent = objNode.Parent;
                                    objNode.Remove();
                                    if (objParent.Level == 0 && objParent.Nodes.Count == 0)
                                    {
                                        objParent.Remove();
                                    }
                                }
                            }
                        });

                    break;
                }

                case NotifyCollectionChangedAction.Replace:
                {
                    List <TreeNode> lstOldParentNodes = new List <TreeNode>(e.OldItems.Count);
                    await treLimit.DoThreadSafeAsync(x =>
                        {
                            foreach (LimitModifier objLimitModifier in e.OldItems)
                            {
                                TreeNode objNode = x.FindNodeByTag(objLimitModifier);
                                if (objNode != null)
                                {
                                    lstOldParentNodes.Add(objNode.Parent);
                                    objNode.Remove();
                                }
                            }
                        });

                    foreach (LimitModifier objLimitModifier in e.NewItems)
                    {
                        int      intTargetLimit = (int)Enum.Parse(typeof(LimitType), objLimitModifier.Limit);
                        TreeNode objParentNode  = await GetLimitModifierParentNode(intTargetLimit);

                        await treLimit.DoThreadSafeAsync(x =>
                            {
                                TreeNodeCollection lstParentNodeChildren = objParentNode.Nodes;
                                if (!lstParentNodeChildren.ContainsKey(objLimitModifier.CurrentDisplayName))
                                {
                                    TreeNode objNode = objLimitModifier.CreateTreeNode(
                                        objLimitModifier.CanDelete ? cmsLimitModifier : cmsLimitModifierNotesOnly);
                                    int intNodesCount  = lstParentNodeChildren.Count;
                                    int intTargetIndex = 0;
                                    for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                                    {
                                        if (CompareTreeNodes.CompareText(
                                                lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                                        {
                                            break;
                                        }
                                    }

                                    lstParentNodeChildren.Insert(intTargetIndex, objNode);
                                    objParentNode.Expand();
                                    x.SelectedNode = objNode;
                                }
                            });
                    }

                    await treLimit.DoThreadSafeAsync(() =>
                        {
                            foreach (TreeNode objOldParentNode in lstOldParentNodes)
                            {
                                if (objOldParentNode.Level == 0 && objOldParentNode.Nodes.Count == 0)
                                {
                                    objOldParentNode.Remove();
                                }
                            }
                        });

                    break;
                }

                case NotifyCollectionChangedAction.Reset:
                {
                    await RefreshLimitModifiers();

                    break;
                }
                }
            }

            async ValueTask <TreeNode> GetLimitModifierParentNode(int intTargetLimit)
            {
                TreeNode objParentNode = aobjLimitNodes[intTargetLimit];

                if (objParentNode == null)
                {
                    switch (intTargetLimit)
                    {
                    case 0:
                        objParentNode = new TreeNode
                        {
                            Tag  = "Node_Physical",
                            Text = await LanguageManager.GetStringAsync("Node_Physical")
                        };
                        await treLimit.DoThreadSafeAsync(x => x.Nodes.Insert(0, objParentNode));

                        break;

                    case 1:
                        objParentNode = new TreeNode
                        {
                            Tag  = "Node_Mental",
                            Text = await LanguageManager.GetStringAsync("Node_Mental")
                        };
                        await treLimit.DoThreadSafeAsync(x => x.Nodes.Insert(aobjLimitNodes[0] == null ? 0 : 1, objParentNode));

                        break;

                    case 2:
                        objParentNode = new TreeNode
                        {
                            Tag  = "Node_Social",
                            Text = await LanguageManager.GetStringAsync("Node_Social")
                        };
                        await treLimit.DoThreadSafeAsync(x => x.Nodes.Insert((aobjLimitNodes[0] == null ? 0 : 1) + (aobjLimitNodes[1] == null ? 0 : 1), objParentNode));

                        break;

                    case 3:
                        objParentNode = new TreeNode
                        {
                            Tag  = "Node_Astral",
                            Text = await LanguageManager.GetStringAsync("Node_Astral")
                        };
                        await treLimit.DoThreadSafeAsync(x => x.Nodes.Add(objParentNode));

                        break;
                    }

                    aobjLimitNodes[intTargetLimit] = objParentNode;
                    if (objParentNode != null)
                    {
                        await treLimit.DoThreadSafeAsync(() => objParentNode.Expand());
                    }
                }
                return(objParentNode);
            }
        }
        protected void RefreshLimitModifiers(NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs = null)
        {
            string strSelectedId = (treLimit.SelectedNode?.Tag as IHasInternalId)?.InternalId ?? string.Empty;

            TreeNode[] aobjLimitNodes = new TreeNode[(int)LimitType.NumLimitTypes];

            if (notifyCollectionChangedEventArgs == null)
            {
                treLimit.Nodes.Clear();

                // Add Limit Modifiers.
                foreach (LimitModifier objLimitModifier in _objCharacter.LimitModifiers)
                {
                    int      intTargetLimit = (int)Enum.Parse(typeof(LimitType), objLimitModifier.Limit);
                    TreeNode objParentNode  = GetLimitModifierParentNode(intTargetLimit);
                    if (!objParentNode.Nodes.ContainsKey(objLimitModifier.DisplayName))
                    {
                        objParentNode.Nodes.Add(objLimitModifier.CreateTreeNode(cmsLimitModifier));
                    }
                }

                // Add Limit Modifiers from Improvements
                foreach (Improvement objImprovement in _objCharacter.Improvements.Where(objImprovement => objImprovement.ImproveSource == Improvement.ImprovementSource.Custom))
                {
                    int intTargetLimit = -1;
                    switch (objImprovement.ImproveType)
                    {
                    case Improvement.ImprovementType.LimitModifier:
                        intTargetLimit = (int)Enum.Parse(typeof(LimitType), objImprovement.ImprovedName);
                        break;

                    case Improvement.ImprovementType.PhysicalLimit:
                        intTargetLimit = (int)LimitType.Physical;
                        break;

                    case Improvement.ImprovementType.MentalLimit:
                        intTargetLimit = (int)LimitType.Mental;
                        break;

                    case Improvement.ImprovementType.SocialLimit:
                        intTargetLimit = (int)LimitType.Social;
                        break;
                    }
                    if (intTargetLimit != -1)
                    {
                        TreeNode objParentNode = GetLimitModifierParentNode(intTargetLimit);
                        string   strName       = objImprovement.UniqueName + ": ";
                        if (objImprovement.Value > 0)
                        {
                            strName += '+';
                        }
                        strName += objImprovement.Value.ToString();
                        if (!string.IsNullOrEmpty(objImprovement.Condition))
                        {
                            strName += ", " + objImprovement.Condition;
                        }
                        if (!objParentNode.Nodes.ContainsKey(strName))
                        {
                            TreeNode objNode = new TreeNode
                            {
                                Name             = strName,
                                Text             = strName,
                                Tag              = objImprovement.SourceName,
                                ContextMenuStrip = cmsLimitModifier,
                                ForeColor        = objImprovement.PreferredColor,
                                ToolTipText      = objImprovement.Notes.WordWrap(100)
                            };
                            if (string.IsNullOrEmpty(objImprovement.ImprovedName))
                            {
                                if (objImprovement.ImproveType == Improvement.ImprovementType.SocialLimit)
                                {
                                    objImprovement.ImprovedName = "Social";
                                }
                                else if (objImprovement.ImproveType == Improvement.ImprovementType.MentalLimit)
                                {
                                    objImprovement.ImprovedName = "Mental";
                                }
                                else
                                {
                                    objImprovement.ImprovedName = "Physical";
                                }
                            }

                            objParentNode.Nodes.Add(objNode);
                        }
                    }
                }

                treLimit.SortCustom(strSelectedId);
            }
            else
            {
                aobjLimitNodes[0] = treLimit.FindNode("Node_Physical", false);
                aobjLimitNodes[1] = treLimit.FindNode("Node_Mental", false);
                aobjLimitNodes[2] = treLimit.FindNode("Node_Social", false);
                aobjLimitNodes[3] = treLimit.FindNode("Node_Astral", false);

                switch (notifyCollectionChangedEventArgs.Action)
                {
                case NotifyCollectionChangedAction.Add:
                {
                    foreach (LimitModifier objLimitModifier in notifyCollectionChangedEventArgs.NewItems)
                    {
                        int                intTargetLimit        = (int)Enum.Parse(typeof(LimitType), objLimitModifier.Limit);
                        TreeNode           objParentNode         = GetLimitModifierParentNode(intTargetLimit);
                        TreeNodeCollection lstParentNodeChildren = objParentNode.Nodes;
                        if (!lstParentNodeChildren.ContainsKey(objLimitModifier.DisplayName))
                        {
                            TreeNode objNode        = objLimitModifier.CreateTreeNode(cmsLimitModifier);
                            int      intNodesCount  = lstParentNodeChildren.Count;
                            int      intTargetIndex = 0;
                            for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                            {
                                if (CompareTreeNodes.CompareText(lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                                {
                                    break;
                                }
                            }
                            lstParentNodeChildren.Insert(intTargetIndex, objNode);
                            objParentNode.Expand();
                            treLimit.SelectedNode = objNode;
                        }
                    }
                }
                break;

                case NotifyCollectionChangedAction.Remove:
                {
                    foreach (LimitModifier objLimitModifier in notifyCollectionChangedEventArgs.OldItems)
                    {
                        TreeNode objNode = treLimit.FindNodeByTag(objLimitModifier);
                        if (objNode != null)
                        {
                            TreeNode objParent = objNode.Parent;
                            objNode.Remove();
                            if (objParent.Level == 0 && objParent.Nodes.Count == 0)
                            {
                                objParent.Remove();
                            }
                        }
                    }
                }
                break;

                case NotifyCollectionChangedAction.Replace:
                {
                    List <TreeNode> lstOldParentNodes = new List <TreeNode>();
                    foreach (LimitModifier objLimitModifier in notifyCollectionChangedEventArgs.OldItems)
                    {
                        TreeNode objNode = treLimit.FindNodeByTag(objLimitModifier);
                        if (objNode != null)
                        {
                            lstOldParentNodes.Add(objNode.Parent);
                            objNode.Remove();
                        }
                    }
                    foreach (LimitModifier objLimitModifier in notifyCollectionChangedEventArgs.NewItems)
                    {
                        int                intTargetLimit        = (int)Enum.Parse(typeof(LimitType), objLimitModifier.Limit);
                        TreeNode           objParentNode         = GetLimitModifierParentNode(intTargetLimit);
                        TreeNodeCollection lstParentNodeChildren = objParentNode.Nodes;
                        if (!lstParentNodeChildren.ContainsKey(objLimitModifier.DisplayName))
                        {
                            TreeNode objNode        = objLimitModifier.CreateTreeNode(cmsLimitModifier);
                            int      intNodesCount  = lstParentNodeChildren.Count;
                            int      intTargetIndex = 0;
                            for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                            {
                                if (CompareTreeNodes.CompareText(lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                                {
                                    break;
                                }
                            }
                            lstParentNodeChildren.Insert(intTargetIndex, objNode);
                            objParentNode.Expand();
                            treLimit.SelectedNode = objNode;
                        }
                    }
                    foreach (TreeNode objOldParentNode in lstOldParentNodes)
                    {
                        if (objOldParentNode.Level == 0 && objOldParentNode.Nodes.Count == 0)
                        {
                            objOldParentNode.Remove();
                        }
                    }
                }
                break;

                case NotifyCollectionChangedAction.Reset:
                {
                    RefreshLimitModifiers();
                }
                break;
                }
            }

            TreeNode GetLimitModifierParentNode(int intTargetLimit)
            {
                TreeNode objParentNode = aobjLimitNodes[intTargetLimit];

                if (objParentNode == null)
                {
                    switch (intTargetLimit)
                    {
                    case 0:
                        objParentNode = new TreeNode()
                        {
                            Tag  = "Node_Physical",
                            Text = LanguageManager.GetString("Node_Physical", GlobalOptions.Language)
                        };
                        treLimit.Nodes.Insert(0, objParentNode);
                        break;

                    case 1:
                        objParentNode = new TreeNode()
                        {
                            Tag  = "Node_Mental",
                            Text = LanguageManager.GetString("Node_Mental", GlobalOptions.Language)
                        };
                        treLimit.Nodes.Insert(aobjLimitNodes[0] == null ? 0 : 1, objParentNode);
                        break;

                    case 2:
                        objParentNode = new TreeNode()
                        {
                            Tag  = "Node_Social",
                            Text = LanguageManager.GetString("Node_Social", GlobalOptions.Language)
                        };
                        treLimit.Nodes.Insert((aobjLimitNodes[0] == null ? 0 : 1) + (aobjLimitNodes[1] == null ? 0 : 1), objParentNode);
                        break;

                    case 3:
                        objParentNode = new TreeNode()
                        {
                            Tag  = "Node_Astral",
                            Text = LanguageManager.GetString("Node_Astral", GlobalOptions.Language)
                        };
                        treLimit.Nodes.Add(objParentNode);
                        break;
                    }
                    objParentNode?.Expand();
                }
                return(objParentNode);
            }
        }
Esempio n. 3
0
 /// <summary>
 /// Initializes the binary tree using the supplied comparison routine
 /// </summary>
 /// <param name="compareRoutine"></param>
 public BinaryTree(CompareTreeNodes compareRoutine)
 {
     this.compareRoutine = compareRoutine;
 }