Merge pull request #75 from azakhi/feature/40-add-enable-disable-to-group-browser

Feature/40 add enable disable to group browser
This commit is contained in:
Ben Wallis 2018-09-08 10:12:04 +01:00 committed by GitHub
commit 18c878e350
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 519 additions and 105 deletions

View File

@ -14,6 +14,7 @@ namespace Filtration.ObjectModel
public interface IItemFilterBlock : IItemFilterBlockBase public interface IItemFilterBlock : IItemFilterBlockBase
{ {
bool Enabled { get; set; } bool Enabled { get; set; }
event EventHandler EnabledStatusChanged;
string Description { get; set; } string Description { get; set; }
ItemFilterBlockGroup BlockGroup { get; set; } ItemFilterBlockGroup BlockGroup { get; set; }
BlockAction Action { get; set; } BlockAction Action { get; set; }
@ -88,6 +89,7 @@ namespace Filtration.ObjectModel
{ {
BlockItems = new ObservableCollection<IItemFilterBlockItem> { ActionBlockItem }; BlockItems = new ObservableCollection<IItemFilterBlockItem> { ActionBlockItem };
BlockItems.CollectionChanged += new NotifyCollectionChangedEventHandler(OnBlockItemsChanged); BlockItems.CollectionChanged += new NotifyCollectionChangedEventHandler(OnBlockItemsChanged);
ActionBlockItem.PropertyChanged += OnActionBlockItemChanged;
_enabled = true; _enabled = true;
} }
@ -95,6 +97,7 @@ namespace Filtration.ObjectModel
{ {
BlockItems = new ObservableCollection<IItemFilterBlockItem> { ActionBlockItem }; BlockItems = new ObservableCollection<IItemFilterBlockItem> { ActionBlockItem };
BlockItems.CollectionChanged += new NotifyCollectionChangedEventHandler(OnBlockItemsChanged); BlockItems.CollectionChanged += new NotifyCollectionChangedEventHandler(OnBlockItemsChanged);
ActionBlockItem.PropertyChanged += OnActionBlockItemChanged;
_enabled = true; _enabled = true;
} }
@ -105,8 +108,16 @@ namespace Filtration.ObjectModel
{ {
_enabled = value; _enabled = value;
IsEdited = true; IsEdited = true;
EnabledStatusChanged?.Invoke(null, null);
if(BlockGroup != null && BlockGroup.IsEnableChecked != value)
{
BlockGroup.IsEnableChecked = value;
}
} }
} }
public event EventHandler EnabledStatusChanged;
public string Description public string Description
{ {
get { return _description; } get { return _description; }
@ -165,6 +176,13 @@ namespace Filtration.ObjectModel
{ {
IsEdited = true; IsEdited = true;
} }
private void OnActionBlockItemChanged(object sender, EventArgs e)
{
if (BlockGroup != null && BlockGroup.IsShowChecked != (Action == BlockAction.Show))
{
BlockGroup.IsShowChecked = (Action == BlockAction.Show);
}
}
public bool AddBlockItemAllowed(Type type) public bool AddBlockItemAllowed(Type type)
{ {
@ -198,14 +216,23 @@ namespace Filtration.ObjectModel
private void OnBlockGroupStatusChanged(object sender, EventArgs e) private void OnBlockGroupStatusChanged(object sender, EventArgs e)
{ {
if (BlockGroup.IsChecked == false && Action == BlockAction.Show) if (BlockGroup.IsShowChecked == false && Action == BlockAction.Show)
{ {
Action = BlockAction.Hide; Action = BlockAction.Hide;
} }
else if (BlockGroup.IsChecked && Action == BlockAction.Hide) else if (BlockGroup.IsShowChecked == true && Action == BlockAction.Hide)
{ {
Action = BlockAction.Show; Action = BlockAction.Show;
} }
if (BlockGroup.IsEnableChecked == false && Enabled)
{
Enabled = false;
}
else if (BlockGroup.IsEnableChecked == true && !Enabled)
{
Enabled = true;
}
} }
public Color DisplayTextColor public Color DisplayTextColor

View File

@ -5,31 +5,34 @@ namespace Filtration.ObjectModel
{ {
public class ItemFilterBlockGroup public class ItemFilterBlockGroup
{ {
private bool _isChecked; private bool? _isShowChecked;
private bool? _isEnableChecked;
public ItemFilterBlockGroup(string groupName, ItemFilterBlockGroup parent, bool advanced = false) public ItemFilterBlockGroup(string groupName, ItemFilterBlockGroup parent, bool advanced = false, bool isLeafNode = false)
{ {
GroupName = groupName; GroupName = groupName;
ParentGroup = parent; ParentGroup = parent;
Advanced = advanced; Advanced = advanced;
ChildGroups = new List<ItemFilterBlockGroup>(); ChildGroups = new List<ItemFilterBlockGroup>();
IsLeafNode = isLeafNode;
} }
public string GroupName { get; }
public ItemFilterBlockGroup ParentGroup { get; set; }
public List<ItemFilterBlockGroup> ChildGroups { get; }
public bool Advanced { get; }
public bool IsLeafNode { get; }
public event EventHandler BlockGroupStatusChanged; public event EventHandler BlockGroupStatusChanged;
public string GroupName { get; } public bool? IsShowChecked
public ItemFilterBlockGroup ParentGroup { get; }
public List<ItemFilterBlockGroup> ChildGroups { get; }
public bool Advanced { get; }
public bool IsChecked
{ {
get { return _isChecked; } get { return _isShowChecked; }
set set
{ {
if (value != _isChecked) if (value != _isShowChecked)
{ {
_isChecked = value; _isShowChecked = value;
// Raise an event to let blocks that have this block group assigned that // 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. // they might need to change their Action due to the block group status changing.
BlockGroupStatusChanged?.Invoke(null, null); BlockGroupStatusChanged?.Invoke(null, null);
@ -37,20 +40,85 @@ namespace Filtration.ObjectModel
} }
} }
public bool? IsEnableChecked
{
get { return _isEnableChecked; }
set
{
if (value != _isEnableChecked)
{
_isEnableChecked = value;
// Raise an event to let blocks that have this block group assigned that
// they might need to change their Enabled due to the block group status changing.
BlockGroupStatusChanged?.Invoke(null, null);
}
}
}
public void ClearStatusChangeSubscribers()
{
BlockGroupStatusChanged = null;
}
public void AddOrJoinBlockGroup(ItemFilterBlockGroup blockGroup)
{
var childIndex = ChildGroups.FindIndex(item => item.GroupName.Equals(blockGroup.GroupName));
if (!blockGroup.IsLeafNode && childIndex >= 0)
{
while(blockGroup.ChildGroups.Count > 0)
{
ChildGroups[childIndex].AddOrJoinBlockGroup(blockGroup.ChildGroups[0]);
}
}
else
{
if(blockGroup.ParentGroup != null)
{
blockGroup.ParentGroup.ChildGroups.Remove(blockGroup);
}
blockGroup.ParentGroup = this;
ChildGroups.Add(blockGroup);
}
}
public void DetachSelf(bool keepChildren)
{
if(ParentGroup == null)
return;
if(IsLeafNode && ParentGroup.ParentGroup != null && ParentGroup.ChildGroups.Count < 2)
{
ParentGroup.DetachSelf(false);
}
else
{
ParentGroup.ChildGroups.Remove(this);
if (keepChildren)
{
foreach(var child in ChildGroups)
{
ParentGroup.AddOrJoinBlockGroup(child);
}
}
ParentGroup = null;
}
}
public override string ToString() public override string ToString()
{ {
var currentBlockGroup = this; if(ParentGroup == null)
{
return string.Empty;
}
var outputString = (Advanced ? "~" : string.Empty) + GroupName; var outputString = (Advanced ? "~" : string.Empty) + GroupName;
// TODO: This is retarded, fix this. var parentOutput = ParentGroup.ToString();
if (currentBlockGroup.ParentGroup != null) if(!string.IsNullOrWhiteSpace(parentOutput))
{ {
while (currentBlockGroup.ParentGroup.ParentGroup != null) outputString = parentOutput + (IsLeafNode ? string.Empty : " - " + outputString);
{
outputString = (currentBlockGroup.ParentGroup.Advanced ? "~" : string.Empty) + currentBlockGroup.ParentGroup.GroupName + " - " + outputString;
currentBlockGroup = currentBlockGroup.ParentGroup;
}
} }
return outputString; return outputString;

View File

@ -7,6 +7,6 @@ namespace Filtration.Parser.Interface.Services
{ {
void Initialise(ItemFilterBlockGroup rootBlockGroup); void Initialise(ItemFilterBlockGroup rootBlockGroup);
void Cleanup(); void Cleanup();
ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings); ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings, bool show, bool enabled);
} }
} }

View File

@ -18,11 +18,11 @@ namespace Filtration.Parser.Tests.Services
var builder = new BlockGroupHierarchyBuilder(); var builder = new BlockGroupHierarchyBuilder();
// Act // Act
var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
// Assert // Assert
Assert.AreEqual(1, rootBlock.ChildGroups.Count); Assert.AreEqual(1, rootBlock.ChildGroups.Count);
Assert.AreEqual("Sub Block Group", result.GroupName); Assert.AreEqual("Sub Block Group", result.ParentGroup.GroupName);
} }
[Test] [Test]
@ -35,11 +35,11 @@ namespace Filtration.Parser.Tests.Services
var builder = new BlockGroupHierarchyBuilder(); var builder = new BlockGroupHierarchyBuilder();
// Act // Act
var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
// Assert // Assert
Assert.AreEqual(1, rootBlock.ChildGroups.Count); Assert.AreEqual(1, rootBlock.ChildGroups.Count);
Assert.AreEqual("Block Group", result.GroupName); Assert.AreEqual("Block Group", result.ParentGroup.GroupName);
} }
[Test] [Test]
@ -52,12 +52,12 @@ namespace Filtration.Parser.Tests.Services
var builder = new BlockGroupHierarchyBuilder(); var builder = new BlockGroupHierarchyBuilder();
// Act // Act
var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
// Assert // Assert
Assert.AreEqual(1, rootBlock.ChildGroups.Count); Assert.AreEqual(1, rootBlock.ChildGroups.Count);
Assert.AreEqual("Block Group", result.GroupName); Assert.AreEqual("Block Group", result.ParentGroup.GroupName);
Assert.AreEqual(true, result.Advanced); Assert.AreEqual(true, result.ParentGroup.Advanced);
} }
[Test] [Test]
@ -70,11 +70,11 @@ namespace Filtration.Parser.Tests.Services
var builder = new BlockGroupHierarchyBuilder(); var builder = new BlockGroupHierarchyBuilder();
// Act // Act
var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
// Assert // Assert
Assert.AreEqual(1, rootBlock.ChildGroups.Count); Assert.AreEqual(1, rootBlock.ChildGroups.Count);
Assert.AreEqual(true, result.Advanced); Assert.AreEqual(true, result.ParentGroup.Advanced);
} }
[Test] [Test]
@ -90,12 +90,12 @@ namespace Filtration.Parser.Tests.Services
var builder = new BlockGroupHierarchyBuilder(); var builder = new BlockGroupHierarchyBuilder();
// Act // Act
var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
// Assert // Assert
Assert.AreEqual(1, rootBlock.ChildGroups.Count); Assert.AreEqual(1, rootBlock.ChildGroups.Count);
Assert.AreEqual("Block Group", result.GroupName); Assert.AreEqual("Block Group", result.ParentGroup.GroupName);
Assert.AreEqual(true, result.Advanced); Assert.AreEqual(true, result.ParentGroup.Advanced);
} }
[Test] [Test]
@ -107,15 +107,15 @@ namespace Filtration.Parser.Tests.Services
// Act // Act
var inputStrings = new List<string> { "Block Group" }; var inputStrings = new List<string> { "Block Group" };
builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
inputStrings = new List<string> { "Block Group 2" }; inputStrings = new List<string> { "Block Group 2" };
builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
inputStrings = new List<string> { "Block Group", "Sub Block Group" }; inputStrings = new List<string> { "Block Group", "Sub Block Group" };
var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock); var result = builder.IntegrateStringListIntoBlockGroupHierarchy(inputStrings, rootBlock, true, true);
// Assert // Assert
Assert.AreEqual(2, rootBlock.ChildGroups.Count); Assert.AreEqual(2, rootBlock.ChildGroups.Count);
Assert.AreEqual("Sub Block Group", result.GroupName); Assert.AreEqual("Sub Block Group", result.ParentGroup.GroupName);
} }
} }
} }

