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

View File

@@ -5,13 +5,13 @@ using NUnit.Framework;
namespace Filtration.Tests.Models namespace Filtration.Tests.Models
{ {
[TestFixture] [TestFixture]
public class TestLootFilterBlock public class TestItemFilterBlock
{ {
[Test] [Test]
public void LootFilterBlock_BlockCount_ReturnsCorrectNumber() public void ItemFilterBlock_BlockCount_ReturnsCorrectNumber()
{ {
// Arrange // Arrange
var block = new LootFilterBlock(); var block = new ItemFilterBlock();
block.BlockItems.Add(new ItemLevelBlockItem()); block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem()); block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem()); block.BlockItems.Add(new ItemLevelBlockItem());
@@ -25,10 +25,10 @@ namespace Filtration.Tests.Models
} }
[Test] [Test]
public void LootFilterBlock_AddBlockItemAllowed_LessThanMaximum_ReturnsTrue() public void ItemFilterBlock_AddBlockItemAllowed_LessThanMaximum_ReturnsTrue()
{ {
// Arrange // Arrange
var block = new LootFilterBlock(); var block = new ItemFilterBlock();
block.BlockItems.Add(new ItemLevelBlockItem()); block.BlockItems.Add(new ItemLevelBlockItem());
// Act // Act
@@ -39,10 +39,10 @@ namespace Filtration.Tests.Models
} }
[Test] [Test]
public void LootFilterBlock_AddBlockItemAllowed_MoreThanMaximum_ReturnsFalse() public void ItemFilterBlock_AddBlockItemAllowed_MoreThanMaximum_ReturnsFalse()
{ {
// Arrange // Arrange
var block = new LootFilterBlock(); var block = new ItemFilterBlock();
block.BlockItems.Add(new SoundBlockItem()); block.BlockItems.Add(new SoundBlockItem());
// Act // Act
@@ -51,5 +51,22 @@ namespace Filtration.Tests.Models
// Assert // Assert
Assert.IsFalse(result); 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.ObjectModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media; using System.Windows.Media;
using Filtration.Models; using Filtration.Models;
using Filtration.Models.BlockItemTypes; using Filtration.Models.BlockItemTypes;
@@ -12,14 +8,14 @@ using NUnit.Framework;
namespace Filtration.Tests.Models namespace Filtration.Tests.Models
{ {
[TestFixture] [TestFixture]
public class TestLootFilterScript public class TestItemFilterScript
{ {
[Test] [Test]
public void Validate_AtLeastOneBlock_Fail_ReturnsListWithCorrectError() public void Validate_AtLeastOneBlock_Fail_ReturnsListWithCorrectError()
{ {
// Arrange // Arrange
var script = new LootFilterScript(); var script = new ItemFilterScript();
// Act // Act
var result = script.Validate(); var result = script.Validate();
@@ -33,10 +29,8 @@ namespace Filtration.Tests.Models
{ {
// Arrange // Arrange
var script = new LootFilterScript var script = new ItemFilterScript();
{ script.ItemFilterBlocks.Add(new ItemFilterBlock());
LootFilterBlocks = new ObservableCollection<LootFilterBlock> {new LootFilterBlock()}
};
// Act // Act
var result = script.Validate(); var result = script.Validate();
@@ -59,22 +53,19 @@ namespace Filtration.Tests.Models
ReplaceBackgroundColor = true 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})); 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 })); 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 })); testInputBlock3.BlockItems.Add(new BackgroundColorBlockItem(new Color { A = 255, R = 255, G = 0, B = 0 }));
var script = new LootFilterScript() var script = new ItemFilterScript();
{
LootFilterBlocks = new ObservableCollection<LootFilterBlock> script.ItemFilterBlocks.Add(testInputBlock1);
{ script.ItemFilterBlocks.Add(testInputBlock2);
testInputBlock1, script.ItemFilterBlocks.Add(testInputBlock3);
testInputBlock2,
testInputBlock3
}
};
// Act // Act
script.ReplaceColors(testInputReplaceColors); script.ReplaceColors(testInputReplaceColors);
@@ -105,21 +96,16 @@ namespace Filtration.Tests.Models
ReplaceTextColor = true ReplaceTextColor = true
}; };
var testInputBlock1 = new LootFilterBlock(); var testInputBlock1 = new ItemFilterBlock();
testInputBlock1.BlockItems.Add(new BackgroundColorBlockItem(oldBackgroundColor)); testInputBlock1.BlockItems.Add(new BackgroundColorBlockItem(oldBackgroundColor));
testInputBlock1.BlockItems.Add(new TextColorBlockItem(oldTextColor)); testInputBlock1.BlockItems.Add(new TextColorBlockItem(oldTextColor));
var testInputBlock2 = new LootFilterBlock(); var testInputBlock2 = new ItemFilterBlock();
testInputBlock2.BlockItems.Add(new BackgroundColorBlockItem(oldBackgroundColor)); testInputBlock2.BlockItems.Add(new BackgroundColorBlockItem(oldBackgroundColor));
testInputBlock2.BlockItems.Add(new TextColorBlockItem(new Color {A = 1, R = 2, G = 3, B = 4})); testInputBlock2.BlockItems.Add(new TextColorBlockItem(new Color {A = 1, R = 2, G = 3, B = 4}));
var script = new LootFilterScript var script = new ItemFilterScript();
{ script.ItemFilterBlocks.Add(testInputBlock1);
LootFilterBlocks = new ObservableCollection<LootFilterBlock> script.ItemFilterBlocks.Add(testInputBlock2);
{
testInputBlock1,
testInputBlock2
}
};
// Act // Act
script.ReplaceColors(testInputReplaceColors); 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 # Begin Script Description
# This is a test script # This is a test script
# #

View File

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

View File

@@ -13,7 +13,7 @@ namespace Filtration.Tests.Services
// Arrange // Arrange
var mockFileSystemService = new Mock<IFileSystemService>(); 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); var service = new StaticDataService(mockFileSystemService.Object);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@ using System.Windows.Media;
namespace Filtration.Models namespace Filtration.Models
{ {
internal interface ILootFilterBlockItem : INotifyPropertyChanged internal interface IItemFilterBlockItem : INotifyPropertyChanged
{ {
string PrefixText { get; } string PrefixText { get; }
int MaximumAllowed { 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.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Filtration.Models.BlockItemTypes; using Filtration.Models.BlockItemTypes;
using Filtration.ViewModels;
using Filtration.Views;
namespace Filtration.Models 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 FilePath { get; set; }
public string Description { get; set; } public string Description { get; set; }
public DateTime DateModified { get; set; } public DateTime DateModified { get; set; }
@@ -24,7 +28,7 @@ namespace Filtration.Models
{ {
var validationErrors = new List<string>(); var validationErrors = new List<string>();
if (LootFilterBlocks.Count == 0) if (ItemFilterBlocks.Count == 0)
{ {
validationErrors.Add("A script must have at least one block"); validationErrors.Add("A script must have at least one block");
} }
@@ -37,7 +41,7 @@ namespace Filtration.Models
foreach ( foreach (
var block in var block in
LootFilterBlocks.Where(b => BlockIsColorReplacementCandidate(replaceColorsParameterSet, b))) ItemFilterBlocks.Where(b => BlockIsColorReplacementCandidate(replaceColorsParameterSet, b)))
{ {
if (replaceColorsParameterSet.ReplaceTextColor) 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>() var textColorItem = block.HasBlockItemOfType<TextColorBlockItem>()
? block.BlockItems.OfType<TextColorBlockItem>().First() ? 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 // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Filtration")] [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: AssemblyConfiguration("")]
[assembly: AssemblyCompany("XVar Industries Inc.")] [assembly: AssemblyCompany("XVar Industries Inc.")]
[assembly: AssemblyProduct("Filtration")] [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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.*")] [assembly: AssemblyVersion("0.3.*")]
[assembly: InternalsVisibleTo("Filtration.Tests")] [assembly: InternalsVisibleTo("Filtration.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [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 namespace Filtration.Services
{ {
internal interface ILootFilterPersistenceService internal interface IItemFilterPersistenceService
{ {
string LootFilterScriptDirectory { get; set; } string ItemFilterScriptDirectory { get; set; }
LootFilterScript LoadLootFilterScript(string filePath); ItemFilterScript LoadItemFilterScript(string filePath);
void SaveLootFilterScript(LootFilterScript script); void SaveItemFilterScript(ItemFilterScript script);
string DefaultPathOfExileDirectory(); string DefaultPathOfExileDirectory();
} }
internal class LootFilterPersistenceService : ILootFilterPersistenceService internal class ItemFilterPersistenceService : IItemFilterPersistenceService
{ {
private readonly IFileSystemService _fileSystemService; 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; _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 = var script =
_lootFilterScriptTranslator.TranslateStringToLootFilterScript( _itemFilterScriptTranslator.TranslateStringToItemFilterScript(
_fileSystemService.ReadFileAsString(filePath)); _fileSystemService.ReadFileAsString(filePath));
script.FilePath = filePath; script.FilePath = filePath;
return script; return script;
} }
public void SaveLootFilterScript(LootFilterScript script) public void SaveItemFilterScript(ItemFilterScript script)
{ {
_fileSystemService.WriteFileFromString(script.FilePath, _fileSystemService.WriteFileFromString(script.FilePath,
_lootFilterScriptTranslator.TranslateLootFilterScriptToString(script)); _itemFilterScriptTranslator.TranslateItemFilterScriptToString(script));
} }
public string DefaultPathOfExileDirectory() 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 namespace Filtration.Translators
{ {
internal interface ILootFilterBlockTranslator internal interface IItemFilterBlockTranslator
{ {
LootFilterBlock TranslateStringToLootFilterBlock(string inputString); ItemFilterBlock TranslateStringToItemFilterBlock(string inputString);
string TranslateLootFilterBlockToString(LootFilterBlock block); string TranslateItemFilterBlockToString(ItemFilterBlock block);
} }
internal class LootFilterBlockTranslator : ILootFilterBlockTranslator internal class ItemFilterBlockTranslator : IItemFilterBlockTranslator
{ {
private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder;
private const string Indent = " "; private const string Indent = " ";
private readonly string _newLine = Environment.NewLine + Indent; private readonly string _newLine = Environment.NewLine + Indent;
// This method converts a string into a LootFilterBlock. This is used for pasting LootFilterBlocks public ItemFilterBlockTranslator(IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder)
// and reading LootFilterScripts from a file.
public LootFilterBlock TranslateStringToLootFilterBlock(string inputString)
{ {
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; var showHideFound = false;
foreach (var line in new LineReader(() => new StringReader(inputString))) foreach (var line in new LineReader(() => new StringReader(inputString)))
{ {
if (line.StartsWith(@"# Section:")) if (line.StartsWith(@"# Section:"))
{ {
var section = new LootFilterSection var section = new ItemFilterSection
{ {
Description = line.Substring(line.IndexOf(":", StringComparison.Ordinal) + 1).Trim() Description = line.Substring(line.IndexOf(":", StringComparison.Ordinal) + 1).Trim()
}; };
@@ -47,7 +54,8 @@ namespace Filtration.Translators
continue; 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 spaceOrEndOfLinePos = trimmedLine.IndexOf(" ", StringComparison.Ordinal) > 0 ? trimmedLine.IndexOf(" ", StringComparison.Ordinal) : trimmedLine.Length;
var lineOption = trimmedLine.Substring(0, spaceOrEndOfLinePos); var lineOption = trimmedLine.Substring(0, spaceOrEndOfLinePos);
@@ -56,10 +64,12 @@ namespace Filtration.Translators
case "Show": case "Show":
showHideFound = true; showHideFound = true;
block.Action = BlockAction.Show; block.Action = BlockAction.Show;
AddBlockGroupToBlock(block, trimmedLine);
break; break;
case "Hide": case "Hide":
showHideFound = true; showHideFound = true;
block.Action = BlockAction.Hide; block.Action = BlockAction.Hide;
AddBlockGroupToBlock(block, trimmedLine);
break; break;
case "ItemLevel": case "ItemLevel":
{ {
@@ -122,20 +132,6 @@ namespace Filtration.Translators
} }
case "SocketGroup": 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); AddStringListItemToBlockItems<SocketGroupBlockItem>(block, trimmedLine);
break; break;
} }
@@ -215,7 +211,7 @@ namespace Filtration.Translators
return block; 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)); var existingBlockItemCount = block.BlockItems.Count(b => b.GetType() == typeof(T));
if (existingBlockItemCount > 0) 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>(); var blockItem = Activator.CreateInstance<T>();
@@ -243,7 +239,7 @@ namespace Filtration.Translators
predicate.PredicateOperand = Convert.ToInt16(result.Groups[2].Value); 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>(); var blockItem = Activator.CreateInstance<T>();
PopulateListFromString(blockItem.Items, inputString.Substring(inputString.IndexOf(" ", StringComparison.Ordinal) + 1).Trim()); 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>(); var blockItem = Activator.CreateInstance<T>();
blockItem.Color = GetColorFromString(inputString); blockItem.Color = GetColorFromString(inputString);
block.BlockItems.Add(blockItem); 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) private static Color GetColorFromString(string inputString)
{ {
var argbValues = Regex.Matches(inputString, @"\s+(\d+)"); var argbValues = Regex.Matches(inputString, @"\s+(\d+)");
@@ -294,11 +304,11 @@ namespace Filtration.Translators
return new Color(); return new Color();
} }
// This method converts a LootFilterBlock object into a string. This is used for copying a LootFilterBlock // This method converts an ItemFilterBlock object into a string. This is used for copying a ItemFilterBlock
// to the clipboard, and when saving a LootFilterScript. // to the clipboard, and when saving a ItemFilterScript.
public string TranslateLootFilterBlockToString(LootFilterBlock block) public string TranslateItemFilterBlockToString(ItemFilterBlock block)
{ {
if (block.GetType() == typeof (LootFilterSection)) if (block.GetType() == typeof (ItemFilterSection))
{ {
return "# Section: " + block.Description; return "# Section: " + block.Description;
} }
@@ -312,7 +322,12 @@ namespace Filtration.Translators
outputString += block.Action.GetAttributeDescription(); 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 // of the specific downcasts. Leaving it like this currently to preserve sorting since the different
// downcasts have no defined sort order (yet). // downcasts have no defined sort order (yet).
foreach (var blockItem in block.BlockItems.OfType<ItemLevelBlockItem>()) foreach (var blockItem in block.BlockItems.OfType<ItemLevelBlockItem>())

View File

@@ -1,30 +1,36 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Castle.Core.Internal;
using Filtration.Models; using Filtration.Models;
using Filtration.Utilities; using Filtration.Utilities;
namespace Filtration.Translators namespace Filtration.Translators
{ {
internal interface ILootFilterScriptTranslator internal interface IItemFilterScriptTranslator
{ {
LootFilterScript TranslateStringToLootFilterScript(string inputString); ItemFilterScript TranslateStringToItemFilterScript(string inputString);
string TranslateLootFilterScriptToString(LootFilterScript script); 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; _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", ""); inputString = inputString.Replace("\t", "");
var conditionBoundaries = IdentifyBlockBoundaries(inputString); var conditionBoundaries = IdentifyBlockBoundaries(inputString);
@@ -38,10 +44,14 @@ namespace Filtration.Translators
script.Description += lines[i].Substring(1).Trim(' ') + Environment.NewLine; 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 if (!script.Description.IsNullOrEmpty())
// and add that object to the LootFilterBlocks list {
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) for (var boundary = conditionBoundaries.First; boundary != null; boundary = boundary.Next)
{ {
var begin = boundary.Value; var begin = boundary.Value;
@@ -49,7 +59,7 @@ namespace Filtration.Translators
var block = new string[end - begin]; var block = new string[end - begin];
Array.Copy(lines, begin, block, 0, end - begin); Array.Copy(lines, begin, block, 0, end - begin);
var blockString = string.Join("\r\n", block); var blockString = string.Join("\r\n", block);
script.LootFilterBlocks.Add(_blockTranslator.TranslateStringToLootFilterBlock(blockString)); script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString));
} }
return script; return script;
@@ -78,7 +88,7 @@ namespace Filtration.Translators
return blockBoundaries; return blockBoundaries;
} }
public string TranslateLootFilterScriptToString(LootFilterScript script) public string TranslateItemFilterScriptToString(ItemFilterScript script)
{ {
var outputString = string.Empty; var outputString = string.Empty;
@@ -99,9 +109,9 @@ namespace Filtration.Translators
} }
// ReSharper disable once LoopCanBeConvertedToQuery // 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; return outputString;

View File

@@ -26,7 +26,7 @@
VerticalAlignment="Stretch" SelectionMode="Single" x:Name="ControlListBox" BorderBrush="#CCCCCC"> VerticalAlignment="Stretch" SelectionMode="Single" x:Name="ControlListBox" BorderBrush="#CCCCCC">
<ListBox.Resources> <ListBox.Resources>
<Style TargetType="ListBoxItem"> <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> <Style.Resources>
<!-- SelectedItem with focus --> <!-- SelectedItem with focus -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Silver" /> <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.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Filtration.Models; using Filtration.Models;
using Filtration.Models.BlockItemBaseTypes; using Filtration.Models.BlockItemBaseTypes;
@@ -11,26 +10,27 @@ using Filtration.Models.BlockItemTypes;
using Filtration.Services; using Filtration.Services;
using Filtration.Views; using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using Xceed.Wpf.Toolkit;
namespace Filtration.ViewModels 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; } 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 IStaticDataService _staticDataService;
private readonly IReplaceColorsViewModel _replaceColorsViewModel; private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private readonly MediaPlayer _mediaPlayer = new MediaPlayer(); private readonly MediaPlayer _mediaPlayer = new MediaPlayer();
private LootFilterScriptViewModel _parentScriptViewModel; private ItemFilterScriptViewModel _parentScriptViewModel;
private bool _displaySettingsPopupOpen; private bool _displaySettingsPopupOpen;
public LootFilterBlockViewModel(IStaticDataService staticDataService, IReplaceColorsViewModel replaceColorsViewModel) public ItemFilterBlockViewModel(IStaticDataService staticDataService, IReplaceColorsViewModel replaceColorsViewModel)
{ {
_staticDataService = staticDataService; _staticDataService = staticDataService;
_replaceColorsViewModel = replaceColorsViewModel; _replaceColorsViewModel = replaceColorsViewModel;
@@ -48,24 +48,24 @@ namespace Filtration.ViewModels
AddFilterBlockItemCommand = new RelayCommand<Type>(OnAddFilterBlockItemCommand); AddFilterBlockItemCommand = new RelayCommand<Type>(OnAddFilterBlockItemCommand);
ToggleBlockActionCommand = new RelayCommand(OnToggleBlockActionCommand); ToggleBlockActionCommand = new RelayCommand(OnToggleBlockActionCommand);
AddAudioVisualBlockItemCommand = new RelayCommand<Type>(OnAddAudioVisualBlockItemCommand); AddAudioVisualBlockItemCommand = new RelayCommand<Type>(OnAddAudioVisualBlockItemCommand);
RemoveFilterBlockItemCommand = new RelayCommand<ILootFilterBlockItem>(OnRemoveFilterBlockItemCommand); RemoveFilterBlockItemCommand = new RelayCommand<IItemFilterBlockItem>(OnRemoveFilterBlockItemCommand);
RemoveAudioVisualBlockItemCommand = new RelayCommand<ILootFilterBlockItem>(OnRemoveAudioVisualBlockItemCommand); RemoveAudioVisualBlockItemCommand = new RelayCommand<IItemFilterBlockItem>(OnRemoveAudioVisualBlockItemCommand);
PlaySoundCommand = new RelayCommand(OnPlaySoundCommand, () => HasSound); 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; _parentScriptViewModel = parentScriptViewModel;
Block = lootFilterBlock; Block = itemFilterBlock;
lootFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged; itemFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged;
foreach (var blockItem in lootFilterBlock.BlockItems.OfType<IAudioVisualBlockItem>()) foreach (var blockItem in itemFilterBlock.BlockItems.OfType<IAudioVisualBlockItem>())
{ {
blockItem.PropertyChanged += OnAudioVisualBlockItemChanged; blockItem.PropertyChanged += OnAudioVisualBlockItemChanged;
} }
@@ -84,28 +84,36 @@ namespace Filtration.ViewModels
public RelayCommand ReplaceColorsCommand { get; private set; } public RelayCommand ReplaceColorsCommand { get; private set; }
public RelayCommand<Type> AddFilterBlockItemCommand { get; private set; } public RelayCommand<Type> AddFilterBlockItemCommand { get; private set; }
public RelayCommand<Type> AddAudioVisualBlockItemCommand { get; private set; } public RelayCommand<Type> AddAudioVisualBlockItemCommand { get; private set; }
public RelayCommand<ILootFilterBlockItem> RemoveFilterBlockItemCommand { get; private set; } public RelayCommand<IItemFilterBlockItem> RemoveFilterBlockItemCommand { get; private set; }
public RelayCommand<ILootFilterBlockItem> RemoveAudioVisualBlockItemCommand { get; private set; } public RelayCommand<IItemFilterBlockItem> RemoveAudioVisualBlockItemCommand { get; private set; }
public RelayCommand PlaySoundCommand { 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 bool IsDirty { get; set; }
public ObservableCollection<ILootFilterBlockItem> FilterBlockItems public ObservableCollection<IItemFilterBlockItem> FilterBlockItems
{ {
get { return Block.BlockItems; } get { return Block.BlockItems; }
} }
public IEnumerable<ILootFilterBlockItem> SummaryBlockItems public IEnumerable<IItemFilterBlockItem> SummaryBlockItems
{ {
get { return Block.BlockItems.Where(b => !(b is IAudioVisualBlockItem)); } 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); } get { return Block.BlockItems.Where(b => b is IAudioVisualBlockItem); }
} }
public bool AdvancedBlockGroup
{
get
{
return Block.BlockGroup != null && Block.BlockGroup.Advanced;
}
}
public bool DisplaySettingsPopupOpen public bool DisplaySettingsPopupOpen
{ {
get { return _displaySettingsPopupOpen; } get { return _displaySettingsPopupOpen; }
@@ -189,8 +197,22 @@ namespace Filtration.ViewModels
} }
set set
{ {
Block.Description = value; if (Block.Description != value)
RaisePropertyChanged(); {
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) private void OnAddFilterBlockItemCommand(Type blockItemType)
{ {
if (!AddBlockItemAllowed(blockItemType)) return; if (!AddBlockItemAllowed(blockItemType)) return;
var newBlockItem = (ILootFilterBlockItem) Activator.CreateInstance(blockItemType); var newBlockItem = (IItemFilterBlockItem) Activator.CreateInstance(blockItemType);
FilterBlockItems.Add(newBlockItem); FilterBlockItems.Add(newBlockItem);
IsDirty = true; IsDirty = true;
} }
private void OnRemoveFilterBlockItemCommand(ILootFilterBlockItem blockItem) private void OnRemoveFilterBlockItemCommand(IItemFilterBlockItem blockItem)
{ {
FilterBlockItems.Remove(blockItem); FilterBlockItems.Remove(blockItem);
IsDirty = true; IsDirty = true;
@@ -276,7 +298,7 @@ namespace Filtration.ViewModels
private void OnAddAudioVisualBlockItemCommand(Type blockItemType) private void OnAddAudioVisualBlockItemCommand(Type blockItemType)
{ {
if (!AddBlockItemAllowed(blockItemType)) return; if (!AddBlockItemAllowed(blockItemType)) return;
var newBlockItem = (ILootFilterBlockItem) Activator.CreateInstance(blockItemType); var newBlockItem = (IItemFilterBlockItem) Activator.CreateInstance(blockItemType);
newBlockItem.PropertyChanged += OnAudioVisualBlockItemChanged; newBlockItem.PropertyChanged += OnAudioVisualBlockItemChanged;
FilterBlockItems.Add(newBlockItem); FilterBlockItems.Add(newBlockItem);
@@ -284,7 +306,7 @@ namespace Filtration.ViewModels
IsDirty = true; IsDirty = true;
} }
private void OnRemoveAudioVisualBlockItemCommand(ILootFilterBlockItem blockItem) private void OnRemoveAudioVisualBlockItemCommand(IItemFilterBlockItem blockItem)
{ {
blockItem.PropertyChanged -= OnAudioVisualBlockItemChanged; blockItem.PropertyChanged -= OnAudioVisualBlockItemChanged;
FilterBlockItems.Remove(blockItem); FilterBlockItems.Remove(blockItem);
@@ -347,7 +369,7 @@ namespace Filtration.ViewModels
private bool AddBlockItemAllowed(Type type) 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); var blockCount = FilterBlockItems.Count(b => b.GetType() == type);
return blockCount < blockItem.MaximumAllowed; 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;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using Castle.Core;
using Filtration.Models; using Filtration.Models;
using Filtration.Services; using Filtration.Services;
using Filtration.Translators; using Filtration.Translators;
using Filtration.Views; using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Clipboard = System.Windows.Clipboard; using Clipboard = System.Windows.Clipboard;
using MessageBox = System.Windows.Forms.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
namespace Filtration.ViewModels namespace Filtration.ViewModels
@@ -17,45 +17,76 @@ namespace Filtration.ViewModels
internal interface IMainWindowViewModel internal interface IMainWindowViewModel
{ {
void LoadScriptFromFile(string path); void LoadScriptFromFile(string path);
RelayCommand OpenScriptCommand { get; }
RelayCommand NewScriptCommand { get; }
} }
internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel
{ {
private LootFilterScript _loadedScript; private readonly IItemFilterScriptViewModelFactory _itemFilterScriptViewModelFactory;
private readonly IItemFilterPersistenceService _persistenceService;
private readonly ILootFilterScriptViewModelFactory _lootFilterScriptViewModelFactory; private readonly IItemFilterScriptTranslator _itemFilterScriptTranslator;
private readonly ILootFilterPersistenceService _persistenceService;
private readonly ILootFilterScriptTranslator _lootFilterScriptTranslator;
private readonly IReplaceColorsViewModel _replaceColorsViewModel; private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private ILootFilterScriptViewModel _currentScriptViewModel; private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
private readonly ObservableCollection<ILootFilterScriptViewModel> _scriptViewModels;
public MainWindowViewModel(ILootFilterScriptViewModelFactory lootFilterScriptViewModelFactory, private IDocument _activeDocument;
ILootFilterPersistenceService persistenceService,
ILootFilterScriptTranslator lootFilterScriptTranslator, public MainWindowViewModel(IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory,
IReplaceColorsViewModel replaceColorsViewModel) IItemFilterPersistenceService persistenceService,
IItemFilterScriptTranslator itemFilterScriptTranslator,
IReplaceColorsViewModel replaceColorsViewModel,
IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel)
{ {
_lootFilterScriptViewModelFactory = lootFilterScriptViewModelFactory; _itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory;
_persistenceService = persistenceService; _persistenceService = persistenceService;
_lootFilterScriptTranslator = lootFilterScriptTranslator; _itemFilterScriptTranslator = itemFilterScriptTranslator;
_replaceColorsViewModel = replaceColorsViewModel; _replaceColorsViewModel = replaceColorsViewModel;
_avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel;
_scriptViewModels = new ObservableCollection<ILootFilterScriptViewModel>();
OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand); OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand);
OpenScriptCommand = new RelayCommand(OnOpenScriptCommand); OpenScriptCommand = new RelayCommand(OnOpenScriptCommand);
SaveScriptCommand = new RelayCommand(OnSaveScriptCommand, () => CurrentScriptViewModel != null); SaveScriptCommand = new RelayCommand(OnSaveScriptCommand, ActiveDocumentIsScript);
SaveScriptAsCommand = new RelayCommand(OnSaveScriptAsCommand, () => CurrentScriptViewModel != null); SaveScriptAsCommand = new RelayCommand(OnSaveScriptAsCommand, ActiveDocumentIsScript);
CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, () => CurrentScriptViewModel != null); CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, ActiveDocumentIsScript);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => CurrentScriptViewModel != null && CurrentScriptViewModel.SelectedBlockViewModel != null); CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocumentIsScript() && (_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null));
PasteCommand = new RelayCommand(OnPasteCommand, () => CurrentScriptViewModel != null && CurrentScriptViewModel.SelectedBlockViewModel != null); PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocumentIsScript() && (_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null));
NewScriptCommand = new RelayCommand(OnNewScriptCommand); NewScriptCommand = new RelayCommand(OnNewScriptCommand);
CloseScriptCommand = new RelayCommand<ILootFilterScriptViewModel>(OnCloseScriptCommand, v => CurrentScriptViewModel != null); CloseScriptCommand = new RelayCommand(OnCloseScriptCommand, ActiveDocumentIsScript);
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => CurrentScriptViewModel != null); ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, ActiveDocumentIsScript);
//LoadScriptFromFile("C:\\ThioleLootFilter.txt"); //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; } public RelayCommand OpenScriptCommand { get; private set; }
@@ -65,13 +96,13 @@ namespace Filtration.ViewModels
public RelayCommand PasteCommand { get; private set; } public RelayCommand PasteCommand { get; private set; }
public RelayCommand CopyScriptCommand { get; private set; } public RelayCommand CopyScriptCommand { get; private set; }
public RelayCommand NewScriptCommand { 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 OpenAboutWindowCommand { get; private set; }
public RelayCommand ReplaceColorsCommand { 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 public string WindowTitle
@@ -84,23 +115,9 @@ namespace Filtration.ViewModels
} }
} }
[DoNotWire] private bool ActiveDocumentIsScript()
public ILootFilterScriptViewModel CurrentScriptViewModel
{ {
get { return _currentScriptViewModel; } return _activeDocument != null && _activeDocument.IsScript;
set
{
_currentScriptViewModel = value;
RaisePropertyChanged();
RaisePropertyChanged("NoScriptsOpen");
SaveScriptCommand.RaiseCanExecuteChanged();
SaveScriptAsCommand.RaiseCanExecuteChanged();
}
}
public bool NoScriptsOpen
{
get { return _currentScriptViewModel == null; }
} }
private void OnOpenAboutWindowCommand() private void OnOpenAboutWindowCommand()
@@ -114,7 +131,7 @@ namespace Filtration.ViewModels
var openFileDialog = new OpenFileDialog var openFileDialog = new OpenFileDialog
{ {
Filter = "Filter Files (*.filter)|*.filter|All Files (*.*)|*.*", Filter = "Filter Files (*.filter)|*.filter|All Files (*.*)|*.*",
InitialDirectory = _persistenceService.LootFilterScriptDirectory InitialDirectory = _persistenceService.ItemFilterScriptDirectory
}; };
if (openFileDialog.ShowDialog() != true) return; if (openFileDialog.ShowDialog() != true) return;
@@ -124,9 +141,10 @@ namespace Filtration.ViewModels
public void LoadScriptFromFile(string path) public void LoadScriptFromFile(string path)
{ {
var loadedScript = _persistenceService.LoadItemFilterScript(path);
try try
{ {
_loadedScript = _persistenceService.LoadLootFilterScript(path);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -135,18 +153,17 @@ namespace Filtration.ViewModels
return; return;
} }
var newViewModel = _lootFilterScriptViewModelFactory.Create(); var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(_loadedScript); newViewModel.Initialise(loadedScript, false);
ScriptViewModels.Add(newViewModel); _avalonDockWorkspaceViewModel.AddDocument(newViewModel);
CurrentScriptViewModel = newViewModel;
} }
private void SetLootFilterScriptDirectory() private void SetItemFilterScriptDirectory()
{ {
var defaultDir = _persistenceService.DefaultPathOfExileDirectory(); var defaultDir = _persistenceService.DefaultPathOfExileDirectory();
if (!string.IsNullOrEmpty(defaultDir)) if (!string.IsNullOrEmpty(defaultDir))
{ {
_persistenceService.LootFilterScriptDirectory = defaultDir; _persistenceService.ItemFilterScriptDirectory = defaultDir;
} }
else else
{ {
@@ -159,145 +176,54 @@ namespace Filtration.ViewModels
if (result == DialogResult.OK) if (result == DialogResult.OK)
{ {
_persistenceService.LootFilterScriptDirectory = dlg.SelectedPath; _persistenceService.ItemFilterScriptDirectory = dlg.SelectedPath;
} }
} }
} }
private void OnSaveScriptCommand() private void OnSaveScriptCommand()
{ {
if (!ValidateScript()) return; _avalonDockWorkspaceViewModel.ActiveScriptViewModel.SaveScript();
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);
}
} }
private void OnSaveScriptAsCommand() private void OnSaveScriptAsCommand()
{ {
if (!ValidateScript()) return; _avalonDockWorkspaceViewModel.ActiveScriptViewModel.SaveScriptAs();
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;
}
} }
private void OnReplaceColorsCommand() private void OnReplaceColorsCommand()
{ {
_replaceColorsViewModel.Initialise(CurrentScriptViewModel.Script); _replaceColorsViewModel.Initialise(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script);
var replaceColorsWindow = new ReplaceColorsWindow {DataContext = _replaceColorsViewModel}; var replaceColorsWindow = new ReplaceColorsWindow {DataContext = _replaceColorsViewModel};
replaceColorsWindow.ShowDialog(); 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() private void OnCopyScriptCommand()
{ {
Clipboard.SetText(_lootFilterScriptTranslator.TranslateLootFilterScriptToString(_currentScriptViewModel.Script)); Clipboard.SetText(_itemFilterScriptTranslator.TranslateItemFilterScriptToString(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script));
} }
private void OnCopyBlockCommand() private void OnCopyBlockCommand()
{ {
_currentScriptViewModel.CopyBlock(_currentScriptViewModel.SelectedBlockViewModel); _avalonDockWorkspaceViewModel.ActiveScriptViewModel.CopyBlock(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel);
} }
private void OnPasteCommand() private void OnPasteCommand()
{ {
_currentScriptViewModel.PasteBlock(_currentScriptViewModel.SelectedBlockViewModel); _avalonDockWorkspaceViewModel.ActiveScriptViewModel.PasteBlock(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel);
} }
private void OnNewScriptCommand() private void OnNewScriptCommand()
{ {
var newScript = new LootFilterScript(); var newScript = new ItemFilterScript();
var newViewModel = _lootFilterScriptViewModelFactory.Create(); var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(newScript); newViewModel.Initialise(newScript, true);
newViewModel.Description = "New Script"; _avalonDockWorkspaceViewModel.AddDocument(newViewModel);
ScriptViewModels.Add(newViewModel);
CurrentScriptViewModel = newViewModel;
} }
private void OnCloseScriptCommand(ILootFilterScriptViewModel scriptViewModel) private void OnCloseScriptCommand()
{ {
CurrentScriptViewModel = scriptViewModel; _avalonDockWorkspaceViewModel.ActiveScriptViewModel.Close();
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;
}
}
}
} }
} }
} }

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 System.Windows.Media;
using Filtration.Models; using Filtration.Models;
using Filtration.Models.BlockItemTypes; using Filtration.Models.BlockItemTypes;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using Xceed.Wpf.Toolkit;
namespace Filtration.ViewModels namespace Filtration.ViewModels
{ {
internal interface IReplaceColorsViewModel internal interface IReplaceColorsViewModel
{ {
void Initialise(LootFilterScript lootFilterScript, LootFilterBlock initialiseFromBlock); void Initialise(ItemFilterScript itemFilterScript, ItemFilterBlock initialiseFromBlock);
void Initialise(LootFilterScript lootFilterScript); void Initialise(ItemFilterScript itemFilterScript);
} }
internal class ReplaceColorsViewModel : FiltrationViewModelBase, IReplaceColorsViewModel internal class ReplaceColorsViewModel : FiltrationViewModelBase, IReplaceColorsViewModel
{ {
private LootFilterScript _lootFilterScript; private ItemFilterScript _itemFilterScript;
private ReplaceColorsParameterSet _replaceColorsParameterSet; private ReplaceColorsParameterSet _replaceColorsParameterSet;
public ReplaceColorsViewModel() public ReplaceColorsViewModel()
@@ -24,7 +27,7 @@ namespace Filtration.ViewModels
public RelayCommand ReplaceColorsCommand { get; private set; } public RelayCommand ReplaceColorsCommand { get; private set; }
public void Initialise(LootFilterScript lootFilterScript, LootFilterBlock initialiseFromBlock) public void Initialise(ItemFilterScript itemFilterScript, ItemFilterBlock initialiseFromBlock)
{ {
_replaceColorsParameterSet = new ReplaceColorsParameterSet(); _replaceColorsParameterSet = new ReplaceColorsParameterSet();
@@ -55,7 +58,17 @@ namespace Filtration.ViewModels
_replaceColorsParameterSet.NewBorderColor = existingBlockColor; _replaceColorsParameterSet.NewBorderColor = existingBlockColor;
} }
_lootFilterScript = lootFilterScript; _itemFilterScript = itemFilterScript;
}
public ObservableCollection<ColorItem> AvailableColors
{
get
{
{
return PathOfExileColors.DefaultColors;
}
}
} }
public Color NewTextColor public Color NewTextColor
@@ -159,15 +172,15 @@ namespace Filtration.ViewModels
} }
} }
public void Initialise(LootFilterScript lootFilterScript) public void Initialise(ItemFilterScript itemFilterScript)
{ {
_replaceColorsParameterSet = new ReplaceColorsParameterSet(); _replaceColorsParameterSet = new ReplaceColorsParameterSet();
_lootFilterScript = lootFilterScript; _itemFilterScript = itemFilterScript;
} }
private void OnReplaceColorsCommand() 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" Height="360"
Width="580" Width="580"
Loaded="AboutWindow_OnLoaded" Loaded="AboutWindow_OnLoaded"
BorderThickness="1" BorderBrush="Black"> BorderThickness="1"
BorderBrush="Black"
ShowMaxRestoreButton="False"
ShowMinButton="False">
<Grid Margin="15"> <Grid Margin="15">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition>
@@ -29,7 +32,7 @@
<Image Source="/Filtration;component/Resources/logo.png" Width="75" Height="75" VerticalAlignment="Top" /> <Image Source="/Filtration;component/Resources/logo.png" Width="75" Height="75" VerticalAlignment="Top" />
<StackPanel Grid.Row="0" Grid.Column="1"> <StackPanel Grid.Row="0" Grid.Column="1">
<TextBlock FontWeight="Black">Filtration</TextBlock> <TextBlock FontWeight="Black">Filtration</TextBlock>
<TextBlock>Version 0.2</TextBlock> <TextBlock Text="{Binding Version}" />
<TextBlock>Copyright © 2015</TextBlock> <TextBlock>Copyright © 2015</TextBlock>
<TextBlock>Created by Ben Wallis</TextBlock> <TextBlock>Created by Ben Wallis</TextBlock>
<TextBlock> <TextBlock>

View File

@@ -1,4 +1,6 @@
using System.Windows; using System.Diagnostics;
using System.Reflection;
using System.Windows;
namespace Filtration.Views namespace Filtration.Views
{ {
@@ -7,6 +9,7 @@ namespace Filtration.Views
public AboutWindow() public AboutWindow()
{ {
InitializeComponent(); InitializeComponent();
DataContext = this;
} }
private void AboutWindow_OnLoaded(object sender, RoutedEventArgs e) private void AboutWindow_OnLoaded(object sender, RoutedEventArgs e)
@@ -16,5 +19,15 @@ namespace Filtration.Views
Left = mainWindow.Left + (mainWindow.Width - ActualWidth) / 2; Left = mainWindow.Left + (mainWindow.Width - ActualWidth) / 2;
Top = mainWindow.Top + (mainWindow.Height - ActualHeight) / 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) public override DataTemplate SelectTemplate(object item, DependencyObject container)
{ {
var viewModel = item as LootFilterBlockViewModel; var viewModel = item as ItemFilterBlockViewModel;
var element = container as FrameworkElement; var element = container as FrameworkElement;
if (viewModel == null || element == null) if (viewModel == null || element == null)
return 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/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/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/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> </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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -10,7 +10,7 @@
xmlns:blockItemTypes="clr-namespace:Filtration.Models.BlockItemTypes" xmlns:blockItemTypes="clr-namespace:Filtration.Models.BlockItemTypes"
xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterBlockViewModel}" d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}"
d:DesignHeight="120" d:DesignWidth="175"> d:DesignHeight="120" d:DesignWidth="175">
<UserControl.Resources> <UserControl.Resources>
<ResourceDictionary> <ResourceDictionary>
@@ -62,7 +62,7 @@
<ColumnDefinition SharedSizeGroup="AudioVisualBlockItemCloseColumn" Width="Auto" /> <ColumnDefinition SharedSizeGroup="AudioVisualBlockItemCloseColumn" Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding DisplayHeading}" Style="{StaticResource DisplayHeading}" /> <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}" /> <userControls:CrossButton Grid.Column="2" Height="12" Command="{Binding ElementName=SettingsGrid, Path=DataContext.RemoveAudioVisualBlockItemCommand}" CommandParameter="{Binding}" />
</Grid> </Grid>
</DataTemplate> </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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -6,12 +6,13 @@
xmlns:viewModels="clr-namespace:Filtration.ViewModels" xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:userControls="clr-namespace:Filtration.UserControls" xmlns:userControls="clr-namespace:Filtration.UserControls"
xmlns:views="clr-namespace:Filtration.Views" xmlns:views="clr-namespace:Filtration.Views"
xmlns:converters="clr-namespace:Filtration.Converters"
xmlns:blockItemBaseTypes="clr-namespace:Filtration.Models.BlockItemBaseTypes" xmlns:blockItemBaseTypes="clr-namespace:Filtration.Models.BlockItemBaseTypes"
xmlns:blockItemTypes="clr-namespace:Filtration.Models.BlockItemTypes" xmlns:blockItemTypes="clr-namespace:Filtration.Models.BlockItemTypes"
xmlns:enums="clr-namespace:Filtration.Enums" xmlns:enums="clr-namespace:Filtration.Enums"
xmlns:extensions="clr-namespace:Filtration.Extensions" xmlns:extensions="clr-namespace:Filtration.Extensions"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterBlockViewModel}" d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}"
d:DesignHeight="200" d:DesignWidth="800"> d:DesignHeight="200" d:DesignWidth="800">
<UserControl.Resources> <UserControl.Resources>
<ResourceDictionary> <ResourceDictionary>
@@ -19,6 +20,8 @@
<ResourceDictionary Source="SharedResourcesDictionary.xaml" /> <ResourceDictionary Source="SharedResourcesDictionary.xaml" />
<ResourceDictionary> <ResourceDictionary>
<views:BindingProxy x:Key="proxy" Data="{Binding}" /> <views:BindingProxy x:Key="proxy" Data="{Binding}" />
<converters:BlockGroupAdvancedFillColorConverter x:Key="BlockGroupAdvancedFillColorConverter" />
</ResourceDictionary> </ResourceDictionary>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
@@ -30,10 +33,10 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Rectangle Width="7" > <Rectangle Width="7" Fill="{Binding AdvancedBlockGroup, Converter={StaticResource BlockGroupAdvancedFillColorConverter}}">
<Rectangle.Fill> <Rectangle.ToolTip>
<SolidColorBrush Color="Gray" /> <ToolTip Visibility="{Binding AdvancedBlockGroup, Converter={StaticResource BooleanVisibilityConverter}}">Advanced Block Group</ToolTip>
</Rectangle.Fill> </Rectangle.ToolTip>
</Rectangle> </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 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> <Expander.ContextMenu>
@@ -114,7 +117,7 @@
AllowsTransparency="True" AllowsTransparency="True"
HorizontalOffset="-5" HorizontalOffset="-5"
Width="250"> Width="250">
<views:LootFilterBlockDisplaySettingsView /> <views:ItemFilterBlockDisplaySettingsView />
</Popup> </Popup>
</Grid> </Grid>
</Expander.Header> </Expander.Header>

View File

@@ -1,8 +1,8 @@
namespace Filtration.Views namespace Filtration.Views
{ {
public partial class LootFilterBlockView public partial class ItemFilterBlockView
{ {
public LootFilterBlockView() public ItemFilterBlockView()
{ {
InitializeComponent(); 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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:Filtration.Views" xmlns:views="clr-namespace:Filtration.Views"
xmlns:attachedProperties="clr-namespace:Filtration.Views.AttachedProperties"
xmlns:viewModels="clr-namespace:Filtration.ViewModels" xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:userControls="clr-namespace:Filtration.UserControls" xmlns:userControls="clr-namespace:Filtration.UserControls"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterScriptViewModel}" d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterScriptViewModel}"
d:DesignHeight="300" d:DesignWidth="600"> d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources> <UserControl.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary> <ResourceDictionary>
<!-- ReSharper disable once Xaml.RedundantResource --> <!-- ReSharper disable once Xaml.RedundantResource -->
<DataTemplate x:Key="LootFilterBlockTemplate"> <DataTemplate x:Key="ItemFilterBlockTemplate">
<views:LootFilterBlockView Margin="0,2,0,2" /> <views:ItemFilterBlockView Margin="0,2,0,2" />
</DataTemplate> </DataTemplate>
<!-- ReSharper disable once Xaml.RedundantResource --> <!-- ReSharper disable once Xaml.RedundantResource -->
<DataTemplate x:Key="LootFilterSectionTemplate"> <DataTemplate x:Key="ItemFilterSectionTemplate">
<views:LootFilterSectionView Margin="0,2,0,2" /> <views:ItemFilterSectionView Margin="0,2,0,2" />
</DataTemplate> </DataTemplate>
<views:BlockTemplateSelector x:Key="BlockTemplateSelector" /> <views:BlockTemplateSelector x:Key="BlockTemplateSelector" />
</ResourceDictionary> </ResourceDictionary>
@@ -46,40 +47,24 @@
</Border> </Border>
<Border Grid.Row="1" BorderThickness="1" BorderBrush="DarkGray" Margin="5,5,5,5" Padding="2"> <Border Grid.Row="1" BorderThickness="1" BorderBrush="DarkGray" Margin="5,5,5,5" Padding="2">
<DockPanel LastChildFill="True"> <DockPanel LastChildFill="True">
<ToolBarTray DockPanel.Dock="Top"> <ToolBarTray DockPanel.Dock="Top">
<ToolBar> <ToolBar>
<Button ToolTip="Add Block" Command="{Binding AddBlockCommand}" Content="{StaticResource AddBlockIcon}" /> <Button ToolTip="Add Block" Command="{Binding AddBlockCommand}" Content="{StaticResource AddBlockIcon}" />
<Button ToolTip="Add Section" Command="{Binding AddSectionCommand}" Content="{StaticResource AddSectionIcon}" /> <Button ToolTip="Add Section" Command="{Binding AddSectionCommand}" Content="{StaticResource AddSectionIcon}" />
<Button ToolTip="Delete Block/Section" Command="{Binding DeleteBlockCommand}" Content="{StaticResource DeleteIcon}" /> <Button ToolTip="Delete Block/Section" Command="{Binding DeleteBlockCommand}" Content="{StaticResource DeleteIcon}" />
</ToolBar> </ToolBar>
<ToolBar> <ToolBar>
<Button ToolTip="Move Block to Top" Command="{Binding MoveBlockToTopCommand}" Content="{StaticResource MoveToTopIcon}" /> <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 Up" Command="{Binding MoveBlockUpCommand}" Content="{StaticResource MoveUpIcon}" />
<Button ToolTip="Move Block Down" Command="{Binding MoveBlockDownCommand}" Content="{StaticResource MoveDownIcon}" /> <Button ToolTip="Move Block Down" Command="{Binding MoveBlockDownCommand}" Content="{StaticResource MoveDownIcon}" />
<Button ToolTip="Move Block to Bottom" Command="{Binding MoveBlockToBottomCommand}" Content="{StaticResource MoveToBottomIcon}" /> <Button ToolTip="Move Block to Bottom" Command="{Binding MoveBlockToBottomCommand}" Content="{StaticResource MoveToBottomIcon}" />
</ToolBar> </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> </ToolBarTray>
<Expander DockPanel.Dock="Left" ExpandDirection="Right" MaxWidth="200" HorizontalAlignment="Left" > <userControls:AutoScrollingListBox ItemsSource="{Binding ItemFilterBlockViewModels}"
<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}"
Margin="5,5,5,5" Margin="5,5,5,5"
Padding="5" Padding="5"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
@@ -87,6 +72,7 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.VirtualizationMode="Recycling"
ItemTemplateSelector="{StaticResource BlockTemplateSelector}" ItemTemplateSelector="{StaticResource BlockTemplateSelector}"
attachedProperties:SelectingItemAttachedProperty.SelectingItem="{Binding SectionBrowserSelectedBlockViewModel}"
SelectedItem="{Binding SelectedBlockViewModel}" x:Name="BlocksListBox"> SelectedItem="{Binding SelectedBlockViewModel}" x:Name="BlocksListBox">
<ListBox.InputBindings> <ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteBlockCommand}" /> <KeyBinding Key="Delete" Command="{Binding DeleteBlockCommand}" />

View File

@@ -1,8 +1,8 @@
namespace Filtration.Views namespace Filtration.Views
{ {
public partial class LootFilterSectionView public partial class ItemFilterScriptView
{ {
public LootFilterSectionView() public ItemFilterScriptView()
{ {
InitializeComponent(); 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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewModels="clr-namespace:Filtration.ViewModels" xmlns:viewModels="clr-namespace:Filtration.ViewModels"
d:DataContext="{d:DesignInstance Type=viewModels:LootFilterBlockViewModel}" d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="300"> d:DesignHeight="50" d:DesignWidth="300">
<UserControl.Resources> <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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:views="clr-namespace:Filtration.Views"
xmlns:viewModels="clr-namespace:Filtration.ViewModels" xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:userControls="clr-namespace:Filtration.UserControls" xmlns:viewsAvalonDock="clr-namespace:Filtration.Views.AvalonDock"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}" d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}"
Title="{Binding WindowTitle}" Height="707" Width="930" BorderThickness="1" BorderBrush="Black"> Title="{Binding WindowTitle}" Height="768" Width="1024" BorderThickness="1" BorderBrush="Black">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<DockPanel> <DockPanel>
<Menu DockPanel.Dock="Top"> <Menu DockPanel.Dock="Top">
<MenuItem Header="_File"> <MenuItem Header="_File">
@@ -22,7 +17,7 @@
<MenuItem Header="_Open Script" Command="{Binding OpenScriptCommand}" Icon="{StaticResource OpenIcon}"/> <MenuItem Header="_Open Script" Command="{Binding OpenScriptCommand}" Icon="{StaticResource OpenIcon}"/>
<MenuItem Header="_Save Script" Command="{Binding SaveScriptCommand}" Icon="{StaticResource SaveIcon}"/> <MenuItem Header="_Save Script" Command="{Binding SaveScriptCommand}" Icon="{StaticResource SaveIcon}"/>
<MenuItem Header="Save Script _As" Command="{Binding SaveScriptAsCommand}" 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 Header="E_xit"/>
</MenuItem> </MenuItem>
<MenuItem Header="_Edit"> <MenuItem Header="_Edit">
@@ -46,25 +41,7 @@
</ToolBar> </ToolBar>
</ToolBarTray> </ToolBarTray>
<Grid> <Grid>
<controls:MetroTabControl ItemsSource="{Binding ScriptViewModels}" SelectedItem="{Binding CurrentScriptViewModel}" Name="TabControl" Background="White"> <viewsAvalonDock:AvalonDockWorkspaceView DataContext="{Binding AvalonDockWorkspaceViewModel}" />
<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>
</Grid> </Grid>
</DockPanel> </DockPanel>
</controls:MetroWindow> </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> </Grid.ColumnDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" Content="Replace Text Color" IsChecked="{Binding ReplaceTextColor}" /> <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> <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> <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}" /> <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> <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> <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}" /> <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> <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> <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}" /> <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> <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); .LifeStyle.Singleton);
container.Register( container.Register(
Component.For<ILootFilterPersistenceService>() Component.For<IItemFilterPersistenceService>()
.ImplementedBy<LootFilterPersistenceService>() .ImplementedBy<ItemFilterPersistenceService>()
.LifeStyle.Singleton); .LifeStyle.Singleton);
container.Register( container.Register(

View File

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

View File

@@ -13,16 +13,21 @@ namespace Filtration.WindsorInstallers
container.Register( container.Register(
Component.For<IMainWindowViewModel>() Component.For<IMainWindowViewModel>()
.ImplementedBy<MainWindowViewModel>() .ImplementedBy<MainWindowViewModel>()
.LifeStyle.Singleton);
container.Register(
Component.For<IAvalonDockWorkspaceViewModel>()
.ImplementedBy<AvalonDockWorkspaceViewModel>()
.LifeStyle.Singleton);
container.Register(
Component.For<IItemFilterBlockViewModel>()
.ImplementedBy<ItemFilterBlockViewModel>()
.LifeStyle.Transient); .LifeStyle.Transient);
container.Register( container.Register(
Component.For<ILootFilterBlockViewModel>() Component.For<IItemFilterScriptViewModel>()
.ImplementedBy<LootFilterBlockViewModel>() .ImplementedBy<ItemFilterScriptViewModel>()
.LifeStyle.Transient);
container.Register(
Component.For<ILootFilterScriptViewModel>()
.ImplementedBy<LootFilterScriptViewModel>()
.LifeStyle.Transient); .LifeStyle.Transient);
container.Register( container.Register(
@@ -30,12 +35,27 @@ namespace Filtration.WindsorInstallers
.ImplementedBy<ReplaceColorsViewModel>() .ImplementedBy<ReplaceColorsViewModel>()
.LifeStyle.Singleton); .LifeStyle.Singleton);
container.AddFacility<TypedFactoryFacility>();
container.Register( container.Register(
Component.For<ILootFilterBlockViewModelFactory>().AsFactory()); Component.For<IStartPageViewModel>()
.ImplementedBy<StartPageViewModel>()
.LifeStyle.Singleton);
container.Register( 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"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="AvalonDock" version="2.0.2000" targetFramework="net451" />
<package id="Castle.Core" version="3.3.0" targetFramework="net451" /> <package id="Castle.Core" version="3.3.0" targetFramework="net451" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net451" /> <package id="Castle.Windsor" version="3.3.0" targetFramework="net451" />
<package id="CommonServiceLocator" version="1.3" 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. Filtration is an editor for Path of Exile item filter scripts.
## Current Release ## 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 ## System Requirements
Filtration requires .NET Framework 4.5.1 installed. Filtration requires .NET Framework 4.5.1 installed.