14 Commits
0.2 ... 0.3

83 changed files with 2776 additions and 1107 deletions

View File

@@ -46,13 +46,15 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Models\TestLootFilterBlock.cs" />
<Compile Include="Models\TestLootFilterScript.cs" />
<Compile Include="Models\TestItemFilterBlock.cs" />
<Compile Include="Models\TestItemFilterBlockGroup.cs" />
<Compile Include="Models\TestItemFilterScript.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\TestLootFilterPersistenceService.cs" />
<Compile Include="Services\TestItemFilterPersistenceService.cs" />
<Compile Include="Services\TestStaticDataService.cs" />
<Compile Include="Translators\TestLootFilterBlockTranslator.cs" />
<Compile Include="Translators\TestLootFilterScriptTranslator.cs" />
<Compile Include="Translators\TestBlockGroupHierarchyBuilder.cs" />
<Compile Include="Translators\TestItemFilterBlockTranslator.cs" />
<Compile Include="Translators\TestItemFilterScriptTranslator.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -70,7 +72,7 @@
<Content Include="Resources\testscript.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\ThioleLootFilter.txt">
<Content Include="Resources\ThioleItemFilter.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

View File

@@ -5,13 +5,13 @@ using NUnit.Framework;
namespace Filtration.Tests.Models
{
[TestFixture]
public class TestLootFilterBlock
public class TestItemFilterBlock
{
[Test]
public void LootFilterBlock_BlockCount_ReturnsCorrectNumber()
public void ItemFilterBlock_BlockCount_ReturnsCorrectNumber()
{
// Arrange
var block = new LootFilterBlock();
var block = new ItemFilterBlock();
block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem());
@@ -25,10 +25,10 @@ namespace Filtration.Tests.Models
}
[Test]
public void LootFilterBlock_AddBlockItemAllowed_LessThanMaximum_ReturnsTrue()
public void ItemFilterBlock_AddBlockItemAllowed_LessThanMaximum_ReturnsTrue()
{
// Arrange
var block = new LootFilterBlock();
var block = new ItemFilterBlock();
block.BlockItems.Add(new ItemLevelBlockItem());
// Act
@@ -39,10 +39,10 @@ namespace Filtration.Tests.Models
}
[Test]
public void LootFilterBlock_AddBlockItemAllowed_MoreThanMaximum_ReturnsFalse()
public void ItemFilterBlock_AddBlockItemAllowed_MoreThanMaximum_ReturnsFalse()
{
// Arrange
var block = new LootFilterBlock();
var block = new ItemFilterBlock();
block.BlockItems.Add(new SoundBlockItem());
// Act
@@ -51,5 +51,22 @@ namespace Filtration.Tests.Models
// Assert
Assert.IsFalse(result);
}
[Test]
public void HasParentInBlockGroupHierarchy_ReturnsCorrectResult()
{
// Arrange
var testInputRootBlockGroup = new ItemFilterBlockGroup("Root Block Group", null);
var testInputSubBlockGroup = new ItemFilterBlockGroup("Sub Block Group", testInputRootBlockGroup);
var testInputSubSubBlockGroup = new ItemFilterBlockGroup("Sub Sub Block Group", testInputSubBlockGroup);
var block = new ItemFilterBlock {BlockGroup = testInputSubSubBlockGroup};
// Act
// Assert
Assert.AreEqual(true, block.HasBlockGroupInParentHierarchy(testInputRootBlockGroup, block.BlockGroup));
Assert.AreEqual(true, block.HasBlockGroupInParentHierarchy(testInputSubBlockGroup, block.BlockGroup));
}
}
}

View File

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using Filtration.Models;
using Filtration.Models.BlockItemTypes;
@@ -12,14 +8,14 @@ using NUnit.Framework;
namespace Filtration.Tests.Models
{
[TestFixture]
public class TestLootFilterScript
public class TestItemFilterScript
{
[Test]
public void Validate_AtLeastOneBlock_Fail_ReturnsListWithCorrectError()
{
// Arrange
var script = new LootFilterScript();
var script = new ItemFilterScript();
// Act
var result = script.Validate();
@@ -33,10 +29,8 @@ namespace Filtration.Tests.Models
{
// Arrange
var script = new LootFilterScript
{
LootFilterBlocks = new ObservableCollection<LootFilterBlock> {new LootFilterBlock()}
};
var script = new ItemFilterScript();
script.ItemFilterBlocks.Add(new ItemFilterBlock());
// Act
var result = script.Validate();
@@ -59,22 +53,19 @@ namespace Filtration.Tests.Models
ReplaceBackgroundColor = true
};
var testInputBlock1 = new LootFilterBlock();
var testInputBlock1 = new ItemFilterBlock();
testInputBlock1.BlockItems.Add(new BackgroundColorBlockItem(new Color {A = 255, R = 255, G = 0, B = 0}));
var testInputBlock2 = new LootFilterBlock();
var testInputBlock2 = new ItemFilterBlock();
testInputBlock2.BlockItems.Add(new BackgroundColorBlockItem(new Color { A = 255, R = 255, G = 1, B = 0 }));
var testInputBlock3 = new LootFilterBlock();
var testInputBlock3 = new ItemFilterBlock();
testInputBlock3.BlockItems.Add(new BackgroundColorBlockItem(new Color { A = 255, R = 255, G = 0, B = 0 }));
var script = new LootFilterScript()
{
LootFilterBlocks = new ObservableCollection<LootFilterBlock>
{
testInputBlock1,
testInputBlock2,
testInputBlock3
}
};
var script = new ItemFilterScript();
script.ItemFilterBlocks.Add(testInputBlock1);
script.ItemFilterBlocks.Add(testInputBlock2);
script.ItemFilterBlocks.Add(testInputBlock3);
// Act
script.ReplaceColors(testInputReplaceColors);
@@ -105,21 +96,16 @@ namespace Filtration.Tests.Models
ReplaceTextColor = true
};
var testInputBlock1 = new LootFilterBlock();
var testInputBlock1 = new ItemFilterBlock();
testInputBlock1.BlockItems.Add(new BackgroundColorBlockItem(oldBackgroundColor));
testInputBlock1.BlockItems.Add(new TextColorBlockItem(oldTextColor));
var testInputBlock2 = new LootFilterBlock();
var testInputBlock2 = new ItemFilterBlock();
testInputBlock2.BlockItems.Add(new BackgroundColorBlockItem(oldBackgroundColor));
testInputBlock2.BlockItems.Add(new TextColorBlockItem(new Color {A = 1, R = 2, G = 3, B = 4}));
var script = new LootFilterScript
{
LootFilterBlocks = new ObservableCollection<LootFilterBlock>
{
testInputBlock1,
testInputBlock2
}
};
var script = new ItemFilterScript();
script.ItemFilterBlocks.Add(testInputBlock1);
script.ItemFilterBlocks.Add(testInputBlock2);
// Act
script.ReplaceColors(testInputReplaceColors);
@@ -135,3 +121,4 @@ namespace Filtration.Tests.Models
}
}
}

View File

@@ -1,4 +1,4 @@
# Loot Filter Script created by Filtration v0.1 - www.github.com/XVar/filtration
# Item Filter Script created by Filtration v0.1 - www.github.com/XVar/filtration
# Begin Script Description
# This is a test script
#

View File

@@ -7,55 +7,55 @@ using NUnit.Framework;
namespace Filtration.Tests.Services
{
[TestFixture]
public class TestLootFilterPersistenceService
public class TestItemFilterPersistenceService
{
[Test]
public void LoadLootFilterScript_CallsTranslatorAndFileSystemService()
public void LoadItemFilterScript_CallsTranslatorAndFileSystemService()
{
// Arrange
const string TestInputPath = "C:\\Test Path\\Script.Filter";
const string TestScriptString = "This is a test loot filter script";
var testLootFilterScript = new LootFilterScript();
const string TestScriptString = "This is a test item filter script";
var testItemFilterScript = new ItemFilterScript();
var mockFileSystemService = new Mock<IFileSystemService>();
mockFileSystemService.Setup(s => s.ReadFileAsString(TestInputPath)).Returns(TestScriptString).Verifiable();
var mockLootFilterScriptTranslator = new Mock<ILootFilterScriptTranslator>();
mockLootFilterScriptTranslator.Setup(t => t.TranslateStringToLootFilterScript(TestScriptString)).Returns(testLootFilterScript).Verifiable();
var mockItemFilterScriptTranslator = new Mock<IItemFilterScriptTranslator>();
mockItemFilterScriptTranslator.Setup(t => t.TranslateStringToItemFilterScript(TestScriptString)).Returns(testItemFilterScript).Verifiable();
var service = new LootFilterPersistenceService(mockFileSystemService.Object, mockLootFilterScriptTranslator.Object);
var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object);
// Act
var script = service.LoadLootFilterScript(TestInputPath);
var script = service.LoadItemFilterScript(TestInputPath);
// Assert
mockFileSystemService.Verify();
mockLootFilterScriptTranslator.Verify();
Assert.AreEqual(testLootFilterScript, script);
mockItemFilterScriptTranslator.Verify();
Assert.AreEqual(testItemFilterScript, script);
}
[Test]
public void SaveLootFilterScript_CallsTranslatorAndFileSystemService()
public void SaveItemFilterScript_CallsTranslatorAndFileSystemService()
{
// Arrange
var testFilePath = "C:\\Test\\File.txt";
var testScript = new LootFilterScript {FilePath = testFilePath};
var testScript = new ItemFilterScript {FilePath = testFilePath};
var testTranslatedScript = "Test translated script";
var mockFileSystemService = new Mock<IFileSystemService>();
mockFileSystemService.Setup(s => s.WriteFileFromString(testFilePath, testTranslatedScript)).Verifiable();
var mockLootFilterScriptTranslator = new Mock<ILootFilterScriptTranslator>();
mockLootFilterScriptTranslator.Setup(t => t.TranslateLootFilterScriptToString(testScript)).Returns(testTranslatedScript).Verifiable();
var mockItemFilterScriptTranslator = new Mock<IItemFilterScriptTranslator>();
mockItemFilterScriptTranslator.Setup(t => t.TranslateItemFilterScriptToString(testScript)).Returns(testTranslatedScript).Verifiable();
var service = new LootFilterPersistenceService(mockFileSystemService.Object, mockLootFilterScriptTranslator.Object);
var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object);
// Act
service.SaveLootFilterScript(testScript);
service.SaveItemFilterScript(testScript);
// Assert
mockFileSystemService.Verify();
mockLootFilterScriptTranslator.Verify();
mockItemFilterScriptTranslator.Verify();
}
[Test]
@@ -69,9 +69,9 @@ namespace Filtration.Tests.Services
mockFileSystemService.Setup(f => f.GetUserProfilePath()).Returns(TestUserProfilePath).Verifiable();
mockFileSystemService.Setup(f => f.DirectoryExists(TestUserProfilePath + "\\Documents\\My Games\\Path of Exile")).Returns(true).Verifiable();
var mockLootFilterScriptTranslator = new Mock<ILootFilterScriptTranslator>();
var mockItemFilterScriptTranslator = new Mock<IItemFilterScriptTranslator>();
var service = new LootFilterPersistenceService(mockFileSystemService.Object, mockLootFilterScriptTranslator.Object);
var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object);
// Act
var result = service.DefaultPathOfExileDirectory();

View File

@@ -13,7 +13,7 @@ namespace Filtration.Tests.Services
// Arrange
var mockFileSystemService = new Mock<IFileSystemService>();
mockFileSystemService.Setup(f => f.ReadFileAsString(It.IsAny<string>())).Verifiable();
mockFileSystemService.Setup(f => f.ReadFileAsString(It.IsAny<string>())).Returns("TestResult").Verifiable();
var service = new StaticDataService(mockFileSystemService.Object);

View File

@@ -11,45 +11,48 @@ using NUnit.Framework;
namespace Filtration.Tests.Translators
{
[TestFixture]
public class TestLootFilterScriptTranslator
public class TestItemFilterScriptTranslator
{
[Test]
public void TranslateStringToLootFilterScript_ReturnsScriptWithCorrectNumberOfBlocks()
private ItemFilterScriptTranslatorTestUtility _testUtility;
[SetUp]
public void ItemFilterScriptTranslatorTestSetup()
{
// Arrange
var testInput = File.ReadAllText(@"Resources/testscript.txt");
var mockLootFilterBlockTranslator = new Mock<ILootFilterBlockTranslator>();
mockLootFilterBlockTranslator.Setup(t => t.TranslateStringToLootFilterBlock(It.IsAny<string>())).Verifiable();
var translator = new LootFilterScriptTranslator(mockLootFilterBlockTranslator.Object);
// Act
var script = translator.TranslateStringToLootFilterScript(testInput);
// Assert
Assert.AreEqual(5, script.LootFilterBlocks.Count);
mockLootFilterBlockTranslator.Verify();
_testUtility = new ItemFilterScriptTranslatorTestUtility();
}
[Test]
public void TranslateStringToLootFilterScript_ReturnsScriptWithDescriptionCorrectlySet()
public void TranslateStringToItemFilterScript_ReturnsScriptWithCorrectNumberOfBlocks()
{
// Arrange
var testInput = File.ReadAllText(@"Resources/testscript.txt");
var expectedDescription = "Loot Filter Script created by Filtration v0.1 - www.github.com/XVar/filtration" + Environment.NewLine +
_testUtility.MockItemFilterBlockTranslator.Setup(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>())).Verifiable();
// Act
var script = _testUtility.ScriptTranslator.TranslateStringToItemFilterScript(testInput);
// Assert
Assert.AreEqual(5, script.ItemFilterBlocks.Count);
_testUtility.MockItemFilterBlockTranslator.Verify();
}
[Test]
public void TranslateStringToItemFilterScript_ReturnsScriptWithDescriptionCorrectlySet()
{
// Arrange
var testInput = File.ReadAllText(@"Resources/testscript.txt");
var expectedDescription = "Item Filter Script created by Filtration v0.1 - www.github.com/XVar/filtration" + Environment.NewLine +
"Begin Script Description" + Environment.NewLine +
"This is a test script" + Environment.NewLine +
Environment.NewLine +
"End Script Description";
var mockLootFilterBlockTranslator = new Mock<ILootFilterBlockTranslator>();
mockLootFilterBlockTranslator.Setup(t => t.TranslateStringToLootFilterBlock(It.IsAny<string>())).Verifiable();
var translator = new LootFilterScriptTranslator(mockLootFilterBlockTranslator.Object);
var mockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>();
mockItemFilterBlockTranslator.Setup(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>())).Verifiable();
// Act
var script = translator.TranslateStringToLootFilterScript(testInput);
var script = _testUtility.ScriptTranslator.TranslateStringToItemFilterScript(testInput);
// Assert
Assert.AreEqual(expectedDescription, script.Description);
@@ -57,69 +60,66 @@ namespace Filtration.Tests.Translators
[Ignore("Integration Test")]
[Test]
public void TranslateStringToLootFilterScript_ThioleLootFilterTest()
public void TranslateStringToItemFilterScript_ThioleItemFilterTest()
{
// Arrange
var testInput = File.ReadAllText(@"Resources/ThioleLootFilter.txt");
var testInput = File.ReadAllText(@"Resources/ThioleItemFilter.txt");
var BlockTranslator = new LootFilterBlockTranslator();
var translator = new LootFilterScriptTranslator(BlockTranslator);
var mockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
var blockTranslator = new ItemFilterBlockTranslator(mockBlockGroupHierarchyBuilder.Object);
var translator = new ItemFilterScriptTranslator(blockTranslator, mockBlockGroupHierarchyBuilder.Object);
// Act
var script = translator.TranslateStringToLootFilterScript(testInput);
var script = translator.TranslateStringToItemFilterScript(testInput);
// Assert
// Not crashing out when loading a huge script means this integration test has passed!
}
[Test]
public void TranslateLootFilterScriptToString_OneBlock_CallsTranslator()
public void TranslateItemFilterScriptToString_OneBlock_CallsTranslator()
{
// Arrange
var testScript = new LootFilterScript();
var testScript = new ItemFilterScript();
var testBlock = new LootFilterBlock();
var testBlock = new ItemFilterBlock();
testBlock.BlockItems.Add(new ItemLevelBlockItem(FilterPredicateOperator.Equal, 5));
var BlockOutput = "Test Script Output";
var expectedOutput = "Test Script Output" + Environment.NewLine + Environment.NewLine;
testScript.LootFilterBlocks.Add(testBlock);
testScript.ItemFilterBlocks.Add(testBlock);
var mockLootFilterBlockTranslator = new Mock<ILootFilterBlockTranslator>();
mockLootFilterBlockTranslator.Setup(t => t.TranslateLootFilterBlockToString(testBlock)).Returns(BlockOutput).Verifiable();
_testUtility.MockItemFilterBlockTranslator.Setup(t => t.TranslateItemFilterBlockToString(testBlock)).Returns(BlockOutput).Verifiable();
var translator = new LootFilterScriptTranslator(mockLootFilterBlockTranslator.Object);
// Act
var result = translator.TranslateLootFilterScriptToString(testScript);
var result = _testUtility.ScriptTranslator.TranslateItemFilterScriptToString(testScript);
// Assert
Assert.AreEqual(expectedOutput, result);
mockLootFilterBlockTranslator.Verify();
_testUtility.MockItemFilterBlockTranslator.Verify();
}
[Test]
public void TranslateLootFilterScriptToString_FullScript_ReturnsCorrectOutput()
public void TranslateItemFilterScriptToString_FullScript_ReturnsCorrectOutput()
{
var script = new LootFilterScript
var script = new ItemFilterScript
{
Description = "Test script description" + Environment.NewLine +
"This is a really great script!" + Environment.NewLine +
"Multiple line script descriptions are fun!"
};
var block1 = new LootFilterBlock {Description = "Test Filter 1"};
var block1 = new ItemFilterBlock {Description = "Test Filter 1"};
block1.BlockItems.Add(new ItemLevelBlockItem(FilterPredicateOperator.GreaterThan, 5));
var block2 = new LootFilterBlock();
var block2 = new ItemFilterBlock();
block2.BlockItems.Add(new QualityBlockItem(FilterPredicateOperator.LessThan, 15));
block2.BlockItems.Add(new FontSizeBlockItem(7));
block2.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 3));
script.LootFilterBlocks.Add(block1);
script.LootFilterBlocks.Add(block2);
script.ItemFilterBlocks.Add(block1);
script.ItemFilterBlocks.Add(block2);
var expectedOutput = "# Script edited with Filtration - http://ben-wallis.github.io/Filtration/" + Environment.NewLine +
var expectedOutput = "# Script edited with Filtration - https://github.com/ben-wallis/Filtration" + Environment.NewLine +
"# Test script description" + Environment.NewLine +
"# This is a really great script!" + Environment.NewLine +
"# Multiple line script descriptions are fun!" + Environment.NewLine +
@@ -133,41 +133,39 @@ namespace Filtration.Tests.Translators
" Width = 3" + Environment.NewLine +
" SetFontSize 7" + Environment.NewLine + Environment.NewLine;
var blockTranslator = new LootFilterBlockTranslator();
var translator = new LootFilterScriptTranslator(blockTranslator);
var mockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
var blockTranslator = new ItemFilterBlockTranslator(mockBlockGroupHierarchyBuilder.Object);
var translator = new ItemFilterScriptTranslator(blockTranslator, mockBlockGroupHierarchyBuilder.Object);
// Act
var result = translator.TranslateLootFilterScriptToString(script);
var result = translator.TranslateItemFilterScriptToString(script);
// Assert
Assert.AreEqual(expectedOutput, result);
}
[Test]
public void TranslateLootFilterScriptToString_FullScriptWithExistingFiltrationTagline_ReturnsCorrectOutput()
public void TranslateItemFilterScriptToString_FullScriptWithExistingFiltrationTagline_ReturnsCorrectOutput()
{
var script = new LootFilterScript
var script = new ItemFilterScript
{
Description = "Script edited with Filtration - http://ben-wallis.github.io/Filtration/" + Environment.NewLine +
Description = "Script edited with Filtration - https://github.com/ben-wallis/Filtration" + Environment.NewLine +
"Test script description" + Environment.NewLine
};
var expectedOutput = "# Script edited with Filtration - http://ben-wallis.github.io/Filtration/" +
var expectedOutput = "# Script edited with Filtration - https://github.com/ben-wallis/Filtration" +
Environment.NewLine +
"# Test script description" + Environment.NewLine + Environment.NewLine;
var blockTranslator = new LootFilterBlockTranslator();
var translator = new LootFilterScriptTranslator(blockTranslator);
// Act
var result = translator.TranslateLootFilterScriptToString(script);
var result = _testUtility.ScriptTranslator.TranslateItemFilterScriptToString(script);
// Assert
Assert.AreEqual(expectedOutput, result);
}
[Test]
public void TranslateStringToLootFilterScript_SectionDirectlyBeforeBlockWithoutDescription_ReturnsCorrectObject()
public void TranslateStringToItemFilterScript_SectionDirectlyBeforeBlockWithoutDescription_ReturnsCorrectObject()
{
// Arrange
var testInputScript = "# My Script" + Environment.NewLine +
@@ -178,19 +176,36 @@ namespace Filtration.Tests.Translators
" SetBorderColor 255 0 255" + Environment.NewLine +
" SetFontSize 25";
var blockTranslator = new LootFilterBlockTranslator();
var translator = new LootFilterScriptTranslator(blockTranslator);
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object);
var translator = new ItemFilterScriptTranslator(blockTranslator, _testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act
var result = translator.TranslateStringToLootFilterScript(testInputScript);
var result = translator.TranslateStringToItemFilterScript(testInputScript);
// Assert
Assert.AreEqual(2, result.LootFilterBlocks.Count);
var block = result.LootFilterBlocks.First(l => l.GetType() != typeof(LootFilterSection));
Assert.AreEqual(2, result.ItemFilterBlocks.Count);
var block = result.ItemFilterBlocks.First(l => l.GetType() != typeof(ItemFilterSection));
Assert.AreEqual(4, block.BlockItems.Count);
var baseTypeItem = block.BlockItems.OfType<BaseTypeBlockItem>().First();
Assert.AreEqual(2, baseTypeItem.Items.Count);
}
private class ItemFilterScriptTranslatorTestUtility
{
public ItemFilterScriptTranslatorTestUtility()
{
// Mock setups
MockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>();
MockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
// Class under test instantiation
ScriptTranslator = new ItemFilterScriptTranslator(MockItemFilterBlockTranslator.Object, MockBlockGroupHierarchyBuilder.Object);
}
public ItemFilterScriptTranslator ScriptTranslator { get; private set; }
public Mock<IItemFilterBlockTranslator> MockItemFilterBlockTranslator { get; private set; }
public Mock<IBlockGroupHierarchyBuilder> MockBlockGroupHierarchyBuilder { get; private set; }
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Globalization;
using System.Windows.Data;
using Filtration.ViewModels;
namespace Filtration.Converters
{
class ActiveDocumentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is IDocument)
return value;
return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is IDocument)
return value;
return Binding.DoNothing;
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace Filtration.Converters
{
internal class BlockGroupAdvancedColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var advanced = (bool) value;
return advanced ? new SolidColorBrush(Colors.IndianRed) : new SolidColorBrush(Colors.Black);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace Filtration.Converters
{
internal class BlockGroupAdvancedFillColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var advanced = (bool) value;
return advanced ? new SolidColorBrush(Colors.IndianRed) : new SolidColorBrush(Colors.SlateGray);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Filtration.Converters
{
internal class BlockGroupVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var blockGroupAdvanced = (bool) values[0];
var showAdvanced = (bool)values[1];
if (!blockGroupAdvanced || showAdvanced)
{
return Visibility.Visible;
}
return Visibility.Hidden;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -9,7 +9,7 @@ namespace Filtration.Converters
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var test = (ILootFilterBlockItem)Activator.CreateInstance((Type) value);
var test = (IItemFilterBlockItem)Activator.CreateInstance((Type) value);
return test.DisplayHeading;
}

View File

@@ -25,9 +25,10 @@ namespace Filtration.Extensions
var hyperlink = sender as Hyperlink;
if ((bool)args.NewValue)
hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
else
hyperlink.RequestNavigate -= Hyperlink_RequestNavigate;
{
if (hyperlink != null) hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
}
else if (hyperlink != null) hyperlink.RequestNavigate -= Hyperlink_RequestNavigate;
}
private static void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)