View File

@ -48,7 +48,7 @@ namespace Filtration.Parser.Tests.Services
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null); var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
_testUtility.MockBlockGroupHierarchyBuilder _testUtility.MockBlockGroupHierarchyBuilder
.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())) .Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true))
.Returns(inputBlockGroup); .Returns(inputBlockGroup);
// Act // Act
@ -121,6 +121,7 @@ namespace Filtration.Parser.Tests.Services
Assert.AreEqual(FilterPredicateOperator.GreaterThanOrEqual, blockItem.FilterPredicate.PredicateOperator); Assert.AreEqual(FilterPredicateOperator.GreaterThanOrEqual, blockItem.FilterPredicate.PredicateOperator);
} }
[Ignore("Update required, ItemFilterBlockTranslator does not set IsShowChecked anymore")]
[Test] [Test]
public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_ShowBlock_SetsBlockGroupIsCheckedCorrectly() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_ShowBlock_SetsBlockGroupIsCheckedCorrectly()
{ {
@ -129,13 +130,14 @@ namespace Filtration.Parser.Tests.Services
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null); var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true)).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
Assert.AreEqual(true, inputBlockGroup.IsChecked); Assert.AreEqual(true, inputBlockGroup.IsShowChecked);
} }
[Ignore("Update required, ItemFilterBlockTranslator does not set IsShowChecked anymore")]
[Test] [Test]
public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_HideBlock_SetsBlockGroupIsCheckedCorrectly() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_HideBlock_SetsBlockGroupIsCheckedCorrectly()
{ {
@ -144,11 +146,11 @@ namespace Filtration.Parser.Tests.Services
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null); var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), false, true)).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
Assert.AreEqual(false, inputBlockGroup.IsChecked); Assert.AreEqual(false, inputBlockGroup.IsShowChecked);
} }
[Test] [Test]
@ -159,7 +161,7 @@ namespace Filtration.Parser.Tests.Services
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null); var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true)).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
@ -173,11 +175,11 @@ namespace Filtration.Parser.Tests.Services
var inputString = "Show" + Environment.NewLine; var inputString = "Show" + Environment.NewLine;
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true)).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
_testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never); _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true), Times.Never);
} }
[Test] [Test]
@ -190,7 +192,7 @@ namespace Filtration.Parser.Tests.Services
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
_testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never); _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true), Times.Never);
} }
[Test] [Test]
@ -202,7 +204,7 @@ namespace Filtration.Parser.Tests.Services
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder _testUtility.MockBlockGroupHierarchyBuilder
.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.Is<IEnumerable<string>>(s => s.Contains("Test Block Group") && s.Contains("Test Sub Block Group") && s.Contains("Test Another Block Group")))) .Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.Is<IEnumerable<string>>(s => s.Contains("Test Block Group") && s.Contains("Test Sub Block Group") && s.Contains("Test Another Block Group")), true, true))
.Returns(testBlockGroup) .Returns(testBlockGroup)
.Verifiable(); .Verifiable();
@ -222,7 +224,7 @@ namespace Filtration.Parser.Tests.Services
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder _testUtility.MockBlockGroupHierarchyBuilder
.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.Is<IEnumerable<string>>(s => s.Contains("AAA-BBB-CCC")))) .Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.Is<IEnumerable<string>>(s => s.Contains("AAA-BBB-CCC")), true, true))
.Returns(testBlockGroup) .Returns(testBlockGroup)
.Verifiable(); .Verifiable();
@ -244,7 +246,7 @@ namespace Filtration.Parser.Tests.Services
// Assert // Assert
Assert.IsNull(result.BlockGroup); Assert.IsNull(result.BlockGroup);
_testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never); _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, true), Times.Never);
} }
[Test] [Test]

