public void AddComponent_ReturnsFirstAddedComponent_WhenComponentAddedTwice() { // Arrange var testInputTargetType = ThemeComponentType.TextColor; var testInputComponentName = "testComponent"; var testInputColor = new Color(); var componentCollection = new ThemeComponentCollection(); // Act var firstResult = componentCollection.AddComponent(testInputTargetType, testInputComponentName, testInputColor); var secondResult = componentCollection.AddComponent(testInputTargetType, testInputComponentName, testInputColor); // Assert Assert.AreSame(firstResult, secondResult); }
private T GetColorBlockItemFromString <T>(string inputString) where T : ColorBlockItem { var blockItem = Activator.CreateInstance <T>(); var result = Regex.Matches(inputString, @"([\w\s]*)[#]?(.*)"); blockItem.Color = GetColorFromString(result[0].Groups[1].Value); var componentName = result[0].Groups[2].Value.Trim(); if (!string.IsNullOrEmpty(componentName)) { ThemeComponentType componentType; if (typeof(T) == typeof(TextColorBlockItem)) { componentType = ThemeComponentType.TextColor; } else if (typeof(T) == typeof(BackgroundColorBlockItem)) { componentType = ThemeComponentType.BackgroundColor; } else if (typeof(T) == typeof(BorderColorBlockItem)) { componentType = ThemeComponentType.BorderColor; } else { throw new Exception("Parsing error - unknown theme component type"); } if (_masterComponentCollection != null) { blockItem.ThemeComponent = _masterComponentCollection.AddComponent(componentType, componentName, blockItem.Color); } } return(blockItem); }
// This method converts a string into a ItemFilterBlock. This is used for pasting ItemFilterBlocks // and reading ItemFilterScripts from a file. public IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScript parentItemFilterScript, string originalString = "", bool initialiseBlockGroupHierarchyBuilder = false) { if (initialiseBlockGroupHierarchyBuilder) { _blockGroupHierarchyBuilder.Initialise(parentItemFilterScript.ItemFilterBlockGroups.First()); } _masterComponentCollection = parentItemFilterScript.ItemFilterScriptSettings.ThemeComponentCollection; var block = new ItemFilterBlock(parentItemFilterScript); var showHideFound = false; block.OriginalText = originalString; foreach (var line in new LineReader(() => new StringReader(inputString))) { if (line.StartsWith(@"#")) { if (!showHideFound) { block.Description = line.TrimStart('#').TrimStart(' '); } else { if (block.BlockItems.Count > 1) { block.BlockItems.Last().Comment += Environment.NewLine + line.TrimStart('#'); } else { block.ActionBlockItem.Comment += Environment.NewLine + line.TrimStart('#'); } } continue; } var fullLine = line.Trim(); var trimmedLine = fullLine; var blockComment = ""; var themeComponentType = -1; if (trimmedLine.IndexOf('#') > 0) { blockComment = trimmedLine.Substring(trimmedLine.IndexOf('#') + 1); trimmedLine = trimmedLine.Substring(0, trimmedLine.IndexOf('#')).Trim(); } var spaceOrEndOfLinePos = trimmedLine.IndexOf(" ", StringComparison.Ordinal) > 0 ? trimmedLine.IndexOf(" ", StringComparison.Ordinal) : trimmedLine.Length; var lineOption = trimmedLine.Substring(0, spaceOrEndOfLinePos); switch (lineOption) { case "Show": case "Hide": case "ShowDisabled": case "HideDisabled": { showHideFound = true; block.Action = lineOption.StartsWith("Show") ? BlockAction.Show : BlockAction.Hide; block.Enabled = !lineOption.EndsWith("Disabled"); // If block groups are enabled for this script, the comment after Show/Hide is parsed as a block // group hierarchy, if block groups are disabled it is preserved as a simple text comment. if (parentItemFilterScript.ItemFilterScriptSettings.BlockGroupsEnabled) { AddBlockGroupToBlock(block, fullLine); } else { block.ActionBlockItem.Comment = GetTextAfterFirstComment(fullLine); } break; } case "ItemLevel": { AddNumericFilterPredicateItemToBlockItems <ItemLevelBlockItem>(block, trimmedLine); break; } case "DropLevel": { AddNumericFilterPredicateItemToBlockItems <DropLevelBlockItem>(block, trimmedLine); break; } case "Quality": { AddNumericFilterPredicateItemToBlockItems <QualityBlockItem>(block, trimmedLine); break; } case "Rarity": { RemoveExistingBlockItemsOfType <RarityBlockItem>(block); var blockItemValue = new RarityBlockItem(); var result = Regex.Match(trimmedLine, @"^\w+\s+([><!=]{0,2})\s*(\w+)$"); if (result.Groups.Count == 3) { blockItemValue.FilterPredicate.PredicateOperator = EnumHelper.GetEnumValueFromDescription <FilterPredicateOperator>(string.IsNullOrEmpty(result.Groups[1].Value) ? "=" : result.Groups[1].Value); blockItemValue.FilterPredicate.PredicateOperand = (int)EnumHelper.GetEnumValueFromDescription <ItemRarity>(result.Groups[2].Value); } block.BlockItems.Add(blockItemValue); break; } case "Class": { AddStringListItemToBlockItems <ClassBlockItem>(block, trimmedLine); break; } case "BaseType": { AddStringListItemToBlockItems <BaseTypeBlockItem>(block, trimmedLine); break; } case "Prophecy": { AddStringListItemToBlockItems <ProphecyBlockItem>(block, trimmedLine); break; } case "Corrupted": { AddBooleanItemToBlockItems <CorruptedBlockItem>(block, trimmedLine); break; } case "Identified": { AddBooleanItemToBlockItems <IdentifiedBlockItem>(block, trimmedLine); break; } case "ElderItem": { AddBooleanItemToBlockItems <ElderItemBlockItem>(block, trimmedLine); break; } case "ShaperItem": { AddBooleanItemToBlockItems <ShaperItemBlockItem>(block, trimmedLine); break; } case "ShapedMap": { AddBooleanItemToBlockItems <ShapedMapBlockItem>(block, trimmedLine); break; } case "Sockets": { AddNumericFilterPredicateItemToBlockItems <SocketsBlockItem>(block, trimmedLine); break; } case "LinkedSockets": { AddNumericFilterPredicateItemToBlockItems <LinkedSocketsBlockItem>(block, trimmedLine); break; } case "Width": { AddNumericFilterPredicateItemToBlockItems <WidthBlockItem>(block, trimmedLine); break; } case "Height": { AddNumericFilterPredicateItemToBlockItems <HeightBlockItem>(block, trimmedLine); break; } case "SocketGroup": { AddStringListItemToBlockItems <SocketGroupBlockItem>(block, trimmedLine); break; } case "SetTextColor": { // Only ever use the last SetTextColor item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <TextColorBlockItem>(block); var result = Regex.Matches(trimmedLine, @"([\w\s]*)"); var blockItem = new TextColorBlockItem { Color = GetColorFromString(result[0].Groups[1].Value) }; block.BlockItems.Add(blockItem); themeComponentType = (int)ThemeComponentType.TextColor; break; } case "SetBackgroundColor": { // Only ever use the last SetBackgroundColor item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <BackgroundColorBlockItem>(block); var result = Regex.Matches(trimmedLine, @"([\w\s]*)"); var blockItem = new BackgroundColorBlockItem { Color = GetColorFromString(result[0].Groups[1].Value) }; block.BlockItems.Add(blockItem); themeComponentType = (int)ThemeComponentType.BackgroundColor; break; } case "SetBorderColor": { // Only ever use the last SetBorderColor item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <BorderColorBlockItem>(block); var result = Regex.Matches(trimmedLine, @"([\w\s]*)"); var blockItem = new BorderColorBlockItem { Color = GetColorFromString(result[0].Groups[1].Value) }; block.BlockItems.Add(blockItem); themeComponentType = (int)ThemeComponentType.BorderColor; break; } case "SetFontSize": { // Only ever use the last SetFontSize item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <FontSizeBlockItem>(block); var match = Regex.Matches(trimmedLine, @"(\s+(\d+)\s*)"); if (match.Count > 0) { var blockItem = new FontSizeBlockItem(Convert.ToInt16(match[0].Groups[2].Value)); block.BlockItems.Add(blockItem); themeComponentType = (int)ThemeComponentType.FontSize; } break; } case "PlayAlertSound": case "PlayAlertSoundPositional": { // Only ever use the last PlayAlertSound item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <SoundBlockItem>(block); RemoveExistingBlockItemsOfType <PositionalSoundBlockItem>(block); RemoveExistingBlockItemsOfType <CustomSoundBlockItem>(block); var match = Regex.Match(trimmedLine, @"\S+\s+(\S+)\s?(\d+)?"); if (match.Success) { string firstValue = match.Groups[1].Value; var secondValue = match.Groups[2].Success ? Convert.ToInt16(match.Groups[2].Value) : 79; if (lineOption == "PlayAlertSound") { var blockItemValue = new SoundBlockItem { Value = firstValue, SecondValue = secondValue }; block.BlockItems.Add(blockItemValue); } else { var blockItemValue = new PositionalSoundBlockItem { Value = firstValue, SecondValue = secondValue }; block.BlockItems.Add(blockItemValue); } themeComponentType = (int)ThemeComponentType.AlertSound; } break; } case "GemLevel": { AddNumericFilterPredicateItemToBlockItems <GemLevelBlockItem>(block, trimmedLine); break; } case "StackSize": { AddNumericFilterPredicateItemToBlockItems <StackSizeBlockItem>(block, trimmedLine); break; } case "HasExplicitMod": { AddStringListItemToBlockItems <HasExplicitModBlockItem>(block, trimmedLine); break; } case "ElderMap": { AddBooleanItemToBlockItems <ElderMapBlockItem>(block, trimmedLine); break; } case "DisableDropSound": { // Only ever use the last DisableDropSound item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <DisableDropSoundBlockItem>(block); AddNilItemToBlockItems <DisableDropSoundBlockItem>(block, trimmedLine); break; } case "MinimapIcon": { // Only ever use the last Icon item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <MapIconBlockItem>(block); // TODO: Get size, color, shape values programmatically var match = Regex.Match(trimmedLine, @"\S+\s+(0|1|2)\s+(Red|Green|Blue|Brown|White|Yellow)\s+(Circle|Diamond|Hexagon|Square|Star|Triangle)\s*([#]?)(.*)", RegexOptions.IgnoreCase); if (match.Success) { var blockItemValue = new MapIconBlockItem { Size = (IconSize)short.Parse(match.Groups[1].Value), Color = EnumHelper.GetEnumValueFromDescription <IconColor>(match.Groups[2].Value), Shape = EnumHelper.GetEnumValueFromDescription <IconShape>(match.Groups[3].Value) }; block.BlockItems.Add(blockItemValue); themeComponentType = (int)ThemeComponentType.Icon; } break; } case "PlayEffect": { // Only ever use the last BeamColor item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <PlayEffectBlockItem>(block); // TODO: Get colors programmatically var match = Regex.Match(trimmedLine, @"\S+\s+(Red|Green|Blue|Brown|White|Yellow)\s*(Temp)?", RegexOptions.IgnoreCase); if (match.Success) { var blockItemValue = new PlayEffectBlockItem { Color = EnumHelper.GetEnumValueFromDescription <EffectColor>(match.Groups[1].Value), Temporary = match.Groups[2].Value.Trim().ToLower() == "temp" }; block.BlockItems.Add(blockItemValue); themeComponentType = (int)ThemeComponentType.Effect; } break; } case "CustomAlertSound": { // Only ever use the last CustomSoundBlockItem item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType <CustomSoundBlockItem>(block); RemoveExistingBlockItemsOfType <SoundBlockItem>(block); RemoveExistingBlockItemsOfType <PositionalSoundBlockItem>(block); var match = Regex.Match(trimmedLine, @"\S+\s+""([^\*\<\>\?|]+)"""); if (match.Success) { var blockItemValue = new CustomSoundBlockItem { Value = match.Groups[1].Value }; block.BlockItems.Add(blockItemValue); themeComponentType = (int)ThemeComponentType.CustomSound; } break; } case "MapTier": { AddNumericFilterPredicateItemToBlockItems <MapTierBlockItem>(block, trimmedLine); break; } } if (!string.IsNullOrWhiteSpace(blockComment) && block.BlockItems.Count > 1) { if (!(block.BlockItems.Last() is IBlockItemWithTheme blockItemWithTheme)) { block.BlockItems.Last().Comment = blockComment; } else { switch ((ThemeComponentType)themeComponentType) { case ThemeComponentType.AlertSound: { ThemeComponent themeComponent; if (blockItemWithTheme is SoundBlockItem item) { themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.AlertSound, blockComment.Trim(), item.Value, item.SecondValue); } else { themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.AlertSound, blockComment.Trim(), ((PositionalSoundBlockItem)blockItemWithTheme).Value, ((PositionalSoundBlockItem)blockItemWithTheme).SecondValue); } blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.BackgroundColor: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.BackgroundColor, blockComment.Trim(), ((BackgroundColorBlockItem)blockItemWithTheme).Color); blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.BorderColor: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.BorderColor, blockComment.Trim(), ((BorderColorBlockItem)blockItemWithTheme).Color); blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.CustomSound: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.CustomSound, blockComment.Trim(), ((CustomSoundBlockItem)blockItemWithTheme).Value); blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.Effect: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.Effect, blockComment.Trim(), ((EffectColorBlockItem)blockItemWithTheme).Color, ((EffectColorBlockItem)blockItemWithTheme).Temporary); blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.FontSize: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.FontSize, blockComment.Trim(), ((FontSizeBlockItem)blockItemWithTheme).Value); blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.Icon: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.Icon, blockComment.Trim(), ((IconBlockItem)blockItemWithTheme).Size, ((IconBlockItem)blockItemWithTheme).Color, ((IconBlockItem)blockItemWithTheme).Shape); blockItemWithTheme.ThemeComponent = themeComponent; break; } case ThemeComponentType.TextColor: { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.TextColor, blockComment.Trim(), ((TextColorBlockItem)blockItemWithTheme).Color); blockItemWithTheme.ThemeComponent = themeComponent; break; } } } } }
public void ReplaceAudioVisualBlockItemsFromString(ObservableCollection <IItemFilterBlockItem> blockItems, string inputString) { // Reverse iterate to remove existing IAudioVisualBlockItems for (var idx = blockItems.Count - 1; idx >= 0; idx--) { if (blockItems[idx] is IAudioVisualBlockItem) { blockItems.RemoveAt(idx); } } foreach (var line in new LineReader(() => new StringReader(inputString))) { var matches = Regex.Match(line, @"(\w+)"); var blockComment = ""; var trimmedLine = line.Trim(); if (trimmedLine.IndexOf('#') > 0) { blockComment = trimmedLine.Substring(trimmedLine.IndexOf('#') + 1); trimmedLine = trimmedLine.Substring(0, trimmedLine.IndexOf('#')).Trim(); } switch (matches.Value) { case "PlayAlertSound": { var match = Regex.Match(trimmedLine, @"\s+(\S+) (\d+)"); if (!match.Success) { break; } var blockItem = new SoundBlockItem(match.Groups[1].Value, Convert.ToInt16(match.Groups[2].Value)); if (_masterComponentCollection != null && !string.IsNullOrWhiteSpace(blockComment)) { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.AlertSound, blockComment, blockItem.Value, blockItem.SecondValue); blockItem.ThemeComponent = themeComponent; } blockItems.Add(blockItem); break; } case "SetTextColor": { var result = Regex.Matches(trimmedLine, @"([\w\s]*)"); var blockItem = new TextColorBlockItem(); blockItem.Color = GetColorFromString(result[0].Groups[1].Value); if (_masterComponentCollection != null && !string.IsNullOrWhiteSpace(blockComment)) { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.TextColor, blockComment, blockItem.Color); blockItem.ThemeComponent = themeComponent; } blockItems.Add(blockItem); break; } case "SetBackgroundColor": { var result = Regex.Matches(trimmedLine, @"([\w\s]*)"); var blockItem = new BackgroundColorBlockItem(); blockItem.Color = GetColorFromString(result[0].Groups[1].Value); if (_masterComponentCollection != null && !string.IsNullOrWhiteSpace(blockComment)) { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.BackgroundColor, blockComment, blockItem.Color); blockItem.ThemeComponent = themeComponent; } blockItems.Add(blockItem); break; } case "SetBorderColor": { var result = Regex.Matches(trimmedLine, @"([\w\s]*)"); var blockItem = new BorderColorBlockItem(); blockItem.Color = GetColorFromString(result[0].Groups[1].Value); if (_masterComponentCollection != null && !string.IsNullOrWhiteSpace(blockComment)) { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.BorderColor, blockComment, blockItem.Color); blockItem.ThemeComponent = themeComponent; } blockItems.Add(blockItem); break; } case "SetFontSize": { var match = Regex.Match(trimmedLine, @"\s+(\d+)"); if (!match.Success) { break; } var blockItem = new FontSizeBlockItem(Convert.ToInt16(match.Value)); if (_masterComponentCollection != null && !string.IsNullOrWhiteSpace(blockComment)) { ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.FontSize, blockComment, blockItem.Value); blockItem.ThemeComponent = themeComponent; } blockItems.Add(blockItem); break; } } } }