View File

@@ -60,6 +60,8 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.ObjectModel" />
<Reference Include="System.Runtime" />
<Reference Include="System.Windows.Controls.Input.Toolkit">
<HintPath>..\packages\WPFToolkit.3.5.50211.1\lib\System.Windows.Controls.Input.Toolkit.dll</HintPath>
</Reference>
@@ -79,6 +81,21 @@
<Reference Include="WPFToolkit">
<HintPath>..\packages\WPFToolkit.3.5.50211.1\lib\WPFToolkit.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock">
<HintPath>..\packages\AvalonDock.2.0.2000\lib\net40\Xceed.Wpf.AvalonDock.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Aero">
<HintPath>..\packages\AvalonDock.2.0.2000\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Expression">
<HintPath>..\packages\AvalonDock.2.0.2000\lib\net40\Xceed.Wpf.AvalonDock.Themes.Expression.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Metro">
<HintPath>..\packages\AvalonDock.2.0.2000\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.VS2010">
<HintPath>..\packages\AvalonDock.2.0.2000\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll</HintPath>
</Reference>
<Reference Include="Xceed.Wpf.Toolkit, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.Toolkit.dll</HintPath>
@@ -89,11 +106,16 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Converters\ActiveDocumentConverter.cs" />
<Compile Include="Converters\BlockGroupAdvancedFillConverter.cs" />
<Compile Include="Converters\BlockGroupAdvancedColorConverter.cs" />
<Compile Include="Converters\BlockGroupVisibilityConverter.cs" />
<Compile Include="Converters\BlockItemTypeToStringConverter.cs" />
<Compile Include="Converters\BooleanInverterConverter.cs" />
<Compile Include="Converters\BooleanToBlockActionInverseConverter.cs" />
<Compile Include="Converters\BooleanToBlockActionConverter.cs" />
<Compile Include="Converters\ColorToSolidColorBrushConverter.cs" />
<Compile Include="Converters\HashSignRemovalConverter.cs" />
<Compile Include="Converters\ItemRarityConverter.cs" />
<Compile Include="Converters\BooleanVisibilityConverter.cs" />
<Compile Include="Converters\StringToVisibilityConverter.cs" />
@@ -130,19 +152,21 @@
<Compile Include="Models\BlockItemTypes\QualityBlockItem.cs" />
<Compile Include="Models\BlockItemTypes\ItemLevelBlockItem.cs" />
<Compile Include="Models\IAudioVisualBlockItem.cs" />
<Compile Include="Models\LootFilterBlock.cs" />
<Compile Include="Models\ILootFilterBlockItem.cs" />
<Compile Include="Models\LootFilterScript.cs" />
<Compile Include="Models\LootFilterSection.cs" />
<Compile Include="Models\ItemFilterBlockGroup.cs" />
<Compile Include="Models\ItemFilterBlock.cs" />
<Compile Include="Models\IItemFilterBlockItem.cs" />
<Compile Include="Models\ItemFilterScript.cs" />
<Compile Include="Models\ItemFilterSection.cs" />
<Compile Include="Models\NumericFilterPredicate.cs" />
<Compile Include="Models\BlockItemBaseTypes\SocketGroupBlockItemBase.cs" />
<Compile Include="Models\ReplaceColorsParameterSet.cs" />
<Compile Include="Properties\Annotations.cs" />
<Compile Include="Services\FileSystemService.cs" />
<Compile Include="Services\LootFilterPersistenceService.cs" />
<Compile Include="Services\ItemFilterPersistenceService.cs" />
<Compile Include="Services\StaticDataService.cs" />
<Compile Include="Translators\LootFilterBlockTranslator.cs" />
<Compile Include="Translators\LootFilterScriptTranslator.cs" />
<Compile Include="Translators\BlockGroupHierarchyBuilder.cs" />
<Compile Include="Translators\ItemFilterBlockTranslator.cs" />
<Compile Include="Translators\ItemFilterScriptTranslator.cs" />
<Compile Include="UserControls\AutoScrollingListBox.cs" />
<Compile Include="UserControls\CrossButton.cs" />
<Compile Include="UserControls\EditableListBoxControl.xaml.cs">
@@ -152,35 +176,60 @@
<DependentUpon>ItemPreviewControl.xaml</DependentUpon>
</Compile>
<Compile Include="Utilities\LineReader.cs" />
<Compile Include="ViewModels\AvalonDockWorkspaceViewModel.cs" />
<Compile Include="ViewModels\BlockGroupBrowserViewModel.cs" />
<Compile Include="ViewModels\FiltrationViewModelBase.cs" />
<Compile Include="ViewModels\ILootFilterScriptViewModelFactory.cs" />
<Compile Include="ViewModels\ILootFilterBlockViewModelFactory.cs" />
<Compile Include="ViewModels\LootFilterBlockViewModel.cs" />
<Compile Include="ViewModels\LootFilterScriptViewModel.cs" />
<Compile Include="ViewModels\IDocument.cs" />
<Compile Include="ViewModels\IItemFilterScriptViewModelFactory.cs" />
<Compile Include="ViewModels\IItemFilterBlockViewModelFactory.cs" />
<Compile Include="ViewModels\ItemFilterBlockViewModel.cs" />
<Compile Include="ViewModels\ItemFilterScriptViewModel.cs" />
<Compile Include="ViewModels\PaneViewModel.cs" />
<Compile Include="ViewModels\ReplaceColorsViewModel.cs" />
<Compile Include="ViewModels\SectionBrowserViewModel.cs" />
<Compile Include="ViewModels\StartPageViewModel.cs" />
<Compile Include="ViewModels\ToolViewModel.cs" />
<Compile Include="Views\AttachedProperties\SelectingItemAttachedProperty.cs" />
<Compile Include="Views\AvalonDock\AvalonDockWorkspaceView.xaml.cs">
<DependentUpon>AvalonDockWorkspaceView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Behaviors\BindableSelectedItemBehavior.cs" />
<Compile Include="Views\BindingProxy.cs" />
<Compile Include="Views\PathOfExileColors.cs" />
<Compile Include="Views\ToolPanes\BlockGroupBrowserView.xaml.cs">
<DependentUpon>BlockGroupBrowserView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\BlockTemplateSelector.cs" />
<Compile Include="Views\LootFilterBlockDisplaySettingsView.xaml.cs">
<DependentUpon>LootFilterBlockDisplaySettingsView.xaml</DependentUpon>
<Compile Include="Views\ItemFilterBlockDisplaySettingsView.xaml.cs">
<DependentUpon>ItemFilterBlockDisplaySettingsView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LootFilterScriptView.xaml.cs">
<DependentUpon>LootFilterScriptView.xaml</DependentUpon>
<Compile Include="Views\ItemFilterScriptView.xaml.cs">
<DependentUpon>ItemFilterScriptView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LootFilterBlockView.xaml.cs">
<DependentUpon>LootFilterBlockView.xaml</DependentUpon>
<Compile Include="Views\ItemFilterBlockView.xaml.cs">
<DependentUpon>ItemFilterBlockView.xaml</DependentUpon>
</Compile>
<Compile Include="UserControls\NumericFilterPredicateControl.xaml.cs">
<DependentUpon>NumericFilterPredicateControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LootFilterSectionView.xaml.cs">
<DependentUpon>LootFilterSectionView.xaml</DependentUpon>
<Compile Include="Views\ItemFilterSectionView.xaml.cs">
<DependentUpon>ItemFilterSectionView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\AboutWindow.xaml.cs">
<DependentUpon>AboutWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\AvalonDock\LayoutInitializer.cs" />
<Compile Include="Views\AvalonDock\PanesStyleSelector.cs" />
<Compile Include="Views\AvalonDock\PanesTemplateSelector.cs" />
<Compile Include="Views\ReplaceColorsWindow.xaml.cs">
<DependentUpon>ReplaceColorsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ToolPanes\SectionBrowserView.xaml.cs">
<DependentUpon>SectionBrowserView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\StartPageView.xaml.cs">
<DependentUpon>StartPageView.xaml</DependentUpon>
</Compile>
<Compile Include="WindsorInstallers\ModelsInstaller.cs" />
<Compile Include="WindsorInstallers\ServicesInstaller.cs" />
<Compile Include="WindsorInstallers\TranslatorsInstaller.cs" />
@@ -190,6 +239,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\AvalonDock\AvalonDockWorkspaceView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ToolPanes\BlockGroupBrowserView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\CrossButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -206,7 +263,11 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LootFilterBlockDisplaySettingsView.xaml">
<Page Include="Views\ItemFilterBlockDisplaySettingsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ToolPanes\SectionBrowserView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -214,15 +275,15 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LootFilterScriptView.xaml">
<Page Include="Views\ItemFilterScriptView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LootFilterBlockView.xaml">
<Page Include="Views\ItemFilterBlockView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LootFilterSectionView.xaml">
<Page Include="Views\ItemFilterSectionView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -251,6 +312,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\StartPageView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -307,6 +372,10 @@
<Resource Include="Resources\Icons\about_icon.png" />
<Resource Include="Resources\filtration.ico" />
<Resource Include="Resources\Icons\replace_colors_icon.png" />
<Resource Include="Resources\Icons\block_group_browser_icon.png" />
<Resource Include="Resources\Icons\clear_filter_icon.png" />
<Resource Include="Resources\Icons\filter_icon.png" />
<Resource Include="Resources\Icons\show_advanced_icon.png" />
<Content Include="Resources\ItemBaseTypes.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

View File