View File

@ -119,7 +119,7 @@ namespace Filtration.Parser.Tests.Services
" Class \"Life Flasks\" \"Mana Flasks\"" + Environment.NewLine + " Class \"Life Flasks\" \"Mana Flasks\"" + Environment.NewLine +
" Rarity Normal " " Rarity Normal "
) )
} && s.ItemFilterBlockGroups == new ObservableCollection<ItemFilterBlockGroup> { new ItemFilterBlockGroup("Root", null, false) } } && s.ItemFilterBlockGroups == new ObservableCollection<ItemFilterBlockGroup> { new ItemFilterBlockGroup("Root", null, false, false) }
&& s.ThemeComponents == new ThemeComponentCollection() && s.ThemeComponents == new ThemeComponentCollection()
&& s.ItemFilterScriptSettings == new ItemFilterScriptSettings(new ThemeComponentCollection()) && s.ItemFilterScriptSettings == new ItemFilterScriptSettings(new ThemeComponentCollection())
&& s.Description == "Script description\r\nScript description\r\nScript description\r\nScript description"); && s.Description == "Script description\r\nScript description\r\nScript description\r\nScript description");
@ -385,8 +385,8 @@ namespace Filtration.Parser.Tests.Services
var mockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>(); var mockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
mockBlockGroupHierarchyBuilder.Setup( mockBlockGroupHierarchyBuilder.Setup(
b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())) b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>(), true, false))
.Returns(new ItemFilterBlockGroup("My Block Group", null)); .Returns(new ItemFilterBlockGroup("My Block Group", null, false, true));
var blockTranslator = new ItemFilterBlockTranslator(mockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(mockBlockGroupHierarchyBuilder.Object);

View File

@ -20,16 +20,16 @@ namespace Filtration.Parser.Services
_rootBlockGroup = null; _rootBlockGroup = null;
} }
public ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings) public ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings, bool show, bool enabled)
{ {
if (_rootBlockGroup == null) if (_rootBlockGroup == null)
{ {
throw new Exception("BlockGroupHierarchyBuilder must be initialised with root BlockGroup before use"); throw new Exception("BlockGroupHierarchyBuilder must be initialised with root BlockGroup before use");
} }
return IntegrateStringListIntoBlockGroupHierarchy(groupStrings, _rootBlockGroup); return IntegrateStringListIntoBlockGroupHierarchy(groupStrings, _rootBlockGroup, show, enabled);
} }
public ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings, ItemFilterBlockGroup startItemGroup) public ItemFilterBlockGroup IntegrateStringListIntoBlockGroupHierarchy(IEnumerable<string> groupStrings, ItemFilterBlockGroup startItemGroup, bool show, bool enabled)
{ {
var inputGroups = groupStrings.ToList(); var inputGroups = groupStrings.ToList();
var firstGroup = inputGroups.First().Trim(); var firstGroup = inputGroups.First().Trim();
@ -47,12 +47,47 @@ namespace Filtration.Parser.Services
if (matchingChildItemGroup == null) if (matchingChildItemGroup == null)
{ {
var newItemGroup = CreateBlockGroup(inputGroups.First().Trim(), startItemGroup); var newItemGroup = CreateBlockGroup(inputGroups.First().Trim(), startItemGroup);
newItemGroup.IsShowChecked = show;
newItemGroup.IsEnableChecked = enabled;
startItemGroup.ChildGroups.Add(newItemGroup); startItemGroup.ChildGroups.Add(newItemGroup);
inputGroups = inputGroups.Skip(1).ToList(); inputGroups = inputGroups.Skip(1).ToList();
return inputGroups.Count > 0 ? IntegrateStringListIntoBlockGroupHierarchy(inputGroups, newItemGroup) : newItemGroup; if (inputGroups.Count > 0)
{
return IntegrateStringListIntoBlockGroupHierarchy(inputGroups, newItemGroup, show, enabled);
}
else
{
var leafNode = new ItemFilterBlockGroup("", newItemGroup, false, true);
leafNode.IsShowChecked = show;
leafNode.IsEnableChecked = enabled;
newItemGroup.ChildGroups.Add(leafNode);
return leafNode;
}
}
else
{
if(matchingChildItemGroup.IsShowChecked != show)
{
matchingChildItemGroup.IsShowChecked = null;
}
if (matchingChildItemGroup.IsEnableChecked != enabled)
{
matchingChildItemGroup.IsEnableChecked = null;
}
} }
inputGroups = inputGroups.Skip(1).ToList(); inputGroups = inputGroups.Skip(1).ToList();
return inputGroups.Count > 0 ? IntegrateStringListIntoBlockGroupHierarchy(inputGroups, matchingChildItemGroup) : matchingChildItemGroup; if(inputGroups.Count > 0)
{
return IntegrateStringListIntoBlockGroupHierarchy(inputGroups, matchingChildItemGroup, show, enabled);
}
else
{
var leafNode = new ItemFilterBlockGroup("", matchingChildItemGroup, false, true);
leafNode.IsShowChecked = show;
leafNode.IsEnableChecked = enabled;
matchingChildItemGroup.ChildGroups.Add(leafNode);
return leafNode;
}
} }
private ItemFilterBlockGroup CreateBlockGroup(string groupNameString, ItemFilterBlockGroup parentGroup) private ItemFilterBlockGroup CreateBlockGroup(string groupNameString, ItemFilterBlockGroup parentGroup)