@@ -5,7 +5,7 @@ using Filtration.Annotations;
namespace Filtration.Models.BlockItemBaseTypes
{
abstract class BlockItemBase : ILootFilterBlockItem
abstract class BlockItemBase : IItemFilterBlockItem
{
public abstract string PrefixText { get; }
public abstract int MaximumAllowed { get; }

View File

@@ -6,6 +6,7 @@ namespace Filtration.Models.BlockItemTypes
{
public FontSizeBlockItem()
{
Value = 35;
}
public FontSizeBlockItem(int value) : base(value)

View File

@@ -3,7 +3,7 @@ using System.Windows.Media;
namespace Filtration.Models
{
internal interface ILootFilterBlockItem : INotifyPropertyChanged
internal interface IItemFilterBlockItem : INotifyPropertyChanged
{
string PrefixText { get; }
int MaximumAllowed { get; }

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using Filtration.Enums;
using Filtration.Models.BlockItemBaseTypes;
namespace Filtration.Models
{
internal class ItemFilterBlock
{
private ItemFilterBlockGroup _blockGroup;
public ItemFilterBlock()
{
BlockItems = new ObservableCollection<IItemFilterBlockItem> {new ActionBlockItem(BlockAction.Show)};
}
public string Description { get; set; }
public ItemFilterBlockGroup BlockGroup
{
get { return _blockGroup; }
set
{
var oldBlockGroup = _blockGroup;
_blockGroup = value;
if (_blockGroup != null)
{
_blockGroup.BlockGroupStatusChanged += OnBlockGroupStatusChanged;
if (oldBlockGroup != null)
{
oldBlockGroup.BlockGroupStatusChanged -= OnBlockGroupStatusChanged;
}
}
else
{
if (oldBlockGroup != null)
{
oldBlockGroup.BlockGroupStatusChanged -= OnBlockGroupStatusChanged;
}
}
}
}
public BlockAction Action
{
get
{
var actionBlock = BlockItems.OfType<ActionBlockItem>().First();
return actionBlock.Action;
}
set
{
var actionBlock = BlockItems.OfType<ActionBlockItem>().First();
actionBlock.Action = value;
}
}
public ObservableCollection<IItemFilterBlockItem> BlockItems { get; private set; }
public int BlockCount(Type type)
{
return BlockItems != null ? BlockItems.Count(b => b.GetType() == type) : 0;
}
public bool AddBlockItemAllowed(Type type)
{
var blockItem = (IItemFilterBlockItem)Activator.CreateInstance(type);
return BlockCount(type) < blockItem.MaximumAllowed;
}
public bool HasBlockItemOfType<T>()
{
return BlockItems.Count(b => b is T) > 0;
}
public bool HasBlockGroupInParentHierarchy(ItemFilterBlockGroup targetBlockGroup, ItemFilterBlockGroup startingBlockGroup)
{
if (startingBlockGroup == targetBlockGroup)
{
return true;
}
if (BlockGroup == null)
{
return false;
}
if (startingBlockGroup.ParentGroup != null)
{
return HasBlockGroupInParentHierarchy(targetBlockGroup, startingBlockGroup.ParentGroup);
}
return false;
}
private void OnBlockGroupStatusChanged(object sender, EventArgs e)
{
if (BlockGroup.IsChecked == false && Action == BlockAction.Show)
{
Action = BlockAction.Hide;
}
else if (BlockGroup.IsChecked == true && Action == BlockAction.Hide)
{
Action = BlockAction.Show;
}
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using Filtration.Annotations;
namespace Filtration.Models
{
internal class ItemFilterBlockGroup : INotifyPropertyChanged
{
private bool? _isChecked;
private bool _reentrancyCheck;
public ItemFilterBlockGroup(string groupName, ItemFilterBlockGroup parent, bool advanced = false)
{
GroupName = groupName;
ParentGroup = parent;
Advanced = advanced;
ChildGroups = new ObservableCollection<ItemFilterBlockGroup>();
}
public event EventHandler BlockGroupStatusChanged;
public string GroupName { get; private set; }
public ItemFilterBlockGroup ParentGroup { get; private set; }
public ObservableCollection<ItemFilterBlockGroup> ChildGroups { get; private set; }
public override string ToString()
{
var currentBlockGroup = this;
var outputString = GroupName;
// TODO: This is retarded, fix this.
if (currentBlockGroup.ParentGroup != null)
{
while (currentBlockGroup.ParentGroup.ParentGroup != null)
{
outputString = currentBlockGroup.ParentGroup.GroupName + " - " + outputString;
currentBlockGroup = currentBlockGroup.ParentGroup;
}
}
return outputString;
}
public bool Advanced { get; private set; }
public bool? IsChecked
{
get
{
return _isChecked;
}
set
{
if (_isChecked != value)
{
if (_reentrancyCheck)
{
return;
}
_reentrancyCheck = true;
_isChecked = value;
UpdateCheckState();
OnPropertyChanged();
// Raise an event to let blocks that have this block group assigned that
// they might need to change their Action due to the block group status changing.
if (BlockGroupStatusChanged != null)
{
BlockGroupStatusChanged.Invoke(null, null);
}
_reentrancyCheck = false;
}
}
}
private void UpdateCheckState()
{
// update all children:
if (ChildGroups.Count != 0)
{
UpdateChildrenCheckState();
}
// update parent item
if (ParentGroup != null)
{
var parentIsChecked = ParentGroup.DetermineCheckState();
ParentGroup.IsChecked = parentIsChecked;
}
}
private void UpdateChildrenCheckState()
{
foreach (var childGroup in ChildGroups.Where(c => IsChecked != null && !c.Advanced))
{
childGroup.IsChecked = IsChecked;
}
}
private bool? DetermineCheckState()
{
var allChildrenChecked = ChildGroups.Count(x => x.IsChecked == true) == ChildGroups.Count;
if (allChildrenChecked)
{
return true;
}
var allChildrenUnchecked = ChildGroups.Count(x => x.IsChecked == false) == ChildGroups.Count;
if (allChildrenUnchecked)
{
return false;
}
return null;
}
public ItemFilterBlockGroup Search(Func<ItemFilterBlockGroup, bool> predicate)
{
// if node is a leaf
if (ChildGroups == null || ChildGroups.Count == 0)
{
return predicate(this) ? this : null;
}
var results = ChildGroups
.Select(i => i.Search(predicate))
.Where(i => i != null).ToList();
if (results.Any())
{
var result = (ItemFilterBlockGroup)MemberwiseClone();
result.ChildGroups = new ObservableCollection<ItemFilterBlockGroup>(results);
return result;
}
return null;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -3,19 +3,23 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Filtration.Models.BlockItemTypes;
using Filtration.ViewModels;
using Filtration.Views;
namespace Filtration.Models
{
internal class LootFilterScript
internal class ItemFilterScript
{
public LootFilterScript()
public ItemFilterScript()
{
LootFilterBlocks = new ObservableCollection<LootFilterBlock>();
ItemFilterBlocks = new ObservableCollection<ItemFilterBlock>();
ItemFilterBlockGroups = new ObservableCollection<ItemFilterBlockGroup>
{
new ItemFilterBlockGroup("Root", null)
};
}
public ObservableCollection<LootFilterBlock> LootFilterBlocks { get; set; }
public ObservableCollection<ItemFilterBlock> ItemFilterBlocks { get; private set; }
public ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; private set; }
public string FilePath { get; set; }
public string Description { get; set; }
public DateTime DateModified { get; set; }
@@ -24,7 +28,7 @@ namespace Filtration.Models
{
var validationErrors = new List<string>();
if (LootFilterBlocks.Count == 0)
if (ItemFilterBlocks.Count == 0)
{
validationErrors.Add("A script must have at least one block");
}
@@ -37,7 +41,7 @@ namespace Filtration.Models
foreach (
var block in
LootFilterBlocks.Where(b => BlockIsColorReplacementCandidate(replaceColorsParameterSet, b)))
ItemFilterBlocks.Where(b => BlockIsColorReplacementCandidate(replaceColorsParameterSet, b)))
{
if (replaceColorsParameterSet.ReplaceTextColor)
{
@@ -58,7 +62,7 @@ namespace Filtration.Models
}
private bool BlockIsColorReplacementCandidate(ReplaceColorsParameterSet replaceColorsParameterSet, LootFilterBlock block)
private bool BlockIsColorReplacementCandidate(ReplaceColorsParameterSet replaceColorsParameterSet, ItemFilterBlock block)
{
var textColorItem = block.HasBlockItemOfType<TextColorBlockItem>()
? block.BlockItems.OfType<TextColorBlockItem>().First()

View File

@@ -0,0 +1,6 @@
namespace Filtration.Models
{
internal class ItemFilterSection : ItemFilterBlock
{
}
}

View File

@@ -1,51 +0,0 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using Filtration.Enums;
using Filtration.Models.BlockItemBaseTypes;
using Filtration.Models.BlockItemTypes;
namespace Filtration.Models
{
internal class LootFilterBlock
{
public LootFilterBlock()
{
BlockItems = new ObservableCollection<ILootFilterBlockItem> {new ActionBlockItem(BlockAction.Show)};
}
public string Description { get; set; }
public BlockAction Action
{
get
{
var actionBlock = BlockItems.OfType<ActionBlockItem>().First();
return actionBlock.Action;
}
set
{
var actionBlock = BlockItems.OfType<ActionBlockItem>().First();
actionBlock.Action = value;
}
}
public ObservableCollection<ILootFilterBlockItem> BlockItems { get; private set; }
public int BlockCount(Type type)
{
return BlockItems != null ? BlockItems.Count(b => b.GetType() == type) : 0;
}
public bool AddBlockItemAllowed(Type type)
{
var blockItem = (ILootFilterBlockItem)Activator.CreateInstance(type);
return BlockCount(type) < blockItem.MaximumAllowed;
}
public bool HasBlockItemOfType<T>()
{
return BlockItems.Count(b => b is T) > 0;
}
}
}

View File

@@ -1,6 +0,0 @@
namespace Filtration.Models
{
internal class LootFilterSection : LootFilterBlock
{
}
}

View File

@@ -7,7 +7,7 @@ using System.Windows;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Filtration")]
[assembly: AssemblyDescription("A loot filter script manager for Path of Exile")]
[assembly: AssemblyDescription("An item filter script manager for Path of Exile")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("XVar Industries Inc.")]
[assembly: AssemblyProduct("Filtration")]
@@ -50,7 +50,7 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.*")]
[assembly: AssemblyVersion("0.3.*")]
[assembly: InternalsVisibleTo("Filtration.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

View File

@@ -3,41 +3,41 @@ using Filtration.Translators;
namespace Filtration.Services
{
internal interface ILootFilterPersistenceService
internal interface IItemFilterPersistenceService
{
string LootFilterScriptDirectory { get; set; }
LootFilterScript LoadLootFilterScript(string filePath);
void SaveLootFilterScript(LootFilterScript script);
string ItemFilterScriptDirectory { get; set; }
ItemFilterScript LoadItemFilterScript(string filePath);
void SaveItemFilterScript(ItemFilterScript script);
string DefaultPathOfExileDirectory();
}
internal class LootFilterPersistenceService : ILootFilterPersistenceService
internal class ItemFilterPersistenceService : IItemFilterPersistenceService
{
private readonly IFileSystemService _fileSystemService;
private readonly ILootFilterScriptTranslator _lootFilterScriptTranslator;
private readonly IItemFilterScriptTranslator _itemFilterScriptTranslator;
public LootFilterPersistenceService(IFileSystemService fileSystemService, ILootFilterScriptTranslator lootFilterScriptTranslator)
public ItemFilterPersistenceService(IFileSystemService fileSystemService, IItemFilterScriptTranslator itemFilterScriptTranslator)
{
_fileSystemService = fileSystemService;
_lootFilterScriptTranslator = lootFilterScriptTranslator;
_itemFilterScriptTranslator = itemFilterScriptTranslator;
}
public string LootFilterScriptDirectory { get; set; }
public string ItemFilterScriptDirectory { get; set; }
public LootFilterScript LoadLootFilterScript(string filePath)
public ItemFilterScript LoadItemFilterScript(string filePath)
{
var script =
_lootFilterScriptTranslator.TranslateStringToLootFilterScript(
_itemFilterScriptTranslator.TranslateStringToItemFilterScript(
_fileSystemService.ReadFileAsString(filePath));
script.FilePath = filePath;
return script;
}
public void SaveLootFilterScript(LootFilterScript script)
public void SaveItemFilterScript(ItemFilterScript script)
{
_fileSystemService.WriteFileFromString(script.FilePath,
_lootFilterScriptTranslator.TranslateLootFilterScriptToString(script));
_itemFilterScriptTranslator.TranslateItemFilterScriptToString(script));
}
public string DefaultPathOfExileDirectory()

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Filtration.Models;
namespace Filtration.Translators
{
internal interface IBlockGroupHierarchyBuilder
{
void Initialise(ItemFilterBlockGroup rootBlockGroup);
ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings);
}
internal class BlockGroupHierarchyBuilder : IBlockGroupHierarchyBuilder
{
private ItemFilterBlockGroup _rootBlockGroup;
public void Initialise(ItemFilterBlockGroup rootBlockGroup)
{
_rootBlockGroup = rootBlockGroup;
}
public ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings)
{
if (_rootBlockGroup == null)
{
throw new Exception("BlockGroupHierarchyBuilder must be initialised with root BlockGroup before use");
}
return IntegrateStringListIntoBlockGroupHierarchy(groupStrings, _rootBlockGroup);
}
public ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings, ItemFilterBlockGroup startItemGroup)
{
var inputGroups = groupStrings.ToList();
var firstGroup = inputGroups.First().Trim();
if (firstGroup.StartsWith("~"))
{
firstGroup = firstGroup.Substring(1);
}
ItemFilterBlockGroup matchingChildItemGroup = null;
if (startItemGroup.ChildGroups.Count(g => g.GroupName == firstGroup) > 0)
{
matchingChildItemGroup = startItemGroup.ChildGroups.First(c => c.GroupName == firstGroup);
}
if (matchingChildItemGroup == null)
{
var newItemGroup = CreateBlockGroup(inputGroups.First().Trim(), startItemGroup);
startItemGroup.ChildGroups.Add(newItemGroup);
inputGroups = inputGroups.Skip(1).ToList();
return inputGroups.Count > 0 ? IntegrateStringListIntoBlockGroupHierarchy(inputGroups, newItemGroup) : newItemGroup;
}
inputGroups = inputGroups.Skip(1).ToList();
return inputGroups.Count > 0 ? IntegrateStringListIntoBlockGroupHierarchy(inputGroups, matchingChildItemGroup) : matchingChildItemGroup;
}
private ItemFilterBlockGroup CreateBlockGroup(string groupNameString, ItemFilterBlockGroup parentGroup)
{
var advanced = false;
if (groupNameString.StartsWith("~"))
{
groupNameString = groupNameString.Substring(1);
advanced = true;
}
if (parentGroup.Advanced)
{
advanced = true;
}
return new ItemFilterBlockGroup(groupNameString, parentGroup, advanced);
}
}
}

View File

@@ -13,28 +13,35 @@ using Filtration.Utilities;
namespace Filtration.Translators
{
internal interface ILootFilterBlockTranslator
internal interface IItemFilterBlockTranslator
{
LootFilterBlock TranslateStringToLootFilterBlock(string inputString);
string TranslateLootFilterBlockToString(LootFilterBlock block);
ItemFilterBlock TranslateStringToItemFilterBlock(string inputString);
string TranslateItemFilterBlockToString(ItemFilterBlock block);
}
internal class LootFilterBlockTranslator : ILootFilterBlockTranslator
internal class ItemFilterBlockTranslator : IItemFilterBlockTranslator
{
private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder;
private const string Indent = " ";
private readonly string _newLine = Environment.NewLine + Indent;
// This method converts a string into a LootFilterBlock. This is used for pasting LootFilterBlocks
// and reading LootFilterScripts from a file.
public LootFilterBlock TranslateStringToLootFilterBlock(string inputString)
public ItemFilterBlockTranslator(IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder)
{
var block = new LootFilterBlock();
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
}
// This method converts a string into a ItemFilterBlock. This is used for pasting ItemFilterBlocks
// and reading ItemFilterScripts from a file.
public ItemFilterBlock TranslateStringToItemFilterBlock(string inputString)
{
var block = new ItemFilterBlock();
var showHideFound = false;
foreach (var line in new LineReader(() => new StringReader(inputString)))
{
if (line.StartsWith(@"# Section:"))
{
var section = new LootFilterSection
var section = new ItemFilterSection
{
Description = line.Substring(line.IndexOf(":", StringComparison.Ordinal) + 1).Trim()
};
@@ -47,7 +54,8 @@ namespace Filtration.Translators
continue;
}
var trimmedLine = line.TrimStart(' ');
var adjustedLine = line.Replace("#", " # ");
var trimmedLine = adjustedLine.TrimStart(' ');
var spaceOrEndOfLinePos = trimmedLine.IndexOf(" ", StringComparison.Ordinal) > 0 ? trimmedLine.IndexOf(" ", StringComparison.Ordinal) : trimmedLine.Length;
var lineOption = trimmedLine.Substring(0, spaceOrEndOfLinePos);
@@ -56,10 +64,12 @@ namespace Filtration.Translators
case "Show":
showHideFound = true;
block.Action = BlockAction.Show;
AddBlockGroupToBlock(block, trimmedLine);
break;
case "Hide":
showHideFound = true;
block.Action = BlockAction.Hide;
AddBlockGroupToBlock(block, trimmedLine);
break;
case "ItemLevel":
{
@@ -122,20 +132,6 @@ namespace Filtration.Translators
}
case "SocketGroup":
{
//var blockItem = new SocketGroupBlockItem();
//var socketGroups = Regex.Matches(trimmedLine, @"\s+([RGBW]{1,6})");
//foreach (Match socketGroupMatch in socketGroups)
//{
// var socketGroupCharArray = socketGroupMatch.Groups[1].Value.Trim(' ').ToCharArray();
// var socketColorList = socketGroupCharArray.Select(c => (EnumHelper.GetEnumValueFromDescription<SocketColor>(c.ToString()))).ToList();
// blockItem.SocketColorGroups.Add(socketColorList);
//}
//block.FilterBlockItems.Add(blockItem);
AddStringListItemToBlockItems<SocketGroupBlockItem>(block, trimmedLine);
break;
}
@@ -215,7 +211,7 @@ namespace Filtration.Translators
return block;
}
private static void RemoveExistingBlockItemsOfType<T>(LootFilterBlock block)
private static void RemoveExistingBlockItemsOfType<T>(ItemFilterBlock block)
{
var existingBlockItemCount = block.BlockItems.Count(b => b.GetType() == typeof(T));
if (existingBlockItemCount > 0)
@@ -225,7 +221,7 @@ namespace Filtration.Translators
}
}
private static void AddNumericFilterPredicateItemToBlockItems<T>(LootFilterBlock block, string inputString) where T : NumericFilterPredicateBlockItem
private static void AddNumericFilterPredicateItemToBlockItems<T>(ItemFilterBlock block, string inputString) where T : NumericFilterPredicateBlockItem
{
var blockItem = Activator.CreateInstance<T>();
@@ -243,7 +239,7 @@ namespace Filtration.Translators
predicate.PredicateOperand = Convert.ToInt16(result.Groups[2].Value);
}
private static void AddStringListItemToBlockItems<T>(LootFilterBlock block, string inputString) where T : StringListBlockItem
private static void AddStringListItemToBlockItems<T>(ItemFilterBlock block, string inputString) where T : StringListBlockItem
{
var blockItem = Activator.CreateInstance<T>();
PopulateListFromString(blockItem.Items, inputString.Substring(inputString.IndexOf(" ", StringComparison.Ordinal) + 1).Trim());
@@ -261,13 +257,27 @@ namespace Filtration.Translators
}
}
private static void AddColorItemToBlockItems<T>(LootFilterBlock block, string inputString) where T : ColorBlockItem
private static void AddColorItemToBlockItems<T>(ItemFilterBlock block, string inputString) where T : ColorBlockItem
{
var blockItem = Activator.CreateInstance<T>();
blockItem.Color = GetColorFromString(inputString);
block.BlockItems.Add(blockItem);
}
private void AddBlockGroupToBlock(ItemFilterBlock block, string inputString)
{
var blockGroupStart = inputString.IndexOf("#", StringComparison.Ordinal);
if (blockGroupStart <= 0) return;
var blockGroupText = inputString.Substring(blockGroupStart + 1);
var blockGroups = blockGroupText.Split('-').ToList();
if (blockGroups.Count(b => !string.IsNullOrEmpty(b.Trim())) > 0)
{
block.BlockGroup = _blockGroupHierarchyBuilder.IntegrateStringListIntoBlockGroupHierarchy(blockGroups);
block.BlockGroup.IsChecked = block.Action == BlockAction.Show;
}
}
private static Color GetColorFromString(string inputString)
{
var argbValues = Regex.Matches(inputString, @"\s+(\d+)");
@@ -294,11 +304,11 @@ namespace Filtration.Translators
return new Color();
}
// This method converts a LootFilterBlock object into a string. This is used for copying a LootFilterBlock
// to the clipboard, and when saving a LootFilterScript.
public string TranslateLootFilterBlockToString(LootFilterBlock block)
// This method converts an ItemFilterBlock object into a string. This is used for copying a ItemFilterBlock
// to the clipboard, and when saving a ItemFilterScript.
public string TranslateItemFilterBlockToString(ItemFilterBlock block)
{
if (block.GetType() == typeof (LootFilterSection))
if (block.GetType() == typeof (ItemFilterSection))
{
return "# Section: " + block.Description;
}
@@ -312,7 +322,12 @@ namespace Filtration.Translators
outputString += block.Action.GetAttributeDescription();
// This could be refactored to use the upcasted NumericFilterPredicateBlockItem (or even ILootFilterBlockItem) instead
if (block.BlockGroup != null)
{
outputString += " # " + block.BlockGroup;
}
// This could be refactored to use the upcasted NumericFilterPredicateBlockItem (or even IItemFilterBlockItem) instead
// of the specific downcasts. Leaving it like this currently to preserve sorting since the different
// downcasts have no defined sort order (yet).
foreach (var blockItem in block.BlockItems.OfType<ItemLevelBlockItem>())

View File

@@ -1,30 +1,36 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Castle.Core.Internal;
using Filtration.Models;
using Filtration.Utilities;
namespace Filtration.Translators
{
internal interface ILootFilterScriptTranslator
internal interface IItemFilterScriptTranslator
{
LootFilterScript TranslateStringToLootFilterScript(string inputString);
string TranslateLootFilterScriptToString(LootFilterScript script);
ItemFilterScript TranslateStringToItemFilterScript(string inputString);
string TranslateItemFilterScriptToString(ItemFilterScript script);
}
internal class LootFilterScriptTranslator : ILootFilterScriptTranslator
internal class ItemFilterScriptTranslator : IItemFilterScriptTranslator
{
private readonly ILootFilterBlockTranslator _blockTranslator;
private readonly IItemFilterBlockTranslator _blockTranslator;
private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder;
public LootFilterScriptTranslator(ILootFilterBlockTranslator blockTranslator)
public ItemFilterScriptTranslator(IItemFilterBlockTranslator blockTranslator, IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder)
{
_blockTranslator = blockTranslator;
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
}
public LootFilterScript TranslateStringToLootFilterScript(string inputString)
public ItemFilterScript TranslateStringToItemFilterScript(string inputString)
{
var script = new LootFilterScript();
var script = new ItemFilterScript();
_blockGroupHierarchyBuilder.Initialise(script.ItemFilterBlockGroups.First());
inputString = inputString.Replace("\t", "");
var conditionBoundaries = IdentifyBlockBoundaries(inputString);
@@ -38,10 +44,14 @@ namespace Filtration.Translators
script.Description += lines[i].Substring(1).Trim(' ') + Environment.NewLine;
}
}
script.Description = script.Description.TrimEnd('\n').TrimEnd('\r');
// Extract each block from between boundaries and translate it into a LootFilterBlock object
// and add that object to the LootFilterBlocks list
if (!script.Description.IsNullOrEmpty())
{
script.Description = script.Description.TrimEnd('\n').TrimEnd('\r');
}
// Extract each block from between boundaries and translate it into a ItemFilterBlock object
// and add that object to the ItemFilterBlocks list
for (var boundary = conditionBoundaries.First; boundary != null; boundary = boundary.Next)
{
var begin = boundary.Value;
@@ -49,7 +59,7 @@ namespace Filtration.Translators
var block = new string[end - begin];
Array.Copy(lines, begin, block, 0, end - begin);
var blockString = string.Join("\r\n", block);
script.LootFilterBlocks.Add(_blockTranslator.TranslateStringToLootFilterBlock(blockString));
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString));
}
return script;
@@ -78,7 +88,7 @@ namespace Filtration.Translators
return blockBoundaries;
}
public string TranslateLootFilterScriptToString(LootFilterScript script)
public string TranslateItemFilterScriptToString(ItemFilterScript script)
{
var outputString = string.Empty;
@@ -99,9 +109,9 @@ namespace Filtration.Translators
}
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var block in script.LootFilterBlocks)
foreach (var block in script.ItemFilterBlocks)
{
outputString += _blockTranslator.TranslateLootFilterBlockToString(block) + Environment.NewLine + Environment.NewLine;
outputString += _blockTranslator.TranslateItemFilterBlockToString(block) + Environment.NewLine + Environment.NewLine;
}
return outputString;

View File

@@ -26,7 +26,7 @@
VerticalAlignment="Stretch" SelectionMode="Single" x:Name="ControlListBox" BorderBrush="#CCCCCC">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<!-- Undo the style that we set in the parent LootFilterScriptView to hide the condition selections -->
<!-- Undo the style that we set in the parent ItemFilterScriptView to hide the condition selections -->
<Style.Resources>
<!-- SelectedItem with focus -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Silver" />

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Messaging;
namespace Filtration.ViewModels
{
internal interface IAvalonDockWorkspaceViewModel
{
event EventHandler ActiveDocumentChanged;
IDocument ActiveDocument { get; set; }
IItemFilterScriptViewModel ActiveScriptViewModel { get; }
void AddDocument(IDocument document);
void CloseDocument(IDocument document);
void SwitchActiveDocument(IDocument document);
}
internal class AvalonDockWorkspaceViewModel : FiltrationViewModelBase, IAvalonDockWorkspaceViewModel
{
private readonly ISectionBrowserViewModel _sectionBrowserViewModel;
private readonly IBlockGroupBrowserViewModel _blockGroupBrowserViewModel;
private IDocument _activeDocument;
private IItemFilterScriptViewModel _activeScriptViewModel;
private readonly ObservableCollection<IDocument> _openDocuments;
public AvalonDockWorkspaceViewModel(ISectionBrowserViewModel sectionBrowserViewModel,
IBlockGroupBrowserViewModel blockGroupBrowserViewModel,
IStartPageViewModel startPageViewModel)
{
_sectionBrowserViewModel = sectionBrowserViewModel;
_blockGroupBrowserViewModel = blockGroupBrowserViewModel;
_sectionBrowserViewModel.Initialise(this);
_blockGroupBrowserViewModel.Initialise(this);
_openDocuments = new ObservableCollection<IDocument> {startPageViewModel};
ActiveDocument = startPageViewModel;
}
public event EventHandler ActiveDocumentChanged;
public ObservableCollection<IDocument> OpenDocuments
{
get { return _openDocuments; }
}
public IDocument ActiveDocument
{
get { return _activeDocument; }
set
{
_activeDocument = value;
RaisePropertyChanged();
if (value.IsScript)
{
_activeScriptViewModel = (IItemFilterScriptViewModel) value;
}
else
{
_activeScriptViewModel = null;
}
if (ActiveDocumentChanged != null)
{
ActiveDocumentChanged(this, EventArgs.Empty);
}
Messenger.Default.Send(new NotificationMessage("ActiveDocumentChanged"));
}
}
public IItemFilterScriptViewModel ActiveScriptViewModel
{
get { return _activeScriptViewModel; }
}
private List<IToolViewModel> _tools;
public IEnumerable<IToolViewModel> Tools
{
get
{
if (_tools == null)
{
_tools = new List<IToolViewModel> { _sectionBrowserViewModel, _blockGroupBrowserViewModel };
}
return _tools;
}
}
public void AddDocument(IDocument document)
{
if (document.IsScript)
{
_activeScriptViewModel = (IItemFilterScriptViewModel)document;
}
OpenDocuments.Add(document);
ActiveDocument = document;
}
public void CloseDocument(IDocument document)
{
if (!OpenDocuments.Contains(document))
{
throw new ArgumentException("CloseDocument called with non-existant document");
}
if (document.IsScript)
{
_sectionBrowserViewModel.ClearDown();
_blockGroupBrowserViewModel.ClearDown();
}
OpenDocuments.Remove(document);
}
public void SwitchActiveDocument(IDocument document)
{
if (!OpenDocuments.Contains(document))
{
throw new ArgumentException("SwitchActiveDocument called with non-existant document");
}
ActiveDocument = document;
}
}
}

View File

@@ -0,0 +1,7 @@
namespace Filtration.ViewModels
{
interface IDocument
{
bool IsScript { get; }
}
}

View File

@@ -0,0 +1,8 @@
namespace Filtration.ViewModels
{
internal interface IItemFilterBlockViewModelFactory
{
IItemFilterBlockViewModel Create();
void Release(IItemFilterBlockViewModel itemFilterBlockViewModel);
}
}

View File

@@ -0,0 +1,8 @@
namespace Filtration.ViewModels
{
internal interface IItemFilterScriptViewModelFactory
{
IItemFilterScriptViewModel Create();
void Release(IItemFilterScriptViewModel itemFilterScriptViewModel);
}
}

View File

@@ -1,8 +0,0 @@
namespace Filtration.ViewModels
{
internal interface ILootFilterBlockViewModelFactory
{
ILootFilterBlockViewModel Create();
void Release(ILootFilterBlockViewModel lootFilterBlockViewModel);
}
}

View File

@@ -1,8 +0,0 @@
namespace Filtration.ViewModels
{
internal interface ILootFilterScriptViewModelFactory
{
ILootFilterScriptViewModel Create();
void Release(ILootFilterScriptViewModel lootFilterScriptViewModel);
}
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Filtration.Models;
using Filtration.Models.BlockItemBaseTypes;
@@ -11,26 +10,27 @@ using Filtration.Models.BlockItemTypes;
using Filtration.Services;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf;
using Xceed.Wpf.Toolkit;
namespace Filtration.ViewModels
{
internal interface ILootFilterBlockViewModel
internal interface IItemFilterBlockViewModel
{
void Initialise(LootFilterBlock lootFilterBlock, LootFilterScriptViewModel parentScriptViewModel);
void Initialise(ItemFilterBlock itemFilterBlock, ItemFilterScriptViewModel parentScriptViewModel);
bool IsDirty { get; set; }
LootFilterBlock Block { get; }
ItemFilterBlock Block { get; }
}
internal class LootFilterBlockViewModel : FiltrationViewModelBase, ILootFilterBlockViewModel
internal class ItemFilterBlockViewModel : FiltrationViewModelBase, IItemFilterBlockViewModel
{
private readonly IStaticDataService _staticDataService;
private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private readonly MediaPlayer _mediaPlayer = new MediaPlayer();
private LootFilterScriptViewModel _parentScriptViewModel;
private ItemFilterScriptViewModel _parentScriptViewModel;
private bool _displaySettingsPopupOpen;
public LootFilterBlockViewModel(IStaticDataService staticDataService, IReplaceColorsViewModel replaceColorsViewModel)
public ItemFilterBlockViewModel(IStaticDataService staticDataService, IReplaceColorsViewModel replaceColorsViewModel)
{
_staticDataService = staticDataService;
_replaceColorsViewModel = replaceColorsViewModel;
@@ -48,24 +48,24 @@ namespace Filtration.ViewModels
AddFilterBlockItemCommand = new RelayCommand<Type>(OnAddFilterBlockItemCommand);
ToggleBlockActionCommand = new RelayCommand(OnToggleBlockActionCommand);
AddAudioVisualBlockItemCommand = new RelayCommand<Type>(OnAddAudioVisualBlockItemCommand);
RemoveFilterBlockItemCommand = new RelayCommand<ILootFilterBlockItem>(OnRemoveFilterBlockItemCommand);
RemoveAudioVisualBlockItemCommand = new RelayCommand<ILootFilterBlockItem>(OnRemoveAudioVisualBlockItemCommand);
RemoveFilterBlockItemCommand = new RelayCommand<IItemFilterBlockItem>(OnRemoveFilterBlockItemCommand);
RemoveAudioVisualBlockItemCommand = new RelayCommand<IItemFilterBlockItem>(OnRemoveAudioVisualBlockItemCommand);
PlaySoundCommand = new RelayCommand(OnPlaySoundCommand, () => HasSound);
}
public void Initialise(LootFilterBlock lootFilterBlock, LootFilterScriptViewModel parentScriptViewModel)
public void Initialise(ItemFilterBlock itemFilterBlock, ItemFilterScriptViewModel parentScriptViewModel)
{
if (lootFilterBlock == null || parentScriptViewModel == null)
if (itemFilterBlock == null || parentScriptViewModel == null)
{
throw new ArgumentNullException("lootFilterBlock");
throw new ArgumentNullException("itemFilterBlock");
}
_parentScriptViewModel = parentScriptViewModel;
Block = lootFilterBlock;
lootFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged;
Block = itemFilterBlock;
itemFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged;
foreach (var blockItem in lootFilterBlock.BlockItems.OfType<IAudioVisualBlockItem>())
foreach (var blockItem in itemFilterBlock.BlockItems.OfType<IAudioVisualBlockItem>())
{
blockItem.PropertyChanged += OnAudioVisualBlockItemChanged;
}
@@ -84,28 +84,36 @@ namespace Filtration.ViewModels
public RelayCommand ReplaceColorsCommand { get; private set; }
public RelayCommand<Type> AddFilterBlockItemCommand { get; private set; }
public RelayCommand<Type> AddAudioVisualBlockItemCommand { get; private set; }
public RelayCommand<ILootFilterBlockItem> RemoveFilterBlockItemCommand { get; private set; }
public RelayCommand<ILootFilterBlockItem> RemoveAudioVisualBlockItemCommand { get; private set; }
public RelayCommand<IItemFilterBlockItem> RemoveFilterBlockItemCommand { get; private set; }
public RelayCommand<IItemFilterBlockItem> RemoveAudioVisualBlockItemCommand { get; private set; }
public RelayCommand PlaySoundCommand { get; private set; }
public LootFilterBlock Block { get; private set; }
public ItemFilterBlock Block { get; private set; }
public bool IsDirty { get; set; }
public ObservableCollection<ILootFilterBlockItem> FilterBlockItems
public ObservableCollection<IItemFilterBlockItem> FilterBlockItems
{
get { return Block.BlockItems; }
}
public IEnumerable<ILootFilterBlockItem> SummaryBlockItems
public IEnumerable<IItemFilterBlockItem> SummaryBlockItems
{
get { return Block.BlockItems.Where(b => !(b is IAudioVisualBlockItem)); }
}
public IEnumerable<ILootFilterBlockItem> AudioVisualBlockItems
public IEnumerable<IItemFilterBlockItem> AudioVisualBlockItems
{
get { return Block.BlockItems.Where(b => b is IAudioVisualBlockItem); }
}
public bool AdvancedBlockGroup
{
get
{
return Block.BlockGroup != null && Block.BlockGroup.Advanced;
}
}
public bool DisplaySettingsPopupOpen
{
get { return _displaySettingsPopupOpen; }
@@ -189,8 +197,22 @@ namespace Filtration.ViewModels
}
set
{
Block.Description = value;
RaisePropertyChanged();
if (Block.Description != value)
{
Block.Description = value;
IsDirty = true;
RaisePropertyChanged();
}
}
}
public ObservableCollection<ColorItem> AvailableColors
{
get
{
{
return PathOfExileColors.DefaultColors;
}
}
}
@@ -261,13 +283,13 @@ namespace Filtration.ViewModels
private void OnAddFilterBlockItemCommand(Type blockItemType)
{
if (!AddBlockItemAllowed(blockItemType)) return;
var newBlockItem = (ILootFilterBlockItem) Activator.CreateInstance(blockItemType);
var newBlockItem = (IItemFilterBlockItem) Activator.CreateInstance(blockItemType);
FilterBlockItems.Add(newBlockItem);
IsDirty = true;
}
private void OnRemoveFilterBlockItemCommand(ILootFilterBlockItem blockItem)
private void OnRemoveFilterBlockItemCommand(IItemFilterBlockItem blockItem)
{
FilterBlockItems.Remove(blockItem);
IsDirty = true;
@@ -276,7 +298,7 @@ namespace Filtration.ViewModels
private void OnAddAudioVisualBlockItemCommand(Type blockItemType)
{
if (!AddBlockItemAllowed(blockItemType)) return;
var newBlockItem = (ILootFilterBlockItem) Activator.CreateInstance(blockItemType);
var newBlockItem = (IItemFilterBlockItem) Activator.CreateInstance(blockItemType);
newBlockItem.PropertyChanged += OnAudioVisualBlockItemChanged;
FilterBlockItems.Add(newBlockItem);
@@ -284,7 +306,7 @@ namespace Filtration.ViewModels
IsDirty = true;
}
private void OnRemoveAudioVisualBlockItemCommand(ILootFilterBlockItem blockItem)
private void OnRemoveAudioVisualBlockItemCommand(IItemFilterBlockItem blockItem)
{
blockItem.PropertyChanged -= OnAudioVisualBlockItemChanged;
FilterBlockItems.Remove(blockItem);
@@ -347,7 +369,7 @@ namespace Filtration.ViewModels
private bool AddBlockItemAllowed(Type type)
{
var blockItem = (ILootFilterBlockItem)Activator.CreateInstance(type);
var blockItem = (IItemFilterBlockItem)Activator.CreateInstance(type);
var blockCount = FilterBlockItems.Count(b => b.GetType() == type);
return blockCount < blockItem.MaximumAllowed;
}

View File

@@ -0,0 +1,601 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Forms;
using Castle.Core.Internal;
using Filtration.Enums;
using Filtration.Models;
using Filtration.Services;
using Filtration.Translators;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Clipboard = System.Windows.Clipboard;
using MessageBox = System.Windows.MessageBox;
namespace Filtration.ViewModels
{
internal interface IItemFilterScriptViewModel : IDocument
{
ItemFilterScript Script { get; }
IItemFilterBlockViewModel SelectedBlockViewModel { get; set; }
IItemFilterBlockViewModel SectionBrowserSelectedBlockViewModel { get; set; }
IEnumerable<ItemFilterBlockGroup> BlockGroups { get; }
IEnumerable<IItemFilterBlockViewModel> ItemFilterSectionViewModels { get; }
Predicate<IItemFilterBlockViewModel> BlockFilterPredicate { get; set; }
bool IsDirty { get; }
bool ShowAdvanced { get; }
string Description { get; set; }
string DisplayName { get; }
void Initialise(ItemFilterScript itemFilterScript, bool newScript);
void RemoveDirtyFlag();
void SaveScript();
void SaveScriptAs();
void Close();
void AddSection(IItemFilterBlockViewModel targetBlockViewModel);
void AddBlock(IItemFilterBlockViewModel targetBlockViewModel);
void CopyBlock(IItemFilterBlockViewModel targetBlockViewModel);
void PasteBlock(IItemFilterBlockViewModel targetBlockViewModel);
}
internal class ItemFilterScriptViewModel : PaneViewModel, IItemFilterScriptViewModel
{
private readonly IItemFilterBlockViewModelFactory _itemFilterBlockViewModelFactory;
private readonly IItemFilterBlockTranslator _blockTranslator;
private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
private readonly IItemFilterPersistenceService _persistenceService;
private bool _isDirty;
private IItemFilterBlockViewModel _selectedBlockViewModel;
private IItemFilterBlockViewModel _sectionBrowserSelectedBlockViewModel;
private readonly ObservableCollection<IItemFilterBlockViewModel> _itemFilterBlockViewModels;
private ICollectionView _itemFilterBlockViewModelsCollectionView;
private Predicate<IItemFilterBlockViewModel> _blockFilterPredicate;
public ItemFilterScriptViewModel(IItemFilterBlockViewModelFactory itemFilterBlockViewModelFactory,
IItemFilterBlockTranslator blockTranslator,
IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel,
IItemFilterPersistenceService persistenceService)
{
_itemFilterBlockViewModelFactory = itemFilterBlockViewModelFactory;
_blockTranslator = blockTranslator;
_avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel;
_avalonDockWorkspaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged;
_persistenceService = persistenceService;
_itemFilterBlockViewModels = new ObservableCollection<IItemFilterBlockViewModel>();
ToggleShowAdvancedCommand = new RelayCommand<bool>(OnToggleShowAdvancedCommand);
ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null);
CloseCommand = new RelayCommand(OnCloseCommand);
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => SelectedBlockViewModel != null);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => SelectedBlockViewModel != null);
AddBlockCommand = new RelayCommand(OnAddBlockCommand);
AddSectionCommand = new RelayCommand(OnAddSectionCommand, () => SelectedBlockViewModel != null);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null);
PasteBlockCommand = new RelayCommand(OnPasteBlockCommand, () => SelectedBlockViewModel != null);
}
public RelayCommand<bool> ToggleShowAdvancedCommand { get; private set; }
public RelayCommand ClearFilterCommand { get; private set; }
public RelayCommand CloseCommand { get; private set; }
public RelayCommand DeleteBlockCommand { get; private set; }
public RelayCommand MoveBlockToTopCommand { get; private set; }
public RelayCommand MoveBlockUpCommand { get; private set; }
public RelayCommand MoveBlockDownCommand { get; private set; }
public RelayCommand MoveBlockToBottomCommand { get; private set; }
public RelayCommand AddBlockCommand { get; private set; }
public RelayCommand AddSectionCommand { get; private set; }
public RelayCommand CopyBlockCommand { get; private set; }
public RelayCommand PasteBlockCommand { get; private set; }
public ObservableCollection<IItemFilterBlockViewModel> ItemFilterBlockViewModels
{
get
{
_itemFilterBlockViewModelsCollectionView =
CollectionViewSource.GetDefaultView(_itemFilterBlockViewModels);
if (BlockFilterPredicate != null)
{
_itemFilterBlockViewModelsCollectionView.Filter = BlockFilter;
}
else
{
_itemFilterBlockViewModelsCollectionView.Filter = null;
}
return _itemFilterBlockViewModels;
}
}
private bool BlockFilter(object item)
{
var blockViewModel = item as IItemFilterBlockViewModel;
return BlockFilterPredicate(blockViewModel);
}
public Predicate<IItemFilterBlockViewModel> BlockFilterPredicate
{
get { return _blockFilterPredicate; }
set
{
_blockFilterPredicate = value;
RaisePropertyChanged("ItemFilterBlockViewModels");
}
}
public ObservableCollection<IItemFilterBlockViewModel> DisplayedItemFilterBlockViewModels { get; private set; }
public IEnumerable<IItemFilterBlockViewModel> ItemFilterSectionViewModels
{
get { return ItemFilterBlockViewModels.Where(b => b.Block.GetType() == typeof (ItemFilterSection)); }
}
public bool IsScript
{
get { return true; }
}
public string Description
{
get { return Script.Description; }
set
{
Script.Description = value;
IsDirty = true;
RaisePropertyChanged();
}
}
public bool ShowAdvanced
{
get { return _showAdvanced; }
private set
{
_showAdvanced = value;
RaisePropertyChanged();
}
}
public IItemFilterBlockViewModel SelectedBlockViewModel
{
get { return _selectedBlockViewModel; }
set
{
_selectedBlockViewModel = value;
RaisePropertyChanged();
}
}
public IItemFilterBlockViewModel SectionBrowserSelectedBlockViewModel
{
get { return _sectionBrowserSelectedBlockViewModel; }
set
{
_sectionBrowserSelectedBlockViewModel = value;
SelectedBlockViewModel = value;
RaisePropertyChanged();
}
}
public ItemFilterScript Script { get; private set; }
public IEnumerable<ItemFilterBlockGroup> BlockGroups
{
get { return Script.ItemFilterBlockGroups; }
}
public bool IsDirty
{
get { return _isDirty || HasDirtyChildren; }
set
{
if (_isDirty != value)
{
_isDirty = value;
if (_isDirty)
{
Title = Filename + "*";
}
else
{
Title = Filename;
}
}
}
}
public void RemoveDirtyFlag()
{
CleanChildren();
IsDirty = false;
RaisePropertyChanged("Filename");
RaisePropertyChanged("DisplayName");
}
public string DisplayName
{
get { return !string.IsNullOrEmpty(Filename) ? Filename : Description; }
}
public string Filename
{
get { return Path.GetFileName(Script.FilePath); }
}
public string Filepath
{
get { return Script.FilePath; }
}
private bool _filenameIsFake;
private bool _showAdvanced;
public void Initialise(ItemFilterScript itemFilterScript, bool newScript)
{
ItemFilterBlockViewModels.Clear();
Script = itemFilterScript;
foreach (var block in Script.ItemFilterBlocks)
{
var vm = _itemFilterBlockViewModelFactory.Create();
vm.Initialise(block, this);
ItemFilterBlockViewModels.Add(vm);
}
_filenameIsFake = newScript;
if (newScript)
{
Script.FilePath = "Untitled.filter";
}
Title = Filename;
ContentId = "testcontentid";
}
public void SaveScript()
{
if (!ValidateScript()) return;
if (_filenameIsFake)
{
SaveScriptAs();
return;
}
try
{
_persistenceService.SaveItemFilterScript(Script);
RemoveDirtyFlag();
}
catch (Exception e)
{
MessageBox.Show(@"Error saving filter file - " + e.Message, @"Save Error", MessageBoxButton.OK,
MessageBoxImage.Error);
}
}
public void SaveScriptAs()
{
if (!ValidateScript()) return;
var saveDialog = new SaveFileDialog
{
DefaultExt = ".filter",
Filter = @"Filter Files (*.filter)|*.filter|All Files (*.*)|*.*",
InitialDirectory = _persistenceService.ItemFilterScriptDirectory
};
var result = saveDialog.ShowDialog();
if (result != DialogResult.OK) return;
var previousFilePath = Script.FilePath;
try
{
Script.FilePath = saveDialog.FileName;
_persistenceService.SaveItemFilterScript(Script);
_filenameIsFake = false;
Title = Filename;
RemoveDirtyFlag();
}
catch (Exception e)
{
MessageBox.Show(@"Error saving filter file - " + e.Message, @"Save Error", MessageBoxButton.OK,
MessageBoxImage.Error);
Script.FilePath = previousFilePath;
}
}
private void OnActiveDocumentChanged(object sender, EventArgs e)
{
if (_avalonDockWorkspaceViewModel.ActiveScriptViewModel != this)
{
BlockFilterPredicate = null;
}
}
private bool HasDirtyChildren
{
get { return ItemFilterBlockViewModels.Any(vm => vm.IsDirty); }
}
private void CleanChildren()
{
foreach (var vm in ItemFilterBlockViewModels)
{
vm.IsDirty = false;
}
}
private bool ValidateScript()
{
var result = Script.Validate();
if (result.Count == 0) return true;
var failures = string.Empty;
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (string failure in result)
{
failures += failure + Environment.NewLine;
}
var messageText = "The following script validation errors occurred:" + Environment.NewLine + failures;
MessageBox.Show(messageText, "Script Validation Failure", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return false;
}
private void OnCloseCommand()
{
Close();
}
public void Close()
{
if (!IsDirty)
{
CloseScript();
}
else
{
var result = MessageBox.Show(@"Want to save your changes to this script?",
@"Filtration", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
switch (result)
{
case MessageBoxResult.Yes:
{
SaveScript();
CloseScript();
break;
}
case MessageBoxResult.No:
{
CloseScript();
break;
}
case MessageBoxResult.Cancel:
{
return;
}
}
}
}
private void CloseScript()
{
_avalonDockWorkspaceViewModel.ActiveDocumentChanged -= OnActiveDocumentChanged;
_avalonDockWorkspaceViewModel.CloseDocument(this);
}
private void OnToggleShowAdvancedCommand(bool showAdvanced)
{
ShowAdvanced = !ShowAdvanced;
Messenger.Default.Send(new NotificationMessage<bool>(ShowAdvanced, "ShowAdvancedToggled"));
}
private void OnClearFilterCommand()
{
BlockFilterPredicate = null;
}
private void OnCopyBlockCommand()
{
CopyBlock(SelectedBlockViewModel);
}
public void CopyBlock(IItemFilterBlockViewModel targetBlockViewModel)
{
Clipboard.SetText(_blockTranslator.TranslateItemFilterBlockToString(SelectedBlockViewModel.Block));
}
private void OnPasteBlockCommand()
{
PasteBlock(SelectedBlockViewModel);
}
public void PasteBlock(IItemFilterBlockViewModel targetBlockViewModel)
{
var clipboardText = Clipboard.GetText();
if (clipboardText.IsNullOrEmpty()) return;
var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText);
if (translatedBlock == null) return;
var vm = _itemFilterBlockViewModelFactory.Create();
vm.Initialise(translatedBlock, this);
if (ItemFilterBlockViewModels.Count > 0)
{
Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, translatedBlock);
ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
}
else
{
Script.ItemFilterBlocks.Add(translatedBlock);
ItemFilterBlockViewModels.Add(vm);
}
SelectedBlockViewModel = vm;
IsDirty = true;
}
private void OnMoveBlockToTopCommand()
{
MoveBlockToTop(SelectedBlockViewModel);
}
public void MoveBlockToTop(IItemFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex > 0)
{
var block = targetBlockViewModel.Block;
Script.ItemFilterBlocks.Remove(block);
Script.ItemFilterBlocks.Insert(0, block);
ItemFilterBlockViewModels.Move(currentIndex, 0);
IsDirty = true;
RaisePropertyChanged("ItemFilterSectionViewModels");
}
}
private void OnMoveBlockUpCommand()
{
MoveBlockUp(SelectedBlockViewModel);
}
public void MoveBlockUp(IItemFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex > 0)
{
var block = targetBlockViewModel.Block;
var blockPos = Script.ItemFilterBlocks.IndexOf(block);
Script.ItemFilterBlocks.RemoveAt(blockPos);
Script.ItemFilterBlocks.Insert(blockPos - 1, block);
ItemFilterBlockViewModels.Move(currentIndex, currentIndex - 1);
IsDirty = true;
RaisePropertyChanged("ItemFilterSectionViewModels");
}
}
private void OnMoveBlockDownCommand()
{
MoveBlockDown(SelectedBlockViewModel);
}
public void MoveBlockDown(IItemFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex < ItemFilterBlockViewModels.Count - 1)
{
var block = targetBlockViewModel.Block;
var blockPos = Script.ItemFilterBlocks.IndexOf(block);
Script.ItemFilterBlocks.RemoveAt(blockPos);
Script.ItemFilterBlocks.Insert(blockPos + 1, block);
ItemFilterBlockViewModels.Move(currentIndex, currentIndex + 1);
IsDirty = true;
RaisePropertyChanged("ItemFilterSectionViewModels");
}
}
private void OnMoveBlockToBottomCommand()
{
MoveBlockToBottom(SelectedBlockViewModel);
}
public void MoveBlockToBottom(IItemFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex < ItemFilterBlockViewModels.Count - 1)
{
var block = targetBlockViewModel.Block;
Script.ItemFilterBlocks.Remove(block);
Script.ItemFilterBlocks.Add(block);
ItemFilterBlockViewModels.Move(currentIndex, ItemFilterBlockViewModels.Count - 1);
IsDirty = true;
RaisePropertyChanged("ItemFilterSectionViewModels");
}
}
private void OnAddBlockCommand()
{
AddBlock(SelectedBlockViewModel);
}
public void AddBlock(IItemFilterBlockViewModel targetBlockViewModel)
{
var vm = _itemFilterBlockViewModelFactory.Create();
var newBlock = new ItemFilterBlock();
vm.Initialise(newBlock, this);
if (targetBlockViewModel != null)
{
Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, newBlock);
ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
}
else
{
Script.ItemFilterBlocks.Add(newBlock);
ItemFilterBlockViewModels.Add(vm);
}
SelectedBlockViewModel = vm;
IsDirty = true;
}
private void OnAddSectionCommand()
{
AddSection(SelectedBlockViewModel);
}
public void AddSection(IItemFilterBlockViewModel targetBlockViewModel)
{
var vm = _itemFilterBlockViewModelFactory.Create();
var newSection = new ItemFilterSection { Description = "New Section" };
vm.Initialise(newSection, this);
Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, newSection);
ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
IsDirty = true;
SelectedBlockViewModel = vm;
RaisePropertyChanged("ItemFilterSectionViewModels");
}
private void OnDeleteBlockCommand()
{
DeleteBlock(SelectedBlockViewModel);
}
public void DeleteBlock(IItemFilterBlockViewModel targetBlockViewModel)
{
var result = MessageBox.Show("Are you sure you wish to delete this block?", "Delete Confirmation",
MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
Script.ItemFilterBlocks.Remove(targetBlockViewModel.Block);
ItemFilterBlockViewModels.Remove(targetBlockViewModel);
IsDirty = true;
}
SelectedBlockViewModel = null;
}
}
}

View File

@@ -1,340 +0,0 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Windows;
using Castle.Core.Internal;
using Filtration.Models;
using Filtration.Translators;
using GalaSoft.MvvmLight.CommandWpf;
namespace Filtration.ViewModels
{
internal interface ILootFilterScriptViewModel
{
LootFilterScript Script { get; }
bool IsDirty { get; }
string Description { get; set; }
string DisplayName { get; }
void Initialise(LootFilterScript lootFilterScript);
ILootFilterBlockViewModel SelectedBlockViewModel { get; set; }
void RemoveDirtyFlag();
void AddSection(ILootFilterBlockViewModel targetBlockViewModel);
void AddBlock(ILootFilterBlockViewModel targetBlockViewModel);
void CopyBlock(ILootFilterBlockViewModel targetBlockViewModel);
void PasteBlock(ILootFilterBlockViewModel targetBlockViewModel);
}
internal class LootFilterScriptViewModel : FiltrationViewModelBase, ILootFilterScriptViewModel
{
private readonly ILootFilterBlockViewModelFactory _lootFilterBlockViewModelFactory;
private readonly ILootFilterBlockTranslator _blockTranslator;
private bool _isDirty;
private ILootFilterBlockViewModel _selectedBlockViewModel;
public LootFilterScriptViewModel(ILootFilterBlockViewModelFactory lootFilterBlockViewModelFactory, ILootFilterBlockTranslator blockTranslator)
{
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => SelectedBlockViewModel != null);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => SelectedBlockViewModel != null);
AddBlockCommand = new RelayCommand(OnAddBlockCommand);
AddSectionCommand = new RelayCommand(OnAddSectionCommand, () => SelectedBlockViewModel != null);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null);
PasteBlockCommand = new RelayCommand(OnPasteBlockCommand, () => SelectedBlockViewModel != null);
_lootFilterBlockViewModelFactory = lootFilterBlockViewModelFactory;
_blockTranslator = blockTranslator;
LootFilterBlockViewModels = new ObservableCollection<ILootFilterBlockViewModel>();
}
public RelayCommand DeleteBlockCommand { get; private set; }
public RelayCommand MoveBlockToTopCommand { get; private set; }
public RelayCommand MoveBlockUpCommand { get; private set; }
public RelayCommand MoveBlockDownCommand { get; private set; }
public RelayCommand MoveBlockToBottomCommand { get; private set; }
public RelayCommand AddBlockCommand { get; private set; }
public RelayCommand AddSectionCommand { get; private set; }
public RelayCommand CopyBlockCommand { get; private set; }
public RelayCommand PasteBlockCommand { get; private set; }
public ObservableCollection<ILootFilterBlockViewModel> LootFilterBlockViewModels { get; private set; }
public IEnumerable<ILootFilterBlockViewModel> LootFilterSectionViewModels
{
get { return LootFilterBlockViewModels.Where(b => b.Block.GetType() == typeof (LootFilterSection)); }
}
public ILootFilterBlockViewModel SectionBrowserSelectedViewModel { get; set; }
public string Description
{
get { return Script.Description; }
set
{
Script.Description = value;
_isDirty = true;
RaisePropertyChanged();
}
}
public ILootFilterBlockViewModel SelectedBlockViewModel
{
get { return _selectedBlockViewModel; }
set
{
_selectedBlockViewModel = value;
RaisePropertyChanged();
}
}
public LootFilterScript Script { get; private set; }
public bool IsDirty
{
get { return _isDirty || HasDirtyChildren; }
set
{
_isDirty = value;
}
}
private bool HasDirtyChildren
{
get { return LootFilterBlockViewModels.Any(vm => vm.IsDirty); }
}
private void CleanChildren()
{
foreach (var vm in LootFilterBlockViewModels)
{
vm.IsDirty = false;
}
}
public void RemoveDirtyFlag()
{
CleanChildren();
IsDirty = false;
RaisePropertyChanged("Filename");
RaisePropertyChanged("DisplayName");
}
public string DisplayName
{
get { return !string.IsNullOrEmpty(Filename) ? Filename : Description; }
}
public string Filename
{
get { return Path.GetFileName(Script.FilePath); }
}
public string Filepath
{
get { return Script.FilePath; }
}
public void Initialise(LootFilterScript lootFilterScript)
{
LootFilterBlockViewModels.Clear();
Script = lootFilterScript;
foreach (var block in Script.LootFilterBlocks)
{
var vm = _lootFilterBlockViewModelFactory.Create();
vm.Initialise(block, this);
LootFilterBlockViewModels.Add(vm);
}
}
private void OnCopyBlockCommand()
{
CopyBlock(SelectedBlockViewModel);
}
public void CopyBlock(ILootFilterBlockViewModel targetBlockViewModel)
{
Clipboard.SetText(_blockTranslator.TranslateLootFilterBlockToString(SelectedBlockViewModel.Block));
}
private void OnPasteBlockCommand()
{
PasteBlock(SelectedBlockViewModel);
}
public void PasteBlock(ILootFilterBlockViewModel targetBlockViewModel)
{
var clipboardText = Clipboard.GetText();
if (clipboardText.IsNullOrEmpty()) return;
var translatedBlock = _blockTranslator.TranslateStringToLootFilterBlock(clipboardText);
if (translatedBlock == null) return;
var vm = _lootFilterBlockViewModelFactory.Create();
vm.Initialise(translatedBlock, this);
if (LootFilterBlockViewModels.Count > 0)
{
Script.LootFilterBlocks.Insert(Script.LootFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, translatedBlock);
LootFilterBlockViewModels.Insert(LootFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
}
else
{
Script.LootFilterBlocks.Add(translatedBlock);
LootFilterBlockViewModels.Add(vm);
}
SelectedBlockViewModel = vm;
_isDirty = true;
}
private void OnMoveBlockToTopCommand()
{
MoveBlockToTop(SelectedBlockViewModel);
}
public void MoveBlockToTop(ILootFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = LootFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex > 0)
{
var block = targetBlockViewModel.Block;
Script.LootFilterBlocks.Remove(block);
Script.LootFilterBlocks.Insert(0, block);
LootFilterBlockViewModels.Move(currentIndex, 0);
_isDirty = true;
RaisePropertyChanged("LootFilterSectionViewModels");
}
}
private void OnMoveBlockUpCommand()
{
MoveBlockUp(SelectedBlockViewModel);
}
public void MoveBlockUp(ILootFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = LootFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex > 0)
{
var block = targetBlockViewModel.Block;
var blockPos = Script.LootFilterBlocks.IndexOf(block);
Script.LootFilterBlocks.RemoveAt(blockPos);
Script.LootFilterBlocks.Insert(blockPos - 1, block);
LootFilterBlockViewModels.Move(currentIndex, currentIndex - 1);
_isDirty = true;
RaisePropertyChanged("LootFilterSectionViewModels");
}
}
private void OnMoveBlockDownCommand()
{
MoveBlockDown(SelectedBlockViewModel);
}
public void MoveBlockDown(ILootFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = LootFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex < LootFilterBlockViewModels.Count - 1)
{
var block = targetBlockViewModel.Block;
var blockPos = Script.LootFilterBlocks.IndexOf(block);
Script.LootFilterBlocks.RemoveAt(blockPos);
Script.LootFilterBlocks.Insert(blockPos + 1, block);
LootFilterBlockViewModels.Move(currentIndex, currentIndex + 1);
_isDirty = true;
RaisePropertyChanged("LootFilterSectionViewModels");
}
}
private void OnMoveBlockToBottomCommand()
{
MoveBlockToBottom(SelectedBlockViewModel);
}
public void MoveBlockToBottom(ILootFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = LootFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex < LootFilterBlockViewModels.Count - 1)
{
var block = targetBlockViewModel.Block;
Script.LootFilterBlocks.Remove(block);
Script.LootFilterBlocks.Add(block);
LootFilterBlockViewModels.Move(currentIndex, LootFilterBlockViewModels.Count - 1);
_isDirty = true;
RaisePropertyChanged("LootFilterSectionViewModels");
}
}
private void OnAddBlockCommand()
{
AddBlock(SelectedBlockViewModel);
}
public void AddBlock(ILootFilterBlockViewModel targetBlockViewModel)
{
var vm = _lootFilterBlockViewModelFactory.Create();
var newBlock = new LootFilterBlock();
vm.Initialise(newBlock, this);
if (targetBlockViewModel != null)
{
Script.LootFilterBlocks.Insert(Script.LootFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, newBlock);
LootFilterBlockViewModels.Insert(LootFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
}
else
{
Script.LootFilterBlocks.Add(newBlock);
LootFilterBlockViewModels.Add(vm);
}
SelectedBlockViewModel = vm;
_isDirty = true;
}
private void OnAddSectionCommand()
{
AddSection(SelectedBlockViewModel);
}
public void AddSection(ILootFilterBlockViewModel targetBlockViewModel)
{
var vm = _lootFilterBlockViewModelFactory.Create();
var newSection = new LootFilterSection { Description = "New Section" };
vm.Initialise(newSection, this);
Script.LootFilterBlocks.Insert(Script.LootFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, newSection);
LootFilterBlockViewModels.Insert(LootFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
_isDirty = true;
SelectedBlockViewModel = vm;
RaisePropertyChanged("LootFilterSectionViewModels");
}
private void OnDeleteBlockCommand()
{
DeleteBlock(SelectedBlockViewModel);
}
public void DeleteBlock(ILootFilterBlockViewModel targetBlockViewModel)
{
var result = MessageBox.Show("Are you sure you wish to delete this block?", "Delete Confirmation",
MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
Script.LootFilterBlocks.Remove(targetBlockViewModel.Block);
LootFilterBlockViewModels.Remove(targetBlockViewModel);
_isDirty = true;
}
SelectedBlockViewModel = null;
}
}
}

View File

@@ -1,15 +1,15 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using Castle.Core;
using Filtration.Models;
using Filtration.Services;
using Filtration.Translators;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Clipboard = System.Windows.Clipboard;
using MessageBox = System.Windows.Forms.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
namespace Filtration.ViewModels
@@ -17,45 +17,76 @@ namespace Filtration.ViewModels
internal interface IMainWindowViewModel
{
void LoadScriptFromFile(string path);
RelayCommand OpenScriptCommand { get; }
RelayCommand NewScriptCommand { get; }
}
internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel
{
private LootFilterScript _loadedScript;
private readonly ILootFilterScriptViewModelFactory _lootFilterScriptViewModelFactory;
private readonly ILootFilterPersistenceService _persistenceService;
private readonly ILootFilterScriptTranslator _lootFilterScriptTranslator;
private readonly IItemFilterScriptViewModelFactory _itemFilterScriptViewModelFactory;
private readonly IItemFilterPersistenceService _persistenceService;
private readonly IItemFilterScriptTranslator _itemFilterScriptTranslator;
private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private ILootFilterScriptViewModel _currentScriptViewModel;
private readonly ObservableCollection<ILootFilterScriptViewModel> _scriptViewModels;
private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
public MainWindowViewModel(ILootFilterScriptViewModelFactory lootFilterScriptViewModelFactory,
ILootFilterPersistenceService persistenceService,
ILootFilterScriptTranslator lootFilterScriptTranslator,
IReplaceColorsViewModel replaceColorsViewModel)
private IDocument _activeDocument;
public MainWindowViewModel(IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory,
IItemFilterPersistenceService persistenceService,
IItemFilterScriptTranslator itemFilterScriptTranslator,
IReplaceColorsViewModel replaceColorsViewModel,
IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel)
{
_lootFilterScriptViewModelFactory = lootFilterScriptViewModelFactory;
_itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory;
_persistenceService = persistenceService;
_lootFilterScriptTranslator = lootFilterScriptTranslator;
_itemFilterScriptTranslator = itemFilterScriptTranslator;
_replaceColorsViewModel = replaceColorsViewModel;
_scriptViewModels = new ObservableCollection<ILootFilterScriptViewModel>();
_avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel;
OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand);
OpenScriptCommand = new RelayCommand(OnOpenScriptCommand);
SaveScriptCommand = new RelayCommand(OnSaveScriptCommand, () => CurrentScriptViewModel != null);
SaveScriptAsCommand = new RelayCommand(OnSaveScriptAsCommand, () => CurrentScriptViewModel != null);
CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, () => CurrentScriptViewModel != null);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => CurrentScriptViewModel != null && CurrentScriptViewModel.SelectedBlockViewModel != null);
PasteCommand = new RelayCommand(OnPasteCommand, () => CurrentScriptViewModel != null && CurrentScriptViewModel.SelectedBlockViewModel != null);
SaveScriptCommand = new RelayCommand(OnSaveScriptCommand, ActiveDocumentIsScript);
SaveScriptAsCommand = new RelayCommand(OnSaveScriptAsCommand, ActiveDocumentIsScript);
CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, ActiveDocumentIsScript);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocumentIsScript() && (_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null));
PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocumentIsScript() && (_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null));
NewScriptCommand = new RelayCommand(OnNewScriptCommand);
CloseScriptCommand = new RelayCommand<ILootFilterScriptViewModel>(OnCloseScriptCommand, v => CurrentScriptViewModel != null);
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => CurrentScriptViewModel != null);
CloseScriptCommand = new RelayCommand(OnCloseScriptCommand, ActiveDocumentIsScript);
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, ActiveDocumentIsScript);
//LoadScriptFromFile("C:\\ThioleLootFilter.txt");
SetLootFilterScriptDirectory();
SetItemFilterScriptDirectory();
Messenger.Default.Register<NotificationMessage>(this, message =>
{
switch (message.Notification)
{
case "ActiveDocumentChanged":
{
_activeDocument = _avalonDockWorkspaceViewModel.ActiveDocument;
SaveScriptCommand.RaiseCanExecuteChanged();
SaveScriptAsCommand.RaiseCanExecuteChanged();
CopyScriptCommand.RaiseCanExecuteChanged();
CopyBlockCommand.RaiseCanExecuteChanged();
PasteCommand.RaiseCanExecuteChanged();
NewScriptCommand.RaiseCanExecuteChanged();
CloseScriptCommand.RaiseCanExecuteChanged();
ReplaceColorsCommand.RaiseCanExecuteChanged();
break;
}
case "NewScript":
{
OnNewScriptCommand();
break;
}
case "OpenScript":
{
OnOpenScriptCommand();
break;
}
}
});
}
public RelayCommand OpenScriptCommand { get; private set; }
@@ -65,13 +96,13 @@ namespace Filtration.ViewModels
public RelayCommand PasteCommand { get; private set; }
public RelayCommand CopyScriptCommand { get; private set; }
public RelayCommand NewScriptCommand { get; private set; }
public RelayCommand<ILootFilterScriptViewModel> CloseScriptCommand { get; private set; }
public RelayCommand CloseScriptCommand { get; private set; }
public RelayCommand OpenAboutWindowCommand { get; private set; }
public RelayCommand ReplaceColorsCommand { get; private set; }
public ObservableCollection<ILootFilterScriptViewModel> ScriptViewModels
public IAvalonDockWorkspaceViewModel AvalonDockWorkspaceViewModel
{
get { return _scriptViewModels; }
get { return _avalonDockWorkspaceViewModel; }
}
public string WindowTitle
@@ -84,23 +115,9 @@ namespace Filtration.ViewModels
}
}
[DoNotWire]
public ILootFilterScriptViewModel CurrentScriptViewModel
private bool ActiveDocumentIsScript()
{
get { return _currentScriptViewModel; }
set
{
_currentScriptViewModel = value;
RaisePropertyChanged();
RaisePropertyChanged("NoScriptsOpen");
SaveScriptCommand.RaiseCanExecuteChanged();
SaveScriptAsCommand.RaiseCanExecuteChanged();
}
}
public bool NoScriptsOpen
{
get { return _currentScriptViewModel == null; }
return _activeDocument != null && _activeDocument.IsScript;
}
private void OnOpenAboutWindowCommand()
@@ -114,7 +131,7 @@ namespace Filtration.ViewModels
var openFileDialog = new OpenFileDialog
{
Filter = "Filter Files (*.filter)|*.filter|All Files (*.*)|*.*",
InitialDirectory = _persistenceService.LootFilterScriptDirectory
InitialDirectory = _persistenceService.ItemFilterScriptDirectory
};
if (openFileDialog.ShowDialog() != true) return;
@@ -124,9 +141,10 @@ namespace Filtration.ViewModels
public void LoadScriptFromFile(string path)
{
var loadedScript = _persistenceService.LoadItemFilterScript(path);
try
{
_loadedScript = _persistenceService.LoadLootFilterScript(path);
}
catch (Exception e)
{
@@ -135,18 +153,17 @@ namespace Filtration.ViewModels
return;
}
var newViewModel = _lootFilterScriptViewModelFactory.Create();
newViewModel.Initialise(_loadedScript);
ScriptViewModels.Add(newViewModel);
CurrentScriptViewModel = newViewModel;
var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(loadedScript, false);
_avalonDockWorkspaceViewModel.AddDocument(newViewModel);
}
private void SetLootFilterScriptDirectory()
private void SetItemFilterScriptDirectory()
{
var defaultDir = _persistenceService.DefaultPathOfExileDirectory();
if (!string.IsNullOrEmpty(defaultDir))
{
_persistenceService.LootFilterScriptDirectory = defaultDir;
_persistenceService.ItemFilterScriptDirectory = defaultDir;
}
else
{
@@ -159,145 +176,54 @@ namespace Filtration.ViewModels
if (result == DialogResult.OK)
{
_persistenceService.LootFilterScriptDirectory = dlg.SelectedPath;
_persistenceService.ItemFilterScriptDirectory = dlg.SelectedPath;
}
}
}
private void OnSaveScriptCommand()
{
if (!ValidateScript()) return;
if (string.IsNullOrEmpty(CurrentScriptViewModel.Script.FilePath))
{
OnSaveScriptAsCommand();
return;
}
try
{
_persistenceService.SaveLootFilterScript(CurrentScriptViewModel.Script);
CurrentScriptViewModel.RemoveDirtyFlag();
}
catch (Exception e)
{
MessageBox.Show(@"Error saving filter file - " + e.Message, @"Save Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SaveScript();
}
private void OnSaveScriptAsCommand()
{
if (!ValidateScript()) return;
var saveDialog = new SaveFileDialog
{
DefaultExt = ".filter",
Filter = @"Filter Files (*.filter)|*.filter|All Files (*.*)|*.*",
InitialDirectory = _persistenceService.LootFilterScriptDirectory
};
var result = saveDialog.ShowDialog();
if (result != DialogResult.OK) return;
var previousFilePath = CurrentScriptViewModel.Script.FilePath;
try
{
CurrentScriptViewModel.Script.FilePath = saveDialog.FileName;
_persistenceService.SaveLootFilterScript(CurrentScriptViewModel.Script);
CurrentScriptViewModel.RemoveDirtyFlag();
}
catch (Exception e)
{
MessageBox.Show(@"Error saving filter file - " + e.Message, @"Save Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
CurrentScriptViewModel.Script.FilePath = previousFilePath;
}
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SaveScriptAs();
}
private void OnReplaceColorsCommand()
{
_replaceColorsViewModel.Initialise(CurrentScriptViewModel.Script);
_replaceColorsViewModel.Initialise(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script);
var replaceColorsWindow = new ReplaceColorsWindow {DataContext = _replaceColorsViewModel};
replaceColorsWindow.ShowDialog();
}
private bool ValidateScript()
{
var result = CurrentScriptViewModel.Script.Validate();
if (result.Count == 0) return true;
var failures = string.Empty;
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (string failure in result)
{
failures += failure + Environment.NewLine;
}
MessageBox.Show(@"The following script validation errors occurred:" + Environment.NewLine + failures,
@"Script Validation Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
private void OnCopyScriptCommand()
{
Clipboard.SetText(_lootFilterScriptTranslator.TranslateLootFilterScriptToString(_currentScriptViewModel.Script));
Clipboard.SetText(_itemFilterScriptTranslator.TranslateItemFilterScriptToString(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script));
}
private void OnCopyBlockCommand()
{
_currentScriptViewModel.CopyBlock(_currentScriptViewModel.SelectedBlockViewModel);
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.CopyBlock(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel);
}
private void OnPasteCommand()
{
_currentScriptViewModel.PasteBlock(_currentScriptViewModel.SelectedBlockViewModel);
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.PasteBlock(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel);
}
private void OnNewScriptCommand()
{
var newScript = new LootFilterScript();
var newViewModel = _lootFilterScriptViewModelFactory.Create();
newViewModel.Initialise(newScript);
newViewModel.Description = "New Script";
ScriptViewModels.Add(newViewModel);
CurrentScriptViewModel = newViewModel;
var newScript = new ItemFilterScript();
var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(newScript, true);
_avalonDockWorkspaceViewModel.AddDocument(newViewModel);
}
private void OnCloseScriptCommand(ILootFilterScriptViewModel scriptViewModel)
private void OnCloseScriptCommand()
{
CurrentScriptViewModel = scriptViewModel;
if (!CurrentScriptViewModel.IsDirty)
{
ScriptViewModels.Remove(CurrentScriptViewModel);
}
else
{
var result = MessageBox.Show(@"Want to save your changes to this script?",
@"Filtration", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
switch (result)
{
case DialogResult.Yes:
{
OnSaveScriptCommand();
ScriptViewModels.Remove(CurrentScriptViewModel);
break;
}
case DialogResult.No:
{
ScriptViewModels.Remove(CurrentScriptViewModel);
break;
}
case DialogResult.Cancel:
{
break;
}
}
}
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Close();
}
}
}

View File

@@ -0,0 +1,65 @@
using System.Windows.Media;
namespace Filtration.ViewModels
{
class PaneViewModel : FiltrationViewModelBase
{
private string _title;
public string Title
{
get { return _title; }
set
{
if (_title != value)
{
_title = value;
RaisePropertyChanged();
}
}
}
public ImageSource IconSource { get; protected set; }
private string _contentId;
public string ContentId
{
get { return _contentId; }
set
{
if (_contentId != value)
{
_contentId = value;
RaisePropertyChanged();
}
}
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_isSelected = value;
RaisePropertyChanged();
}
}
}
private bool _isActive;
public bool IsActive
{
get { return _isActive; }
set
{
if (_isActive != value)
{
_isActive = value;
RaisePropertyChanged();
}
}
}
}
}

View File

@@ -1,20 +1,23 @@
using System.Linq;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Media;
using Filtration.Models;
using Filtration.Models.BlockItemTypes;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf;
using Xceed.Wpf.Toolkit;
namespace Filtration.ViewModels
{
internal interface IReplaceColorsViewModel
{
void Initialise(LootFilterScript lootFilterScript, LootFilterBlock initialiseFromBlock);
void Initialise(LootFilterScript lootFilterScript);
void Initialise(ItemFilterScript itemFilterScript, ItemFilterBlock initialiseFromBlock);
void Initialise(ItemFilterScript itemFilterScript);
}
internal class ReplaceColorsViewModel : FiltrationViewModelBase, IReplaceColorsViewModel
{
private LootFilterScript _lootFilterScript;
private ItemFilterScript _itemFilterScript;
private ReplaceColorsParameterSet _replaceColorsParameterSet;
public ReplaceColorsViewModel()
@@ -24,7 +27,7 @@ namespace Filtration.ViewModels
public RelayCommand ReplaceColorsCommand { get; private set; }
public void Initialise(LootFilterScript lootFilterScript, LootFilterBlock initialiseFromBlock)
public void Initialise(ItemFilterScript itemFilterScript, ItemFilterBlock initialiseFromBlock)
{
_replaceColorsParameterSet = new ReplaceColorsParameterSet();
@@ -55,7 +58,17 @@ namespace Filtration.ViewModels
_replaceColorsParameterSet.NewBorderColor = existingBlockColor;
}
_lootFilterScript = lootFilterScript;
_itemFilterScript = itemFilterScript;
}
public ObservableCollection<ColorItem> AvailableColors
{
get
{
{
return PathOfExileColors.DefaultColors;
}
}
}
public Color NewTextColor
@@ -159,15 +172,15 @@ namespace Filtration.ViewModels
}
}
public void Initialise(LootFilterScript lootFilterScript)
public void Initialise(ItemFilterScript itemFilterScript)
{
_replaceColorsParameterSet = new ReplaceColorsParameterSet();
_lootFilterScript = lootFilterScript;
_itemFilterScript = itemFilterScript;
}
private void OnReplaceColorsCommand()
{
_lootFilterScript.ReplaceColors(_replaceColorsParameterSet);
_itemFilterScript.ReplaceColors(_replaceColorsParameterSet);
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
namespace Filtration.ViewModels
{
internal interface ISectionBrowserViewModel : IToolViewModel
{
void ClearDown();
}
internal class SectionBrowserViewModel : ToolViewModel, ISectionBrowserViewModel
{
private IEnumerable<IItemFilterBlockViewModel> _sectionBlockViewModels;
private IItemFilterBlockViewModel _selectedSectionBlockViewModel;
public SectionBrowserViewModel() : base("Section Browser")
{
ContentId = ToolContentId;
var icon = new BitmapImage();
icon.BeginInit();
icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/add_section_icon.png");
icon.EndInit();
IconSource = icon;
}
public const string ToolContentId = "SectionBrowserTool";
public IEnumerable<IItemFilterBlockViewModel> SectionBlockViewModels
{
get { return _sectionBlockViewModels; }
private set
{
_sectionBlockViewModels = value;
RaisePropertyChanged();
}
}
public IItemFilterBlockViewModel SelectedSectionBlockViewModel
{
get { return _selectedSectionBlockViewModel; }
set
{
_selectedSectionBlockViewModel = value;
if (AvalonDockWorkspaceViewModel.ActiveDocument.IsScript)
{
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SectionBrowserSelectedBlockViewModel = value;
}
RaisePropertyChanged();
}
}
protected override void OnActiveDocumentChanged(object sender, EventArgs e)
{
if (AvalonDockWorkspaceViewModel.ActiveScriptViewModel != null && AvalonDockWorkspaceViewModel.ActiveDocument.IsScript)
{
SectionBlockViewModels = AvalonDockWorkspaceViewModel.ActiveScriptViewModel.ItemFilterSectionViewModels;
}
else
{
ClearDown();
}
}
public void ClearDown()
{
SectionBlockViewModels = null;
SelectedSectionBlockViewModel = null;
}
}
}

View File

@@ -0,0 +1,35 @@
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
namespace Filtration.ViewModels
{
internal interface IStartPageViewModel : IDocument
{
}
internal class StartPageViewModel : PaneViewModel, IStartPageViewModel
{
public StartPageViewModel()
{
Title = "Start Page";
OpenScriptCommand = new RelayCommand(OnOpenScriptCommand);
NewScriptCommand = new RelayCommand(OnNewScriptCommand);
}
public RelayCommand OpenScriptCommand { get; private set; }
public RelayCommand NewScriptCommand { get; private set; }
public bool IsScript { get { return false; } }
private static void OnOpenScriptCommand()
{
Messenger.Default.Send(new NotificationMessage("OpenScript"));
}
private static void OnNewScriptCommand()
{
Messenger.Default.Send(new NotificationMessage("NewScript"));
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
namespace Filtration.ViewModels
{
internal interface IToolViewModel
{
void Initialise(IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel);
}
class ToolViewModel : PaneViewModel, IToolViewModel
{
public ToolViewModel(string name)
{
Name = name;
Title = name;
}
public string Name { get; private set; }
private bool _isVisible = true;
public bool IsVisible
{
get { return _isVisible; }
set
{
if (_isVisible != value)
{
_isVisible = value;
RaisePropertyChanged();
}
}
}
protected IAvalonDockWorkspaceViewModel AvalonDockWorkspaceViewModel{ get; private set; }
protected virtual void OnActiveDocumentChanged(object sender, EventArgs e)
{
}
public virtual void Initialise(IAvalonDockWorkspaceViewModel avalonDockWorkSpaceViewModel)
{
AvalonDockWorkspaceViewModel = avalonDockWorkSpaceViewModel;
avalonDockWorkSpaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged;
}
}
}

View File

@@ -7,7 +7,10 @@
Height="360"
Width="580"
Loaded="AboutWindow_OnLoaded"
BorderThickness="1" BorderBrush="Black">
BorderThickness="1"
BorderBrush="Black"
ShowMaxRestoreButton="False"
ShowMinButton="False">
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
@@ -29,7 +32,7 @@
<Image Source="/Filtration;component/Resources/logo.png" Width="75" Height="75" VerticalAlignment="Top" />
<StackPanel Grid.Row="0" Grid.Column="1">
<TextBlock FontWeight="Black">Filtration</TextBlock>
<TextBlock>Version 0.2</TextBlock>
<TextBlock Text="{Binding Version}" />
<TextBlock>Copyright © 2015</TextBlock>
<TextBlock>Created by Ben Wallis</TextBlock>
<TextBlock>

View File

@@ -1,4 +1,6 @@
using System.Windows;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
namespace Filtration.Views
{
@@ -7,6 +9,7 @@ namespace Filtration.Views
public AboutWindow()
{
InitializeComponent();
DataContext = this;
}
private void AboutWindow_OnLoaded(object sender, RoutedEventArgs e)
@@ -16,5 +19,15 @@ namespace Filtration.Views
Left = mainWindow.Left + (mainWindow.Width - ActualWidth) / 2;
Top = mainWindow.Top + (mainWindow.Height - ActualHeight) / 2;
}
public string Version
{
get
{
var assembly = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return "Version " + fvi.FileMajorPart + "." + fvi.FileMinorPart;
}
}
}
}

View File

@@ -0,0 +1,40 @@
using System.Windows;
using System.Windows.Controls;
using Filtration.ViewModels;
namespace Filtration.Views.AttachedProperties
{
internal class SelectingItemAttachedProperty
{
public static readonly DependencyProperty SelectingItemProperty = DependencyProperty.RegisterAttached(
"SelectingItem",
typeof(IItemFilterBlockViewModel),
typeof(SelectingItemAttachedProperty),
new PropertyMetadata(default(IItemFilterBlockViewModel), OnSelectingItemChanged));
public static IItemFilterBlockViewModel GetSelectingItem(DependencyObject target)
{
return (IItemFilterBlockViewModel)target.GetValue(SelectingItemProperty);
}
public static void SetSelectingItem(DependencyObject target, IItemFilterBlockViewModel value)
{
target.SetValue(SelectingItemProperty, value);
}
static void OnSelectingItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var listBox = sender as ListBox;
if (listBox == null || listBox.SelectedItem == null)
{
return;
}
listBox.Dispatcher.InvokeAsync(() =>
{
listBox.UpdateLayout();
listBox.ScrollIntoView(listBox.SelectedItem);
});
}
}
}

View File

@@ -0,0 +1,87 @@
<UserControl x:Class="Filtration.Views.AvalonDock.AvalonDockWorkspaceView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:viewsAvalonDock="clr-namespace:Filtration.Views.AvalonDock"
xmlns:views="clr-namespace:Filtration.Views"
xmlns:toolPanes="clr-namespace:Filtration.Views.ToolPanes"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
xmlns:converters="clr-namespace:Filtration.Converters"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance d:Type=viewModels:AvalonDockWorkspaceViewModel}"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ActiveDocumentConverter x:Key="ActiveDocumentConverter" />
</UserControl.Resources>
<Grid>
<!-- ReSharper disable once InconsistentNaming -->
<xcad:DockingManager x:Name="dockManager"
AnchorablesSource="{Binding Tools}"
AllowMixedOrientation="True"
DocumentsSource="{Binding OpenDocuments}"
ActiveContent="{Binding ActiveDocument, Mode=TwoWay, Converter={StaticResource ActiveDocumentConverter}}" >
<xcad:DockingManager.LayoutItemTemplateSelector>
<viewsAvalonDock:PanesTemplateSelector>
<viewsAvalonDock:PanesTemplateSelector.ItemFilterScriptTemplate>
<DataTemplate>
<views:ItemFilterScriptView DataContext="{Binding}" />
</DataTemplate>
</viewsAvalonDock:PanesTemplateSelector.ItemFilterScriptTemplate>
<viewsAvalonDock:PanesTemplateSelector.BlockGroupBrowserTemplate>
<DataTemplate>
<toolPanes:BlockGroupBrowserView DataContext="{Binding}" />
</DataTemplate>
</viewsAvalonDock:PanesTemplateSelector.BlockGroupBrowserTemplate>
<viewsAvalonDock:PanesTemplateSelector.SectionBrowserTemplate>
<DataTemplate>
<toolPanes:SectionBrowserView DataContext="{Binding}" />
</DataTemplate>
</viewsAvalonDock:PanesTemplateSelector.SectionBrowserTemplate>
<viewsAvalonDock:PanesTemplateSelector.StartPageTemplate>
<DataTemplate>
<views:StartPageView DataContext="{Binding}" />
</DataTemplate>
</viewsAvalonDock:PanesTemplateSelector.StartPageTemplate>
</viewsAvalonDock:PanesTemplateSelector>
</xcad:DockingManager.LayoutItemTemplateSelector>
<xcad:DockingManager.LayoutItemContainerStyleSelector>
<viewsAvalonDock:PanesStyleSelector>
<viewsAvalonDock:PanesStyleSelector.ToolStyle>
<Style TargetType="{x:Type xcad:LayoutAnchorableItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<Setter Property="IconSource" Value="{Binding Model.IconSource}"/>
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter={x:Static Visibility.Hidden}}"/>
<Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/>
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
</Style>
</viewsAvalonDock:PanesStyleSelector.ToolStyle>
<viewsAvalonDock:PanesStyleSelector.DocumentStyle>
<Style TargetType="{x:Type xcad:LayoutItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<!--<Setter Property="ToolTip" Value="{Binding Model.FilePath}"/> -->
<Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}"/>
<Setter Property="IconSource" Value="{Binding Model.IconSource}"/>
<Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
</Style>
</viewsAvalonDock:PanesStyleSelector.DocumentStyle>
</viewsAvalonDock:PanesStyleSelector>
</xcad:DockingManager.LayoutItemContainerStyleSelector>
<xcad:DockingManager.LayoutUpdateStrategy>
<viewsAvalonDock:LayoutInitializer></viewsAvalonDock:LayoutInitializer>
</xcad:DockingManager.LayoutUpdateStrategy>
<xcad:LayoutRoot>
<xcad:LayoutPanel Orientation="Horizontal">
<xcad:LayoutAnchorablePane Name="SectionBrowserPane" DockWidth="150" />
<xcad:LayoutDocumentPane/>
<xcad:LayoutAnchorablePane Name="BlockGroupBrowserPane" DockWidth="200" />
</xcad:LayoutPanel>
</xcad:LayoutRoot>
</xcad:DockingManager>
</Grid>
</UserControl>

View File

@@ -0,0 +1,10 @@
namespace Filtration.Views.AvalonDock
{
public partial class AvalonDockWorkspaceView
{
public AvalonDockWorkspaceView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,73 @@
using System.Linq;
using Filtration.ViewModels;
using Xceed.Wpf.AvalonDock.Layout;
namespace Filtration.Views.AvalonDock
{
class LayoutInitializer : ILayoutUpdateStrategy
{
public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)
{
//AD wants to add the anchorable into destinationContainer
//just for test provide a new anchorablepane
//if the pane is floating let the manager go ahead
LayoutAnchorablePane destPane = destinationContainer as LayoutAnchorablePane;
if (destinationContainer != null &&
destinationContainer.FindParent<LayoutFloatingWindow>() != null)
return false;
if (anchorableToShow.Content is SectionBrowserViewModel)
{
var toolsPane = layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(d => d.Name == "SectionBrowserPane");
if (toolsPane != null)
{
anchorableToShow.CanHide = false;
toolsPane.Children.Add(anchorableToShow);
return true;
}
}
//if (anchorableToShow.ContentId == "SectionBrowserTool")
//{
// var toolsPane = layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(d => d.Name == "SectionBrowserPane");
// if (toolsPane != null)
// {
// anchorableToShow.CanHide = false;
// toolsPane.Children.Add(anchorableToShow);
// return true;
// }
//}
//if (anchorableToShow.ContentId == "BlockGroupBrowserTool")
//{
// var toolsPane = layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(d => d.Name == "BlockGroupBrowserPane");
// if (toolsPane != null)
// {
// anchorableToShow.CanHide = false;
// toolsPane.Children.Add(anchorableToShow);
// return true;
// }
//}
return false;
}
public void AfterInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableShown)
{
}
public bool BeforeInsertDocument(LayoutRoot layout, LayoutDocument anchorableToShow, ILayoutContainer destinationContainer)
{
return false;
}
public void AfterInsertDocument(LayoutRoot layout, LayoutDocument anchorableShown)
{
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Windows;
using System.Windows.Controls;
using Filtration.ViewModels;
namespace Filtration.Views.AvalonDock
{
class PanesStyleSelector : StyleSelector
{
public Style ToolStyle { get; set; }
public Style DocumentStyle { get; set; }
public override Style SelectStyle(object item, DependencyObject container)
{
if (item is ToolViewModel)
{
return ToolStyle;
}
if (item is IDocument)
{
return DocumentStyle;
}
return base.SelectStyle(item, container);
}
}
}

View File

@@ -0,0 +1,42 @@
using System.Windows;
using System.Windows.Controls;
using Filtration.ViewModels;
using Xceed.Wpf.AvalonDock.Layout;
namespace Filtration.Views.AvalonDock
{
class PanesTemplateSelector : DataTemplateSelector
{
public DataTemplate ItemFilterScriptTemplate { get; set; }
public DataTemplate BlockGroupBrowserTemplate { get; set; }
public DataTemplate SectionBrowserTemplate { get; set; }
public DataTemplate StartPageTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var itemAsLayoutContent = item as LayoutContent;
if (item is ItemFilterScriptViewModel)
{
return ItemFilterScriptTemplate;
}
if (item is SectionBrowserViewModel)
{
return SectionBrowserTemplate;
}
if (item is BlockGroupBrowserViewModel)
{
return BlockGroupBrowserTemplate;
}
if (item is StartPageViewModel)
{
return StartPageTemplate;
}
return base.SelectTemplate(item, container);
}
}
}

View File

@@ -0,0 +1,55 @@
// Taken from http://stackoverflow.com/a/5118406/4153185
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
namespace Filtration.Views.Behaviors
{
internal class BindableSelectedItemBehavior : Behavior<TreeView>
{
#region SelectedItem Property
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof (object), typeof (BindableSelectedItemBehavior),
new UIPropertyMetadata(null, OnSelectedItemChanged));
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var item = e.NewValue as TreeViewItem;
if (item != null)
{
item.SetValue(TreeViewItem.IsSelectedProperty, true);
}
}
#endregion
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
if (AssociatedObject != null)
{
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
}
}
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SelectedItem = e.NewValue;
}
}
}