View File

@ -666,8 +666,8 @@ namespace Filtration.Parser.Services
if (blockGroups.Count(b => !string.IsNullOrEmpty(b.Trim())) > 0) if (blockGroups.Count(b => !string.IsNullOrEmpty(b.Trim())) > 0)
{ {
block.BlockGroup = _blockGroupHierarchyBuilder.IntegrateStringListIntoBlockGroupHierarchy(blockGroups); block.BlockGroup = _blockGroupHierarchyBuilder.IntegrateStringListIntoBlockGroupHierarchy(blockGroups,
block.BlockGroup.IsChecked = block.Action == BlockAction.Show; block.Action == BlockAction.Show, block.Enabled);
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.ObjectModel; using System;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Filtration.Common.ViewModels; using Filtration.Common.ViewModels;
using Filtration.ObjectModel; using Filtration.ObjectModel;
@ -8,9 +9,12 @@ namespace Filtration.ViewModels
{ {
internal class ItemFilterBlockGroupViewModel : ViewModelBase internal class ItemFilterBlockGroupViewModel : ViewModelBase
{ {
private bool? _isChecked; private bool? _isShowChecked;
private bool _reentrancyCheck; private bool? _isEnableChecked;
private bool _postMapComplete; private bool _showReentrancyCheck;
private bool _enableReentrancyCheck;
private bool _showPostMapComplete;
private bool _enablePostMapComplete;
private bool _isExpanded; private bool _isExpanded;
public ItemFilterBlockGroupViewModel() public ItemFilterBlockGroupViewModel()
@ -24,7 +28,10 @@ namespace Filtration.ViewModels
ParentGroup = parent; ParentGroup = parent;
Advanced = itemFilterBlockGroup.Advanced; Advanced = itemFilterBlockGroup.Advanced;
SourceBlockGroup = itemFilterBlockGroup; SourceBlockGroup = itemFilterBlockGroup;
IsChecked = itemFilterBlockGroup.IsChecked; SourceBlockGroup.ClearStatusChangeSubscribers();
SourceBlockGroup.BlockGroupStatusChanged += OnSourceBlockGroupStatusChanged;
IsShowChecked = itemFilterBlockGroup.IsShowChecked;
IsEnableChecked = itemFilterBlockGroup.IsEnableChecked;
ChildGroups = new ObservableCollection<ItemFilterBlockGroupViewModel>(); ChildGroups = new ObservableCollection<ItemFilterBlockGroupViewModel>();
foreach (var childGroup in itemFilterBlockGroup.ChildGroups.Where(c => showAdvanced || !c.Advanced)) foreach (var childGroup in itemFilterBlockGroup.ChildGroups.Where(c => showAdvanced || !c.Advanced))
@ -32,6 +39,12 @@ namespace Filtration.ViewModels
ChildGroups.Add(new ItemFilterBlockGroupViewModel(childGroup, showAdvanced, this)); ChildGroups.Add(new ItemFilterBlockGroupViewModel(childGroup, showAdvanced, this));
} }
VisibleChildGroups = new ObservableCollection<ItemFilterBlockGroupViewModel>();
foreach (var childGroup in ChildGroups.Where(item => !item.IsHidden))
{
VisibleChildGroups.Add(childGroup);
}
if (ChildGroups.Any()) if (ChildGroups.Any())
{ {
SetIsCheckedBasedOnChildGroups(); SetIsCheckedBasedOnChildGroups();
@ -40,54 +53,105 @@ namespace Filtration.ViewModels
private void SetIsCheckedBasedOnChildGroups() private void SetIsCheckedBasedOnChildGroups()
{ {
if (ChildGroups.All(g => g.IsChecked == true)) if (ChildGroups.All(g => g.IsShowChecked == true))
{ {
IsChecked = true; IsShowChecked = true;
} }
else if (ChildGroups.Any(g => g.IsChecked == true || g.IsChecked == null)) else if (ChildGroups.Any(g => g.IsShowChecked == true || g.IsShowChecked == null))
{ {
IsChecked = null; IsShowChecked = null;
} }
else else
{ {
IsChecked = false; IsShowChecked = false;
}
if (ChildGroups.All(g => g.IsEnableChecked == true))
{
IsEnableChecked = true;
}
else if (ChildGroups.Any(g => g.IsEnableChecked == true || g.IsEnableChecked == null))
{
IsEnableChecked = null;
}
else
{
IsEnableChecked = false;
} }
} }
public string GroupName { get; internal set; } public string GroupName { get; internal set; }
public ItemFilterBlockGroupViewModel ParentGroup { get; internal set; } public ItemFilterBlockGroupViewModel ParentGroup { get; internal set; }
public ObservableCollection<ItemFilterBlockGroupViewModel> ChildGroups { get; internal set; } public ObservableCollection<ItemFilterBlockGroupViewModel> ChildGroups { get; internal set; }
public ObservableCollection<ItemFilterBlockGroupViewModel> VisibleChildGroups { get; internal set; }
public bool Advanced { get; internal set; } public bool Advanced { get; internal set; }
public bool IsHidden
{
get => SourceBlockGroup.IsLeafNode;
}
public ItemFilterBlockGroup SourceBlockGroup { get; internal set; } public ItemFilterBlockGroup SourceBlockGroup { get; internal set; }
public bool? IsChecked public bool? IsShowChecked
{ {
get get
{ {
return _isChecked; return _isShowChecked;
} }
set set
{ {
if (!_postMapComplete) if (!_showPostMapComplete)
{ {
_isChecked = value; _isShowChecked = value;
_postMapComplete = true; _showPostMapComplete = true;
} }
else else
{ {
if (_isChecked != value) if (_isShowChecked != value)
{ {
if (_reentrancyCheck) if (_showReentrancyCheck)
{ {
return; return;
} }
_reentrancyCheck = true; _showReentrancyCheck = true;
_isChecked = value; _isShowChecked = value;
UpdateCheckState(); UpdateCheckState(true);
RaisePropertyChanged(); RaisePropertyChanged();
SourceBlockGroup.IsChecked = value ?? false; SourceBlockGroup.IsShowChecked = value;
_reentrancyCheck = false; _showReentrancyCheck = false;
}
}
}
}
public bool? IsEnableChecked
{
get
{
return _isEnableChecked;
}
set
{
if (!_enablePostMapComplete)
{
_isEnableChecked = value;
_enablePostMapComplete = true;
}
else
{
if (_isEnableChecked != value)
{
if (_enableReentrancyCheck)
{
return;
}
_enableReentrancyCheck = true;
_isEnableChecked = value;
UpdateCheckState(false);
RaisePropertyChanged();
SourceBlockGroup.IsEnableChecked = value;
_enableReentrancyCheck = false;
} }
} }
} }
@ -103,39 +167,74 @@ namespace Filtration.ViewModels
} }
} }
private void UpdateCheckState() public void SetIsExpandedForAll(bool isExpanded)
{
IsExpanded = isExpanded;
foreach(var child in VisibleChildGroups)
{
child.SetIsExpandedForAll(isExpanded);
}
}
public void RecalculateCheckState()
{
_isShowChecked = DetermineCheckState(true);
_isEnableChecked = DetermineCheckState(false);
RaisePropertyChanged(nameof(IsShowChecked));
RaisePropertyChanged(nameof(IsEnableChecked));
}
private void UpdateCheckState(bool isShowCheck)
{ {
// update all children: // update all children:
if (ChildGroups.Count != 0) if (ChildGroups.Count != 0)
{ {
UpdateChildrenCheckState(); UpdateChildrenCheckState(isShowCheck);
} }
// update parent item // inform parent about the change
if (ParentGroup != null) if (ParentGroup != null)
{ {
var parentIsChecked = ParentGroup.DetermineCheckState(); var parentValue = isShowCheck ? ParentGroup.IsShowChecked : ParentGroup.IsEnableChecked;
ParentGroup.IsChecked = parentIsChecked; var ownValue = isShowCheck ? IsShowChecked : IsEnableChecked;
if (parentValue != ownValue)
{
ParentGroup.RecalculateCheckState();
}
} }
} }
private void UpdateChildrenCheckState() private void UpdateChildrenCheckState(bool isShowCheck)
{ {
foreach (var childGroup in ChildGroups.Where(c => IsChecked != null)) // Update children only when state is not null which means update is either from children
// (all children must have same value to be not null) or from user
if (isShowCheck && IsShowChecked != null)
{ {
childGroup.IsChecked = IsChecked; foreach (var childGroup in ChildGroups.Where(c => IsShowChecked != null))
{
childGroup.IsShowChecked = IsShowChecked;
}
}
else if (IsEnableChecked != null)
{
foreach (var childGroup in ChildGroups.Where(c => IsEnableChecked != null))
{
childGroup.IsEnableChecked = IsEnableChecked;
}
} }
} }
private bool? DetermineCheckState() private bool? DetermineCheckState(bool isShowCheck)
{ {
var allChildrenChecked = ChildGroups.Count(x => x.IsChecked == true) == ChildGroups.Count; var allChildrenChecked = (isShowCheck ? ChildGroups.Count(x => x.IsShowChecked == true) :
ChildGroups.Count(x => x.IsEnableChecked == true)) == ChildGroups.Count;
if (allChildrenChecked) if (allChildrenChecked)
{ {
return true; return true;
} }
var allChildrenUnchecked = ChildGroups.Count(x => x.IsChecked == false) == ChildGroups.Count; var allChildrenUnchecked = (isShowCheck ? ChildGroups.Count(x => x.IsShowChecked == false) :
ChildGroups.Count(x => x.IsEnableChecked == false)) == ChildGroups.Count;
if (allChildrenUnchecked) if (allChildrenUnchecked)
{ {
return false; return false;
@ -143,5 +242,19 @@ namespace Filtration.ViewModels
return null; return null;
} }
private void OnSourceBlockGroupStatusChanged(object sender, EventArgs e)
{
// We assume that source block group status is only changed by either view model
// or related ItemFilterBlock if leaf node
if(SourceBlockGroup.IsShowChecked != IsShowChecked)
{
IsShowChecked = SourceBlockGroup.IsShowChecked;
}
if (SourceBlockGroup.IsEnableChecked != IsEnableChecked)
{
IsEnableChecked = SourceBlockGroup.IsEnableChecked;
}
}
} }
} }

View File

@ -12,6 +12,7 @@ using Filtration.ObjectModel.Enums;
using Filtration.Services; using Filtration.Services;
using Filtration.Views; using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Win32; using Microsoft.Win32;
using Xceed.Wpf.Toolkit; using Xceed.Wpf.Toolkit;
@ -52,6 +53,8 @@ namespace Filtration.ViewModels
PlayPositionalSoundCommand = new RelayCommand(OnPlayPositionalSoundCommand, () => HasPositionalSound); PlayPositionalSoundCommand = new RelayCommand(OnPlayPositionalSoundCommand, () => HasPositionalSound);
PlayCustomSoundCommand = new RelayCommand(OnPlayCustomSoundCommand, () => HasCustomSound); PlayCustomSoundCommand = new RelayCommand(OnPlayCustomSoundCommand, () => HasCustomSound);
CustomSoundFileDialogCommand = new RelayCommand(OnCustomSoundFileDialog); CustomSoundFileDialogCommand = new RelayCommand(OnCustomSoundFileDialog);
AddBlockGroupCommand = new RelayCommand(OnAddBlockGroupCommand);
DeleteBlockGroupCommand = new RelayCommand(OnDeleteBlockGroupCommand, () => BlockGroups.Count > 0);
} }
public override void Initialise(IItemFilterBlockBase itemFilterBlockBase, IItemFilterScriptViewModel parentScriptViewModel) public override void Initialise(IItemFilterBlockBase itemFilterBlockBase, IItemFilterScriptViewModel parentScriptViewModel)
@ -62,9 +65,12 @@ namespace Filtration.ViewModels
throw new ArgumentNullException(nameof(itemFilterBlock)); throw new ArgumentNullException(nameof(itemFilterBlock));
} }
BlockGroups = new ObservableCollection<ItemFilterBlockGroup>();
_parentScriptViewModel = parentScriptViewModel; _parentScriptViewModel = parentScriptViewModel;
Block = itemFilterBlock; Block = itemFilterBlock;
Block.EnabledStatusChanged += OnBlockEnabledStatusChanged;
itemFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged; itemFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged;
@ -73,6 +79,8 @@ namespace Filtration.ViewModels
blockItem.PropertyChanged += OnBlockItemChanged; blockItem.PropertyChanged += OnBlockItemChanged;
} }
base.Initialise(itemFilterBlock, parentScriptViewModel); base.Initialise(itemFilterBlock, parentScriptViewModel);
UpdateBlockGroups();
} }
public RelayCommand CopyBlockStyleCommand { get; } public RelayCommand CopyBlockStyleCommand { get; }
@ -86,9 +94,16 @@ namespace Filtration.ViewModels
public RelayCommand SwitchBlockItemsViewCommand { get; } public RelayCommand SwitchBlockItemsViewCommand { get; }
public RelayCommand CustomSoundFileDialogCommand { get; } public RelayCommand CustomSoundFileDialogCommand { get; }
public RelayCommand PlayCustomSoundCommand { get; } public RelayCommand PlayCustomSoundCommand { get; }
public RelayCommand AddBlockGroupCommand { get; }
public RelayCommand DeleteBlockGroupCommand { get; }
public IItemFilterBlock Block { get; private set; } public IItemFilterBlock Block { get; private set; }
public ObservableCollection<ItemFilterBlockGroup> BlockGroups { get; internal set; }
public ObservableCollection<string> BlockGroupSuggestions { get; internal set; }
public string BlockGroupSearch { get; set; }
public bool IsExpanded public bool IsExpanded
{ {
@ -117,7 +132,7 @@ namespace Filtration.ViewModels
get { return Block.BlockItems.Where(b => b is IAudioVisualBlockItem); } get { return Block.BlockItems.Where(b => b is IAudioVisualBlockItem); }
} }
public bool AdvancedBlockGroup => Block.BlockGroup != null && Block.BlockGroup.Advanced; public bool AdvancedBlockGroup => Block.BlockGroup?.ParentGroup != null && Block.BlockGroup.ParentGroup.Advanced;
public bool AudioVisualBlockItemsGridVisible public bool AudioVisualBlockItemsGridVisible
{ {
@ -438,6 +453,11 @@ namespace Filtration.ViewModels
} }
} }
private void OnBlockEnabledStatusChanged(object sender, EventArgs e)
{
RaisePropertyChanged(nameof(BlockEnabled));
}
private void OnBlockItemChanged(object sender, EventArgs e) private void OnBlockItemChanged(object sender, EventArgs e)
{ {
var itemFilterBlockItem = sender as IItemFilterBlockItem; var itemFilterBlockItem = sender as IItemFilterBlockItem;
@ -529,5 +549,104 @@ namespace Filtration.ViewModels
MessageBox.Show("Couldn't play the file. Please be sure it is a valid audio file."); MessageBox.Show("Couldn't play the file. Please be sure it is a valid audio file.");
} }
} }
private void OnAddBlockGroupCommand()
{
var baseBlock = Block as ItemFilterBlock;
if (baseBlock == null)
return;
if (!string.IsNullOrWhiteSpace(BlockGroupSearch))
{
var blockToAdd = _parentScriptViewModel.Script.ItemFilterBlockGroups.First();
if(BlockGroups.Count > 0)
{
blockToAdd = BlockGroups.Last();
}
var newGroup = new ItemFilterBlockGroup(BlockGroupSearch, null, AdvancedBlockGroup, false);
if (baseBlock.BlockGroup == null)
{
baseBlock.BlockGroup = new ItemFilterBlockGroup("", null, false, true);
baseBlock.BlockGroup.IsShowChecked = baseBlock.Action == BlockAction.Show;
baseBlock.BlockGroup.IsEnableChecked = BlockEnabled;
}
newGroup.AddOrJoinBlockGroup(baseBlock.BlockGroup);
blockToAdd.AddOrJoinBlockGroup(newGroup);
Block.IsEdited = true;
_parentScriptViewModel.SetDirtyFlag();
Messenger.Default.Send(new NotificationMessage<bool>(_parentScriptViewModel.ShowAdvanced, "BlockGroupsChanged"));
UpdateBlockGroups();
}
BlockGroupSearch = "";
RaisePropertyChanged(nameof(BlockGroupSearch));
}
private void OnDeleteBlockGroupCommand()
{
if(BlockGroups.Count > 0)
{
Block.BlockGroup.DetachSelf(false);
BlockGroups.RemoveAt(BlockGroups.Count - 1);
var blockToAdd = _parentScriptViewModel.Script.ItemFilterBlockGroups.First();
if (BlockGroups.Count > 0)
{
blockToAdd = BlockGroups.Last();
}
blockToAdd.AddOrJoinBlockGroup(Block.BlockGroup);
Block.IsEdited = true;
_parentScriptViewModel.SetDirtyFlag();
Messenger.Default.Send(new NotificationMessage<bool>(_parentScriptViewModel.ShowAdvanced, "BlockGroupsChanged"));
UpdateBlockGroups();
}
}
private void UpdateBlockGroups()
{
var baseBlock = Block as ItemFilterBlock;
if (baseBlock == null)
return;
var currentGroup = baseBlock.BlockGroup;
var groupList = new List<ItemFilterBlockGroup>();
while (currentGroup != null)
{
groupList.Add(currentGroup);
currentGroup = currentGroup.ParentGroup;
}
var topGroup = _parentScriptViewModel.Script.ItemFilterBlockGroups.First();
if (groupList.Count > 1)
{
groupList.Reverse();
groupList.RemoveAt(0);
groupList.RemoveAt(groupList.Count - 1);
if(groupList.Count > 0)
{
topGroup = groupList.Last();
}
}
BlockGroups = new ObservableCollection<ItemFilterBlockGroup>(groupList);
BlockGroupSuggestions = new ObservableCollection<string>();
foreach(var child in topGroup.ChildGroups)
{
if(!child.IsLeafNode)
{
BlockGroupSuggestions.Add(child.GroupName);
}
}
RaisePropertyChanged(nameof(BlockGroups));
RaisePropertyChanged(nameof(BlockGroupSuggestions));
}
} }
} }