View File

@@ -9,18 +9,18 @@ namespace Filtration.Views
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var viewModel = item as LootFilterBlockViewModel;
var viewModel = item as ItemFilterBlockViewModel;
var element = container as FrameworkElement;
if (viewModel == null || element == null)
return null;
if (viewModel.Block is LootFilterSection)
if (viewModel.Block is ItemFilterSection)
{
return element.FindResource("LootFilterSectionTemplate") as DataTemplate;
return element.FindResource("ItemFilterSectionTemplate") as DataTemplate;
}
return element.FindResource("LootFilterBlockTemplate") as DataTemplate;
return element.FindResource("ItemFilterBlockTemplate") as DataTemplate;
}
}
}

View File

@@ -17,4 +17,7 @@
<Image Source="/Filtration;component/Resources/Icons/play_icon.png" x:Key="PlayIcon" x:Shared="false" />
<Image Source="/Filtration;component/Resources/Icons/about_icon.png" x:Key="AboutIcon" x:Shared="false" />
<Image Source="/Filtration;component/Resources/Icons/replace_colors_icon.png" x:Key="ReplaceColorsIcon" x:Shared="false" />
<Image Source="/Filtration;component/Resources/Icons/clear_filter_icon.png" x:Key="ClearFilterIcon" x:Shared="False" />
<Image Source="/Filtration;component/Resources/Icons/filter_icon.png" x:Key="FilterIcon" x:Shared="False" />
<Image Source="/Filtration;component/Resources/Icons/show_advanced_icon.png" x:Key="ShowAdvancedIcon" x:Shared="False" />
</ResourceDictionary>