View File

@ -112,7 +112,7 @@ namespace Filtration.ViewModels.ToolPanes
// This assumes that there will only ever be a single root node. // This assumes that there will only ever be a single root node.
return new ObservableCollection<ItemFilterBlockGroupViewModel> return new ObservableCollection<ItemFilterBlockGroupViewModel>
( (
new ItemFilterBlockGroupViewModel(AvalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.ItemFilterBlockGroups.First(), showAdvanced, null).ChildGroups new ItemFilterBlockGroupViewModel(AvalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.ItemFilterBlockGroups.First(), showAdvanced, null).VisibleChildGroups
); );
} }
@ -131,7 +131,7 @@ namespace Filtration.ViewModels.ToolPanes
{ {
foreach (var vm in BlockGroupViewModels) foreach (var vm in BlockGroupViewModels)
{ {
vm.IsExpanded = true; vm.SetIsExpandedForAll(true);
} }
} }
@ -139,7 +139,7 @@ namespace Filtration.ViewModels.ToolPanes
{ {
foreach (var vm in BlockGroupViewModels) foreach (var vm in BlockGroupViewModels)
{ {
vm.IsExpanded = false; vm.SetIsExpandedForAll(false);
} }
} }
} }

View File

@ -5,6 +5,7 @@
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"
xmlns:userControls="clr-namespace:Filtration.UserControls" xmlns:userControls="clr-namespace:Filtration.UserControls"
xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
xmlns:views="clr-namespace:Filtration.Views" xmlns:views="clr-namespace:Filtration.Views"
xmlns:converters="clr-namespace:Filtration.Converters" xmlns:converters="clr-namespace:Filtration.Converters"
xmlns:blockItemBaseTypes="clr-namespace:Filtration.ObjectModel.BlockItemBaseTypes;assembly=Filtration.ObjectModel" xmlns:blockItemBaseTypes="clr-namespace:Filtration.ObjectModel.BlockItemBaseTypes;assembly=Filtration.ObjectModel"
@ -200,9 +201,47 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition /> <RowDefinition />
<RowDefinition />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid Grid.Row="0" Visibility="{Binding AudioVisualBlockItemsGridVisible, Converter={StaticResource InverseBooleanVisibilityConverter}}"> <WrapPanel Grid.Row="0">
<TextBlock Text="Group" VerticalAlignment="Center" FontWeight="Bold" />
<ItemsControl ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding BlockGroups}"
BorderThickness="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel VerticalAlignment="Center">
<TextBlock Text=" > " FontWeight="ExtraBold" />
<TextBlock Text="{Binding GroupName}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Height="10" Command="{Binding DeleteBlockGroupCommand}" Content="{StaticResource DeleteIcon}" ToolTip="Delete"
Background="Transparent" BorderThickness="0" Margin="2,3,0,0" VerticalAlignment="Top">
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<toolkit:AutoCompleteBox ItemsSource="{Binding BlockGroupSuggestions}" Text="{Binding BlockGroupSearch, Mode=TwoWay}"
MinWidth="100" Margin="5,0,0,0" BorderThickness="0, 0, 0, 1" FilterMode="Contains"
PreviewKeyDown="AutoCompleteBox_PreviewKeyDown" />
<Button Height="12" Command="{Binding AddBlockGroupCommand}" Content="{StaticResource AddIcon}"
ToolTip="Add" Background="Transparent" BorderThickness="0" Margin="3,0,0,0" />
</WrapPanel>
<Grid Grid.Row="1" Visibility="{Binding AudioVisualBlockItemsGridVisible, Converter={StaticResource InverseBooleanVisibilityConverter}}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition /> <RowDefinition />
@ -285,7 +324,7 @@
</ItemsControl> </ItemsControl>
</WrapPanel> </WrapPanel>
</Grid> </Grid>
<Grid Grid.Row="0" Visibility="{Binding AudioVisualBlockItemsGridVisible, Converter={StaticResource BooleanVisibilityConverter}}"> <Grid Grid.Row="1" Visibility="{Binding AudioVisualBlockItemsGridVisible, Converter={StaticResource BooleanVisibilityConverter}}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition /> <RowDefinition />
@ -339,7 +378,7 @@
</ItemsControl> </ItemsControl>
</WrapPanel> </WrapPanel>
</Grid> </Grid>
<Grid Grid.Row="1" Margin="0,5,0,5"> <Grid Grid.Row="2" Margin="0,5,0,5">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />

View File

@ -20,5 +20,15 @@ namespace Filtration.Views
BlockExpander.IsExpanded = !BlockExpander.IsExpanded; BlockExpander.IsExpanded = !BlockExpander.IsExpanded;
} }
private void AutoCompleteBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
System.Windows.Controls.AutoCompleteBox box = sender as System.Windows.Controls.AutoCompleteBox;
dynamic viewModel = box.DataContext;
viewModel.AddBlockGroupCommand.Execute(null);
}
}
} }
} }

View File

@ -36,10 +36,11 @@
</Style> </Style>
</TreeView.ItemContainerStyle> </TreeView.ItemContainerStyle>
<TreeView.Resources> <TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type viewModels:ItemFilterBlockGroupViewModel}" ItemsSource="{Binding ChildGroups}"> <HierarchicalDataTemplate DataType="{x:Type viewModels:ItemFilterBlockGroupViewModel}" ItemsSource="{Binding VisibleChildGroups}">
<WrapPanel> <WrapPanel>
<CheckBox IsThreeState="True" IsChecked="{Binding IsChecked}" Click="BlockGroupCheckBox_Clicked" /> <CheckBox IsThreeState="True" IsChecked="{Binding IsShowChecked}" Click="BlockGroupCheckBox_Clicked" ToolTip="Show/Hide" />
<TextBlock Text="{Binding GroupName}" VerticalAlignment="Center" Foreground="{Binding Advanced, Converter={StaticResource BlockGroupAdvancedColorConverter}}" /> <CheckBox IsThreeState="True" IsChecked="{Binding IsEnableChecked}" Click="BlockGroupCheckBox_Clicked" ToolTip="Enable/Disable" />
<TextBlock Text="{Binding GroupName}" VerticalAlignment="Center" Foreground="{Binding Advanced, Converter={StaticResource BlockGroupAdvancedColorConverter}}" />
</WrapPanel> </WrapPanel>
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
</TreeView.Resources> </TreeView.Resources>