View File

@@ -1,4 +1,4 @@
<UserControl x:Class="Filtration.Views.LootFilterBlockDisplaySettingsView"
<UserControl x:Class="Filtration.Views.ItemFilterBlockDisplaySettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -10,7 +10,7 @@
xmlns:blockItemTypes="clr-namespace:Filtration.Models.BlockItemTypes"
xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterBlockViewModel}"
d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}"
d:DesignHeight="120" d:DesignWidth="175">
<UserControl.Resources>
<ResourceDictionary>
@@ -62,7 +62,7 @@
<ColumnDefinition SharedSizeGroup="AudioVisualBlockItemCloseColumn" Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding DisplayHeading}" Style="{StaticResource DisplayHeading}" />
<xctk:ColorPicker Grid.Column="1" SelectedColor="{Binding Color}" HorizontalAlignment="Right" Width="100" />
<xctk:ColorPicker Grid.Column="1" SelectedColor="{Binding Color}" HorizontalAlignment="Right" Width="100" AvailableColors="{Binding ElementName=SettingsGrid, Path=DataContext.AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors"/>
<userControls:CrossButton Grid.Column="2" Height="12" Command="{Binding ElementName=SettingsGrid, Path=DataContext.RemoveAudioVisualBlockItemCommand}" CommandParameter="{Binding}" />
</Grid>
</DataTemplate>

View File

@@ -0,0 +1,10 @@
namespace Filtration.Views
{
public partial class ItemFilterBlockDisplaySettingsView
{
public ItemFilterBlockDisplaySettingsView()
{
InitializeComponent();
}
}
}

View File

@@ -1,4 +1,4 @@
<UserControl x:Class="Filtration.Views.LootFilterBlockView"
<UserControl x:Class="Filtration.Views.ItemFilterBlockView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -6,12 +6,13 @@
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:userControls="clr-namespace:Filtration.UserControls"
xmlns:views="clr-namespace:Filtration.Views"
xmlns:converters="clr-namespace:Filtration.Converters"
xmlns:blockItemBaseTypes="clr-namespace:Filtration.Models.BlockItemBaseTypes"
xmlns:blockItemTypes="clr-namespace:Filtration.Models.BlockItemTypes"
xmlns:enums="clr-namespace:Filtration.Enums"
xmlns:extensions="clr-namespace:Filtration.Extensions"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterBlockViewModel}"
d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}"
d:DesignHeight="200" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
@@ -19,6 +20,8 @@
<ResourceDictionary Source="SharedResourcesDictionary.xaml" />
<ResourceDictionary>
<views:BindingProxy x:Key="proxy" Data="{Binding}" />
<converters:BlockGroupAdvancedFillColorConverter x:Key="BlockGroupAdvancedFillColorConverter" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -30,10 +33,10 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Width="7" >
<Rectangle.Fill>
<SolidColorBrush Color="Gray" />
</Rectangle.Fill>
<Rectangle Width="7" Fill="{Binding AdvancedBlockGroup, Converter={StaticResource BlockGroupAdvancedFillColorConverter}}">
<Rectangle.ToolTip>
<ToolTip Visibility="{Binding AdvancedBlockGroup, Converter={StaticResource BooleanVisibilityConverter}}">Advanced Block Group</ToolTip>
</Rectangle.ToolTip>
</Rectangle>
<Expander Grid.Column="1" Style="{StaticResource ExpanderRightAlignStyle}" x:Name="TestExpander" ToolTip="{Binding BlockDescription}" ToolTipService.IsEnabled="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsExpanded, Converter={StaticResource BoolInverterConverter}}">
<Expander.ContextMenu>
@@ -114,7 +117,7 @@
AllowsTransparency="True"
HorizontalOffset="-5"
Width="250">
<views:LootFilterBlockDisplaySettingsView />
<views:ItemFilterBlockDisplaySettingsView />
</Popup>
</Grid>
</Expander.Header>

View File

@@ -1,8 +1,8 @@
namespace Filtration.Views
{
public partial class LootFilterBlockView
public partial class ItemFilterBlockView
{
public LootFilterBlockView()
public ItemFilterBlockView()
{
InitializeComponent();
}

View File

@@ -1,25 +1,26 @@
<UserControl x:Class="Filtration.Views.LootFilterScriptView"
<UserControl x:Class="Filtration.Views.ItemFilterScriptView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:Filtration.Views"
xmlns:attachedProperties="clr-namespace:Filtration.Views.AttachedProperties"
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:userControls="clr-namespace:Filtration.UserControls"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterScriptViewModel}"
d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterScriptViewModel}"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<!-- ReSharper disable once Xaml.RedundantResource -->
<DataTemplate x:Key="LootFilterBlockTemplate">
<views:LootFilterBlockView Margin="0,2,0,2" />
<DataTemplate x:Key="ItemFilterBlockTemplate">
<views:ItemFilterBlockView Margin="0,2,0,2" />
</DataTemplate>
<!-- ReSharper disable once Xaml.RedundantResource -->
<DataTemplate x:Key="LootFilterSectionTemplate">
<views:LootFilterSectionView Margin="0,2,0,2" />
<DataTemplate x:Key="ItemFilterSectionTemplate">
<views:ItemFilterSectionView Margin="0,2,0,2" />
</DataTemplate>
<views:BlockTemplateSelector x:Key="BlockTemplateSelector" />
</ResourceDictionary>
@@ -46,40 +47,24 @@
</Border>
<Border Grid.Row="1" BorderThickness="1" BorderBrush="DarkGray" Margin="5,5,5,5" Padding="2">
<DockPanel LastChildFill="True">
<ToolBarTray DockPanel.Dock="Top">
<ToolBar>
<Button ToolTip="Add Block" Command="{Binding AddBlockCommand}" Content="{StaticResource AddBlockIcon}" />
<Button ToolTip="Add Section" Command="{Binding AddSectionCommand}" Content="{StaticResource AddSectionIcon}" />
<ToolBarTray DockPanel.Dock="Top">
<ToolBar>
<Button ToolTip="Add Block" Command="{Binding AddBlockCommand}" Content="{StaticResource AddBlockIcon}" />
<Button ToolTip="Add Section" Command="{Binding AddSectionCommand}" Content="{StaticResource AddSectionIcon}" />
<Button ToolTip="Delete Block/Section" Command="{Binding DeleteBlockCommand}" Content="{StaticResource DeleteIcon}" />
</ToolBar>
<ToolBar>
<Button ToolTip="Move Block to Top" Command="{Binding MoveBlockToTopCommand}" Content="{StaticResource MoveToTopIcon}" />
<Button ToolTip="Move Block Up" Command="{Binding MoveBlockUpCommand}" Content="{StaticResource MoveUpIcon}" />
<Button ToolTip="Move Block Down" Command="{Binding MoveBlockDownCommand}" Content="{StaticResource MoveDownIcon}" />
<Button ToolTip="Move Block to Bottom" Command="{Binding MoveBlockToBottomCommand}" Content="{StaticResource MoveToBottomIcon}" />
</ToolBar>
<ToolBar>
<Button ToolTip="Move Block to Top" Command="{Binding MoveBlockToTopCommand}" Content="{StaticResource MoveToTopIcon}" />
<Button ToolTip="Move Block Up" Command="{Binding MoveBlockUpCommand}" Content="{StaticResource MoveUpIcon}" />
<Button ToolTip="Move Block Down" Command="{Binding MoveBlockDownCommand}" Content="{StaticResource MoveDownIcon}" />
<Button ToolTip="Move Block to Bottom" Command="{Binding MoveBlockToBottomCommand}" Content="{StaticResource MoveToBottomIcon}" />
</ToolBar>
<ToolBar>
<Button ToolTip="Clear Filter" Command="{Binding ClearFilterCommand}" Content="{StaticResource ClearFilterIcon}" />
<!--<ToggleButton ToolTip="Show Advanced Block Groups" Command="{Binding ToggleShowAdvancedCommand}" CommandParameter="{Binding Path=IsChecked, RelativeSource={RelativeSource Self}}" Content="{StaticResource ShowAdvancedIcon}" />-->
</ToolBar>
</ToolBarTray>
<Expander DockPanel.Dock="Left" ExpandDirection="Right" MaxWidth="200" HorizontalAlignment="Left" >
<Expander.Header>
<TextBlock Text="Section Browser" Foreground="White" VerticalAlignment="Top">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<ListBox ItemsSource="{Binding LootFilterSectionViewModels}"
SelectedItem="{Binding SectionBrowserSelectedViewModel}"
x:Name="SectionBrowserListBox"
SelectionChanged="SectionBrowserListBox_OnSelectionChanged"
ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding BlockDescription}" ToolTip="{Binding BlockDescription}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
<userControls:AutoScrollingListBox ItemsSource="{Binding LootFilterBlockViewModels}"
<userControls:AutoScrollingListBox ItemsSource="{Binding ItemFilterBlockViewModels}"
Margin="5,5,5,5"
Padding="5"
HorizontalContentAlignment="Stretch"
@@ -87,6 +72,7 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ItemTemplateSelector="{StaticResource BlockTemplateSelector}"
attachedProperties:SelectingItemAttachedProperty.SelectingItem="{Binding SectionBrowserSelectedBlockViewModel}"
SelectedItem="{Binding SelectedBlockViewModel}" x:Name="BlocksListBox">
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteBlockCommand}" />

View File

@@ -1,8 +1,8 @@
namespace Filtration.Views
{
public partial class LootFilterSectionView
public partial class ItemFilterScriptView
{
public LootFilterSectionView()
public ItemFilterScriptView()
{
InitializeComponent();
}

View File

@@ -1,10 +1,10 @@
<UserControl x:Class="Filtration.Views.LootFilterSectionView"
<UserControl x:Class="Filtration.Views.ItemFilterSectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterBlockViewModel}"
d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="300">
<UserControl.Resources>

View File

@@ -0,0 +1,10 @@
namespace Filtration.Views
{
public partial class ItemFilterSectionView
{
public ItemFilterSectionView()
{
InitializeComponent();
}
}
}

View File

@@ -1,10 +0,0 @@
namespace Filtration.Views
{
public partial class LootFilterBlockDisplaySettingsView
{
public LootFilterBlockDisplaySettingsView()
{
InitializeComponent();
}
}
}

View File

@@ -1,18 +0,0 @@
using System.Windows.Controls;
namespace Filtration.Views
{
public partial class LootFilterScriptView
{
public LootFilterScriptView()
{
InitializeComponent();
}
private void SectionBrowserListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = (ListBox) sender;
BlocksListBox.ScrollIntoView(listBox.SelectedItem);
}
}
}

View File

@@ -5,16 +5,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:views="clr-namespace:Filtration.Views"
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:userControls="clr-namespace:Filtration.UserControls"
xmlns:viewsAvalonDock="clr-namespace:Filtration.Views.AvalonDock"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}"
Title="{Binding WindowTitle}" Height="707" Width="930" BorderThickness="1" BorderBrush="Black">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
Title="{Binding WindowTitle}" Height="768" Width="1024" BorderThickness="1" BorderBrush="Black">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
@@ -22,7 +17,7 @@
<MenuItem Header="_Open Script" Command="{Binding OpenScriptCommand}" Icon="{StaticResource OpenIcon}"/>
<MenuItem Header="_Save Script" Command="{Binding SaveScriptCommand}" Icon="{StaticResource SaveIcon}"/>
<MenuItem Header="Save Script _As" Command="{Binding SaveScriptAsCommand}" Icon="{StaticResource SaveIcon}"/>
<MenuItem Header="_Close Script" Command="{Binding CloseScriptCommand}" CommandParameter="{Binding CurrentScriptViewModel}"/>
<MenuItem Header="_Close Script" Command="{Binding CloseScriptCommand}" />
<MenuItem Header="E_xit"/>
</MenuItem>
<MenuItem Header="_Edit">
@@ -46,25 +41,7 @@
</ToolBar>
</ToolBarTray>
<Grid>
<controls:MetroTabControl ItemsSource="{Binding ScriptViewModels}" SelectedItem="{Binding CurrentScriptViewModel}" Name="TabControl" Background="White">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5,0,0,0">
<TextBlock Text="{Binding DisplayName}" FontSize="16" VerticalAlignment="Center" Margin="0,0,3,0" />
<userControls:CrossButton Height="12" Command="{Binding ElementName=TabControl, Path=DataContext.CloseScriptCommand}" CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<controls:MetroContentControl>
<views:LootFilterScriptView DataContext="{Binding}" />
</controls:MetroContentControl>
</DataTemplate>
</TabControl.ContentTemplate>
</controls:MetroTabControl>
<TextBlock FontStyle="Italic" Margin="5" FontSize="13" Visibility="{Binding NoScriptsOpen, Converter={StaticResource BooleanToVisibilityConverter}}">Welcome to Filtration, to get started either
<Hyperlink Command="{Binding NewScriptCommand}">create a new script</Hyperlink> or <Hyperlink Command="{Binding OpenScriptCommand}">open an existing script</Hyperlink></TextBlock>
<viewsAvalonDock:AvalonDockWorkspaceView DataContext="{Binding AvalonDockWorkspaceViewModel}" />
</Grid>
</DockPanel>
</controls:MetroWindow>

View File

@@ -0,0 +1,48 @@
using System.Collections.ObjectModel;
using System.Windows.Media;
using Xceed.Wpf.Toolkit;
namespace Filtration.Views
{
static internal class PathOfExileColors
{
static PathOfExileColors()
{
DefaultColors = new ObservableCollection<ColorItem>
{
new ColorItem(new Color {A = 255, R=127, G = 127, B = 127}, "Default"),
new ColorItem(new Color {A = 255, R=255, G = 255, B = 255}, "Value Default"),
new ColorItem(new Color {A = 255, R=255, G = 192, B = 203}, "Pink"),
new ColorItem(new Color {A = 255, R=30, G = 144, B = 255}, "Dodger Blue"),
new ColorItem(new Color {A = 255, R=150, G = 0, B = 0}, "Fire"),
new ColorItem(new Color {A = 255, R=54, G = 100, B = 146}, "Cold"),
new ColorItem(new Color {A = 255, R=255, G = 215, B = 0}, "Lightning"),
new ColorItem(new Color {A = 255, R=208, G = 32, B = 144}, "Chaos"),
new ColorItem(new Color {A = 255, R=136, G = 136, B = 255}, "Augmented"),
new ColorItem(new Color {A = 255, R=184, G = 218, B = 242}, "Crafted"),
new ColorItem(new Color {A = 255, R=210, G = 0, B = 0}, "Unmet"),
new ColorItem(new Color {A = 255, R=175, G = 96, B = 37}, "Unique Item"),
new ColorItem(new Color {A = 255, R=255, G = 255, B = 119}, "Rare Item"),
new ColorItem(new Color {A = 255, R=136, G = 136, B = 255}, "Magic Item"),
new ColorItem(new Color {A = 255, R=200, G = 200, B = 200}, "White Item"),
new ColorItem(new Color {A = 255, R=27, G = 162, B = 155}, "Gem Item"),
new ColorItem(new Color {A = 255, R=170, G = 158, B = 130}, "Currency Item"),
new ColorItem(new Color {A = 255, R=74, G = 230, B = 58}, "Quest Item"),
new ColorItem(new Color {A = 255, R=255, G = 200, B = 0}, "Nemesis Mod"),
new ColorItem(new Color {A = 220, R = 255, G = 40, B = 0}, "Nemesis Mod Outline"),
new ColorItem(new Color {A = 255, R=231, G = 180, B = 120}, "Title"),
new ColorItem(new Color {A = 255, R=210, G = 0, B = 0}, "Corrupted"),
new ColorItem(new Color {A = 255, R=170, G = 158, B = 130}, "Favour"),
new ColorItem(new Color {A = 255, R=180, G = 96, B = 0}, "Supporter Pack New Item"),
new ColorItem(new Color {A = 255, R=163, G = 141, B = 109}, "Supporter Pack Item"),
new ColorItem(new Color {A = 255, R=210, G = 0, B = 220}, "Bloodline Mod"),
new ColorItem(new Color {A = 200, R = 74, G = 0, B = 160}, "Bloodline Mod Outline"),
new ColorItem(new Color {A = 255, R=50, G = 230, B = 100}, "Torment Mod"),
new ColorItem(new Color {A = 200, R = 0, G = 100, B = 150}, "Torment Mod Outline"),
new ColorItem(new Color {A = 255, R=210, G = 0, B = 0}, "Can't Trade or Modify")
};
}
public static ObservableCollection<ColorItem> DefaultColors { get; private set; }
}
}

View File

@@ -40,22 +40,22 @@
</Grid.ColumnDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" Content="Replace Text Color" IsChecked="{Binding ReplaceTextColor}" />
<TextBlock Grid.Row="0" Grid.Column="2" VerticalAlignment="Center">Existing Text Color</TextBlock>
<xctk:ColorPicker Grid.Row="0" Grid.Column="4" SelectedColor="{Binding ReplaceColorsParameterSet.OldTextColor}" />
<xctk:ColorPicker Grid.Row="0" Grid.Column="4" SelectedColor="{Binding ReplaceColorsParameterSet.OldTextColor}" AvailableColors="{Binding AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors" />
<TextBlock Grid.Row="1" Grid.Column="2" VerticalAlignment="Center">New Text Color</TextBlock>
<xctk:ColorPicker Grid.Row="1" Grid.Column="4" SelectedColor="{Binding NewTextColor}" />
<xctk:ColorPicker Grid.Row="1" Grid.Column="4" SelectedColor="{Binding NewTextColor}" AvailableColors="{Binding AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors" />
<CheckBox Grid.Row="2" Grid.Column="0" Content="Replace Background Color" IsChecked="{Binding ReplaceBackgroundColor}" />
<TextBlock Grid.Row="2" Grid.Column="2" VerticalAlignment="Center">Existing Background Color</TextBlock>
<xctk:ColorPicker Grid.Row="2" Grid.Column="4" SelectedColor="{Binding ReplaceColorsParameterSet.OldBackgroundColor}" />
<xctk:ColorPicker Grid.Row="2" Grid.Column="4" SelectedColor="{Binding ReplaceColorsParameterSet.OldBackgroundColor}" AvailableColors="{Binding AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors" />
<TextBlock Grid.Row="3" Grid.Column="2" VerticalAlignment="Center">New Background Color</TextBlock>
<xctk:ColorPicker Grid.Row="3" Grid.Column="4" SelectedColor="{Binding NewBackgroundColor}" />
<xctk:ColorPicker Grid.Row="3" Grid.Column="4" SelectedColor="{Binding NewBackgroundColor}" AvailableColors="{Binding AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors" />
<CheckBox Grid.Row="4" Grid.Column="0" Content="Replace Border Color" IsChecked="{Binding ReplaceBorderColor}" />
<TextBlock Grid.Row="4" Grid.Column="2" VerticalAlignment="Center">Existing Border Color</TextBlock>
<xctk:ColorPicker Grid.Row="4" Grid.Column="4" SelectedColor="{Binding ReplaceColorsParameterSet.OldBorderColor}" />
<xctk:ColorPicker Grid.Row="4" Grid.Column="4" SelectedColor="{Binding ReplaceColorsParameterSet.OldBorderColor}" AvailableColors="{Binding AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors" />
<TextBlock Grid.Row="5" Grid.Column="2" VerticalAlignment="Center">New Border Color</TextBlock>
<xctk:ColorPicker Grid.Row="5" Grid.Column="4" SelectedColor="{Binding NewBorderColor}" />
<xctk:ColorPicker Grid.Row="5" Grid.Column="4" SelectedColor="{Binding NewBorderColor}" AvailableColors="{Binding AvailableColors}" ShowAvailableColors="True" AvailableColorsHeader="Path of Exile Colors" />
<userControls:ItemPreviewControl Grid.Row="6" Grid.Column="4" TextColor="{Binding DisplayTextColor}" BackgroundColor="{Binding DisplayBackgroundColor}" BorderColor="{Binding DisplayBorderColor}" />
<TextBlock Grid.Row="6" Grid.Column="2" VerticalAlignment="Center">Preview</TextBlock>

View File

@@ -0,0 +1,14 @@
<UserControl x:Class="Filtration.Views.StartPageView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<Grid>
<TextBlock FontStyle="Italic" Margin="5" FontSize="13">
Welcome to Filtration, to get started either
<Hyperlink Command="{Binding NewScriptCommand}">create a new script</Hyperlink> or <Hyperlink Command="{Binding OpenScriptCommand}">open an existing script</Hyperlink>
</TextBlock>
</Grid>
</UserControl>

View File

@@ -0,0 +1,10 @@
namespace Filtration.Views
{
public partial class StartPageView
{
public StartPageView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,41 @@
<UserControl x:Class="Filtration.Views.ToolPanes.BlockGroupBrowserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Filtration.Models"
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:converters="clr-namespace:Filtration.Converters"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:Filtration.Views.Behaviors"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:BlockGroupBrowserViewModel}"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<converters:BlockGroupAdvancedColorConverter x:Key="BlockGroupAdvancedColorConverter" />
<converters:BlockGroupVisibilityConverter x:Key="BlockGroupVisibilityConverter" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToolBar Grid.Row="0">
<Button Height="20" Command="{Binding FilterToSelectedBlockGroupCommand}" Content="{StaticResource FilterIcon}" ToolTip="Filter to Selected Block Group" />
</ToolBar>
<TreeView Grid.Row="1" ItemsSource="{Binding BlockGroups}" Name="TreeView">
<i:Interaction.Behaviors>
<behaviors:BindableSelectedItemBehavior SelectedItem="{Binding SelectedBlockGroup, Mode=OneWayToSource}" />
</i:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type models:ItemFilterBlockGroup}" ItemsSource="{Binding ChildGroups}">
<WrapPanel>
<CheckBox IsThreeState="True" IsChecked="{Binding IsChecked}" Click="BlockGroupCheckBox_Clicked" />
<TextBlock Text="{Binding GroupName}" Foreground="{Binding Advanced, Converter={StaticResource BlockGroupAdvancedColorConverter}}" />
</WrapPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</UserControl>

View File

@@ -0,0 +1,26 @@
<UserControl x:Class="Filtration.Views.ToolPanes.SectionBrowserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:converters="clr-namespace:Filtration.Converters"
d:DataContext="{d:DesignInstance Type=viewModels:SectionBrowserViewModel}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<converters:HashSignRemovalConverter x:Key="HashSignRemovalConverter" />
</UserControl.Resources>
<Grid>
<ListBox ItemsSource="{Binding SectionBlockViewModels}"
SelectedItem="{Binding SelectedSectionBlockViewModel}"
x:Name="SectionBrowserListBox"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"><!--SelectionChanged="SectionBrowserListBox_OnSelectionChanged"-->
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Block.Description, Converter={StaticResource HashSignRemovalConverter}}" ToolTip="{Binding Block.Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

View File

@@ -15,8 +15,8 @@ namespace Filtration.WindsorInstallers
.LifeStyle.Singleton);
container.Register(
Component.For<ILootFilterPersistenceService>()
.ImplementedBy<LootFilterPersistenceService>()
Component.For<IItemFilterPersistenceService>()
.ImplementedBy<ItemFilterPersistenceService>()
.LifeStyle.Singleton);
container.Register(

View File

@@ -10,13 +10,18 @@ namespace Filtration.WindsorInstallers
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ILootFilterScriptTranslator>()
.ImplementedBy<LootFilterScriptTranslator>()
Component.For<IItemFilterScriptTranslator>()
.ImplementedBy<ItemFilterScriptTranslator>()
.LifeStyle.Singleton);
container.Register(
Component.For<ILootFilterBlockTranslator>()
.ImplementedBy<LootFilterBlockTranslator>()
Component.For<IItemFilterBlockTranslator>()
.ImplementedBy<ItemFilterBlockTranslator>()
.LifeStyle.Singleton);
container.Register(
Component.For<IBlockGroupHierarchyBuilder>()
.ImplementedBy<BlockGroupHierarchyBuilder>()
.LifeStyle.Singleton);
}
}

View File

@@ -13,16 +13,21 @@ namespace Filtration.WindsorInstallers
container.Register(
Component.For<IMainWindowViewModel>()
.ImplementedBy<MainWindowViewModel>()
.LifeStyle.Singleton);
container.Register(
Component.For<IAvalonDockWorkspaceViewModel>()
.ImplementedBy<AvalonDockWorkspaceViewModel>()
.LifeStyle.Singleton);
container.Register(
Component.For<IItemFilterBlockViewModel>()
.ImplementedBy<ItemFilterBlockViewModel>()
.LifeStyle.Transient);
container.Register(
Component.For<ILootFilterBlockViewModel>()
.ImplementedBy<LootFilterBlockViewModel>()
.LifeStyle.Transient);
container.Register(
Component.For<ILootFilterScriptViewModel>()
.ImplementedBy<LootFilterScriptViewModel>()
Component.For<IItemFilterScriptViewModel>()
.ImplementedBy<ItemFilterScriptViewModel>()
.LifeStyle.Transient);
container.Register(
@@ -30,12 +35,27 @@ namespace Filtration.WindsorInstallers
.ImplementedBy<ReplaceColorsViewModel>()
.LifeStyle.Singleton);
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<ILootFilterBlockViewModelFactory>().AsFactory());
Component.For<IStartPageViewModel>()
.ImplementedBy<StartPageViewModel>()
.LifeStyle.Singleton);
container.Register(
Component.For<ILootFilterScriptViewModelFactory>().AsFactory());
Component.For<ISectionBrowserViewModel>()
.ImplementedBy<SectionBrowserViewModel>()
.LifeStyle.Singleton);
container.Register(
Component.For<IBlockGroupBrowserViewModel>()
.ImplementedBy<BlockGroupBrowserViewModel>()
.LifeStyle.Singleton);
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IItemFilterBlockViewModelFactory>().AsFactory());
container.Register(
Component.For<IItemFilterScriptViewModelFactory>().AsFactory());
}
}
}

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AvalonDock" version="2.0.2000" targetFramework="net451" />
<package id="Castle.Core" version="3.3.0" targetFramework="net451" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net451" />
<package id="CommonServiceLocator" version="1.3" targetFramework="net451" />

View File

@@ -3,9 +3,9 @@
Filtration is an editor for Path of Exile item filter scripts.
## Current Release
<b>Installer (5.71mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.1/filtration_0.1_setup.exe">filtration_0.1_setup.exe</a>
<b>Installer (5.85mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.2/filtration_0.2_setup.exe">filtration_0.2_setup.exe</a>
<b>Zip File (7.01mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.1/filtration_0.1.zip">filtration_0.1.zip</a>
<b>Zip File (7.18mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.2/filtration_0.2.zip">filtration_0.2.zip</a>
## System Requirements
Filtration requires .NET Framework 4.5.1 installed.