Add custom sound theme support

This commit is contained in:
azakhi 2018-08-29 13:11:41 +03:00
parent 2958d93b33
commit a09f0a5090
24 changed files with 255 additions and 14 deletions

View File

@ -1,10 +1,13 @@
using System.Windows.Media;
using System;
using System.Windows.Media;
using Filtration.ObjectModel.ThemeEditor;
namespace Filtration.ObjectModel.BlockItemBaseTypes
{
public abstract class StringBlockItem : BlockItemBase, IAudioVisualBlockItem
public abstract class StringBlockItem : BlockItemBase, IAudioVisualBlockItem, IBlockItemWithTheme
{
private string _value;
private ThemeComponent _themeComponent;
protected StringBlockItem()
{
@ -15,12 +18,36 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes
Value = value;
}
public override string OutputText => PrefixText + " \"" + Value + "\"";
public override string OutputText => PrefixText + " \"" + Value + "\""
+ (ThemeComponent != null ? " # " + ThemeComponent.ComponentName : string.Empty);
public override string SummaryText => string.Empty;
public override Color SummaryBackgroundColor => Colors.Transparent;
public override Color SummaryTextColor => Colors.Transparent;
public ThemeComponent ThemeComponent
{
get { return _themeComponent; }
set
{
if (_themeComponent == value) { return; }
if (_themeComponent != null)
{
_themeComponent.ThemeComponentUpdated -= OnThemeComponentUpdated;
_themeComponent.ThemeComponentDeleted -= OnThemeComponentDeleted;
}
if (value != null)
{
value.ThemeComponentUpdated += OnThemeComponentUpdated;
value.ThemeComponentDeleted += OnThemeComponentDeleted;
}
_themeComponent = value;
OnPropertyChanged();
}
}
public string Value
{
get { return _value; }
@ -31,5 +58,15 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes
OnPropertyChanged();
}
}
private void OnThemeComponentUpdated(object sender, EventArgs e)
{
Value = ((StringThemeComponent)sender).Value;
}
private void OnThemeComponentDeleted(object sender, EventArgs e)
{
ThemeComponent = null;
}
}
}

View File

@ -6,7 +6,7 @@ namespace Filtration.ObjectModel.BlockItemTypes
{
public CustomSoundBlockItem()
{
Value = "";
Value = "placeholder.mp3";
}
public CustomSoundBlockItem(string value) : base(value)

View File

@ -13,6 +13,8 @@ namespace Filtration.ObjectModel.Enums
[Description("Font Size")]
FontSize,
[Description("Alert Sound")]
AlertSound
AlertSound,
[Description("Custom Sound")]
CustomSound
}
}

View File

@ -37,10 +37,26 @@
<Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath>
</Reference>
<Reference Include="CommonServiceLocator, Version=2.0.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\CommonServiceLocator.2.0.2\lib\net45\CommonServiceLocator.dll</HintPath>
</Reference>
<Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
</Reference>
<Reference Include="GalaSoft.MvvmLight.Extras, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=669f0b5e8f868abf, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll</HintPath>
</Reference>
<Reference Include="GalaSoft.MvvmLight.Platform, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=5f873c45e98af8a1, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -132,6 +148,7 @@
<Compile Include="ReplaceColorsParameterSet.cs" />
<Compile Include="Socket.cs" />
<Compile Include="SocketGroup.cs" />
<Compile Include="ThemeEditor\StringThemeComponent.cs" />
<Compile Include="ThemeEditor\StrIntThemeComponent.cs" />
<Compile Include="ThemeEditor\IntegerThemeComponent.cs" />
<Compile Include="ThemeEditor\Theme.cs" />
@ -141,6 +158,9 @@
<Compile Include="WindsorInstallers\CommandsInstaller.cs" />
<Compile Include="WindsorInstallers\ModelsInstaller.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -1,5 +1,4 @@
using System;
using System.Windows.Media;
using Filtration.ObjectModel.Enums;
namespace Filtration.ObjectModel.ThemeEditor

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.ObjectModel;
using Filtration.ObjectModel.Enums;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
namespace Filtration.ObjectModel.ThemeEditor
{
[Serializable]
public class StringThemeComponent : ThemeComponent
{
private string _value;
public static ObservableCollection<string> _customSoundsAvailable;
public StringThemeComponent(ThemeComponentType componentType, string componentName, string componentValue)
{
if (componentName == null || componentValue == null)
{
throw new ArgumentException("Null parameters not allowed in StringThemeComponent constructor");
}
ComponentType = componentType;
Value = componentValue;
ComponentName = componentName;
if (_customSoundsAvailable == null || _customSoundsAvailable.Count < 1)
{
_customSoundsAvailable = new ObservableCollection<string> {
"1maybevaluable.mp3", "2currency.mp3", "3uniques.mp3", "4maps.mp3", "5highmaps.mp3",
"6veryvaluable.mp3", "7chancing.mp3", "12leveling.mp3", "placeholder.mp3"
};
}
if (_customSoundsAvailable.IndexOf(Value) < 0)
{
_customSoundsAvailable.Add(Value);
}
CustomSoundFileDialogCommand = new RelayCommand(OnCustomSoundFileDialog);
}
public RelayCommand CustomSoundFileDialogCommand { get; set; }
public ObservableCollection<string> CustomSoundsAvailable => _customSoundsAvailable;
public string Value
{
get { return _value; }
set
{
_value = value;
OnPropertyChanged();
_themeComponentUpdatedEventHandler?.Invoke(this, EventArgs.Empty);
}
}
private void OnCustomSoundFileDialog()
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.DefaultExt = ".mp3";
var poePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToString() + @"\My Games\Path of Exile\";
fileDialog.InitialDirectory = poePath;
Nullable<bool> result = fileDialog.ShowDialog();
if (result == true)
{
var fileName = fileDialog.FileName;
if (fileName.StartsWith(poePath))
{
fileName = fileName.Replace(poePath, "");
}
if (CustomSoundsAvailable.IndexOf(fileName) < 0)
{
CustomSoundsAvailable.Add(fileName);
OnPropertyChanged(nameof(CustomSoundsAvailable));
}
Value = fileName;
}
}
}
}

View File

@ -48,6 +48,19 @@ namespace Filtration.ObjectModel.ThemeEditor
return component;
}
public ThemeComponent AddComponent(ThemeComponentType componentType, string componentName, string componentValue)
{
if (ComponentExists(componentType, componentName))
{
return Items.FirstOrDefault(t => t.ComponentName == componentName && t.ComponentType == componentType);
}
var component = new StringThemeComponent(componentType, componentName, componentValue);
Items.Add(component);
return component;
}
private bool ComponentExists(ThemeComponentType componentType, string componentName)
{
var componentCount =

View File

@ -2,4 +2,6 @@
<packages>
<package id="Castle.Core" version="3.3.0" targetFramework="net461" />
<package id="Castle.Windsor" version="3.4.0" targetFramework="net461" />
<package id="CommonServiceLocator" version="2.0.2" targetFramework="net461" />
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" />
</packages>

View File

@ -349,14 +349,20 @@ namespace Filtration.Parser.Services
RemoveExistingBlockItemsOfType<SoundBlockItem>(block);
RemoveExistingBlockItemsOfType<PositionalSoundBlockItem>(block);
var match = Regex.Match(trimmedLine, @"\S+\s+""(\S+)""");
var match = Regex.Match(trimmedLine, @"\S+\s+""(\S+)""\s*([#]?)(.*)");
if (match.Success)
{
var blockItemValue = new CustomSoundBlockItem
{
Value = match.Groups[1].Value
};
};
if(match.Groups[2].Value == "#" && !string.IsNullOrWhiteSpace(match.Groups[3].Value))
{
ThemeComponent themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.CustomSound, match.Groups[3].Value.Trim(), blockItemValue.Value);
blockItemValue.ThemeComponent = themeComponent;
}
block.BlockItems.Add(blockItemValue);
}
break;

View File

@ -39,6 +39,10 @@ namespace Filtration.ThemeEditor.Converters
{
return "Alert Sound Theme Components";
}
case "Custom Sound":
{
return "Custom Alert Sound Theme Components";
}
}
return type.GetAttributeDescription();

View File

@ -109,6 +109,7 @@
<Compile Include="Services\ThemePersistenceService.cs" />
<Compile Include="Services\ThemeService.cs" />
<Compile Include="ViewModels\ColorThemeComponentViewModel.cs" />
<Compile Include="ViewModels\StringThemeComponentViewModel.cs" />
<Compile Include="ViewModels\StrIntThemeComponentViewModel.cs" />
<Compile Include="ViewModels\IntegerThemeComponentViewModel.cs" />
<Compile Include="ViewModels\IThemeViewModelFactory.cs" />
@ -138,7 +139,10 @@
<Name>Filtration.ObjectModel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Resource Include="Resources\open_icon.png" />
<Resource Include="Resources\speaker_icon.png" />
</ItemGroup>
<ItemGroup>
<Page Include="Views\ThemeComponentControl.xaml">
<SubType>Designer</SubType>

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,9 @@
using System.Windows.Media;
namespace Filtration.ThemeEditor.ViewModels
{
public class StringThemeComponentViewModel : ThemeComponentViewModel
{
public string Value { get; set; }
}
}

View File

@ -208,6 +208,9 @@ namespace Filtration.ThemeEditor.ViewModels
case ThemeComponentType.AlertSound:
Components.Add(new StrIntThemeComponent(themeComponentType, "Untitled Component", "1", 100));
break;
case ThemeComponentType.CustomSound:
Components.Add(new StringThemeComponent(themeComponentType, "Untitled Component", "placeholder.mp3"));
break;
}
}

View File

@ -7,6 +7,7 @@
xmlns:commonConverters="clr-namespace:Filtration.Common.Converters;assembly=Filtration.Common"
xmlns:themeEditor="clr-namespace:Filtration.ObjectModel.ThemeEditor;assembly=Filtration.ObjectModel"
xmlns:views="clr-namespace:Filtration.ThemeEditor.Views"
xmlns:viewModels="clr-namespace:Filtration.ThemeEditor.ViewModels"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=themeEditor:ThemeComponent}"
d:DesignHeight="100" d:DesignWidth="200">
@ -81,6 +82,23 @@
<xctk:ShortUpDown Grid.Column="1" Value="{Binding SecondValue}" HorizontalAlignment="Right"/>
</Grid>
</DataTemplate>
<!--TODO:File block type and string block type should be separate-->
<!-- Custom Sound Theme Template -->
<DataTemplate DataType="{x:Type themeEditor:StringThemeComponent}">
<Grid>
<!--TODO: Add play sound support-->
<!--<Button Grid.Column="0" Command="{Binding PlayCustomSoundCommand}" Width="20" Height="20" Background="Transparent" BorderBrush="Transparent">
<Image Source="/Filtration.ThemeEditor;component/Resources/speaker_icon.png" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Button>-->
<ComboBox ItemsSource="{Binding CustomSoundsAvailable}"
SelectedValue="{Binding Value}" Style="{StaticResource MetroComboBox}"/>
<Button Command="{Binding CustomSoundFileDialogCommand}"
Width="20" Height="20" Background="Transparent" BorderBrush="Transparent" Margin="0,0,30,0" VerticalAlignment="Center" HorizontalAlignment="Right">
<Image Source="/Filtration.ThemeEditor;component/Resources/open_icon.png"/>
</Button>
</Grid>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>

View File

@ -49,6 +49,7 @@ namespace Filtration
cfg.CreateMap<ColorThemeComponent, ColorThemeComponentViewModel>().ReverseMap();
cfg.CreateMap<IntegerThemeComponent, IntegerThemeComponentViewModel>().ReverseMap();
cfg.CreateMap<StrIntThemeComponent, StrIntThemeComponentViewModel>().ReverseMap();
cfg.CreateMap<StringThemeComponent, StringThemeComponentViewModel>().ReverseMap();
cfg.CreateMap<IThemeEditorViewModel, Theme>();
});

View File

@ -41,6 +41,10 @@ namespace Filtration.Converters
{
themeComponentType = ThemeComponentType.AlertSound;
}
else if (blockItem.GetType() == typeof(CustomSoundBlockItem))
{
themeComponentType = ThemeComponentType.CustomSound;
}
else
{
return null;

View File

@ -185,15 +185,27 @@
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Command="{Binding Path=DataContext.PlayCustomSoundCommand, RelativeSource={RelativeSource AncestorType={x:Type views:ItemFilterBlockView}}}" Width="20" Height="20" Background="Transparent" BorderBrush="Transparent">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0" Command="{Binding Path=DataContext.PlayCustomSoundCommand, RelativeSource={RelativeSource AncestorType={x:Type views:ItemFilterBlockView}}}" Width="20" Height="20" Background="Transparent" BorderBrush="Transparent">
<Image Source="/Filtration;component/Resources/Icons/speaker_icon.png" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Button>
<ComboBox Grid.Column="1" ItemsSource="{Binding Path=DataContext.CustomSoundsAvailable, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type views:ItemFilterBlockView}}}"
SelectedValue="{Binding Value}" Style="{StaticResource MetroComboBox}"/>
<Button Grid.Column="1" Command="{Binding Path=DataContext.CustomSoundFileDialogCommand, RelativeSource={RelativeSource AncestorType={x:Type views:ItemFilterBlockView}}}"
<ComboBox Grid.Column="1" Grid.Row="0" ItemsSource="{Binding Path=DataContext.CustomSoundsAvailable, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type views:ItemFilterBlockView}}}"
SelectedValue="{Binding Value, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource MetroComboBox}"/>
<Button Grid.Column="1" Grid.Row="0" Command="{Binding Path=DataContext.CustomSoundFileDialogCommand, RelativeSource={RelativeSource AncestorType={x:Type views:ItemFilterBlockView}}}"
Width="20" Height="20" Background="Transparent" BorderBrush="Transparent" Margin="0,0,30,0" VerticalAlignment="Center" HorizontalAlignment="Right">
<Image Grid.Column="1" Source="/Filtration;component/Resources/Icons/open_icon.png"/>
</Button>
<userControls:ThemeComponentSelectionControl Grid.Row="1" Grid.Column="1" ThemeComponent="{Binding ThemeComponent}" Margin="0,2,0,0">
<userControls:ThemeComponentSelectionControl.AvailableThemeComponents>
<MultiBinding Converter="{StaticResource AvailableThemeComponentsConverter}">
<Binding Path="DataContext.Script.ThemeComponents" RelativeSource="{RelativeSource AncestorType={x:Type views:ItemFilterScriptView}}"/>
<Binding Path="." />
</MultiBinding>
</userControls:ThemeComponentSelectionControl.AvailableThemeComponents>
</userControls:ThemeComponentSelectionControl>
</Grid>
</DataTemplate>
</ContentControl.Resources>

View File

@ -117,6 +117,10 @@ namespace Filtration.UserControls
strIntBlockItem.Value = ((StrIntThemeComponent)strIntBlockItem.ThemeComponent).Value;
strIntBlockItem.SecondValue = ((StrIntThemeComponent)strIntBlockItem.ThemeComponent).SecondValue;
break;
case ThemeComponentType.CustomSound:
var stringBlockItem = BlockItem as StringBlockItem;
stringBlockItem.Value = ((StringThemeComponent)stringBlockItem.ThemeComponent).Value;
break;
}
}

View File

@ -63,6 +63,10 @@
<DataTemplate DataType="{x:Type themeEditor:StrIntThemeComponent}">
<!--TODO: How to show theese?-->
</DataTemplate>
<DataTemplate DataType="{x:Type themeEditor:StringThemeComponent}">
<!--TODO: How to show theese?-->
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>

View File

@ -83,7 +83,7 @@ namespace Filtration.ViewModels
var customSoundBlockItem = blockItem as CustomSoundBlockItem;
if (customSoundBlockItem != null)
{
if (_customSoundsAvailable.IndexOf(customSoundBlockItem.Value) < 0)
if (!string.IsNullOrWhiteSpace(customSoundBlockItem.Value) && _customSoundsAvailable.IndexOf(customSoundBlockItem.Value) < 0)
{
_customSoundsAvailable.Add(customSoundBlockItem.Value);
}
@ -454,6 +454,15 @@ namespace Filtration.ViewModels
{
IsDirty = true;
}
var customSoundBlockItem = sender as CustomSoundBlockItem;
if (customSoundBlockItem != null)
{
if (!string.IsNullOrWhiteSpace(customSoundBlockItem.Value) && _customSoundsAvailable.IndexOf(customSoundBlockItem.Value) < 0)
{
_customSoundsAvailable.Add(customSoundBlockItem.Value);
}
RaisePropertyChanged(nameof(CustomSoundsAvailable));
}
Block.IsEdited = true;
//if (sender is IAudioVisualBlockItem)
//{

View File

@ -116,6 +116,7 @@ namespace Filtration.ViewModels
AddBorderColorThemeComponentCommand = new RelayCommand(OnAddBorderColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
AddFontSizeThemeComponentCommand = new RelayCommand(OnAddFontSizeThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
AddAlertSoundThemeComponentCommand = new RelayCommand(OnAddAlertSoundThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
AddCustomSoundThemeComponentCommand = new RelayCommand(OnAddCustomSoundThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable && _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent != null);
ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand, () => ActiveDocumentIsScript);
@ -217,6 +218,7 @@ namespace Filtration.ViewModels
public RelayCommand AddBorderColorThemeComponentCommand { get; }
public RelayCommand AddFontSizeThemeComponentCommand { get; }
public RelayCommand AddAlertSoundThemeComponentCommand { get; }
public RelayCommand AddCustomSoundThemeComponentCommand { get; }
public RelayCommand DeleteThemeComponentCommand { get; }
public RelayCommand AddBlockCommand { get; }
@ -691,6 +693,11 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.AlertSound);
}
private void OnAddCustomSoundThemeComponentCommand()
{
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.CustomSound);
}
private void OnDeleteThemeComponentCommand()
{
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.DeleteThemeComponentCommand.Execute(

View File

@ -131,6 +131,7 @@
<fluent:Button SizeDefinition="Middle" Header="Add Border Color" Icon="{StaticResource AddIcon}" Command="{Binding AddBorderColorThemeComponentCommand}" />
<fluent:Button SizeDefinition="Middle" Header="Add Font Size" Icon="{StaticResource AddIcon}" Command="{Binding AddFontSizeThemeComponentCommand}" />
<fluent:Button SizeDefinition="Middle" Header="Add Alert Sound" Icon="{StaticResource AddIcon}" Command="{Binding AddAlertSoundThemeComponentCommand}" />
<fluent:Button SizeDefinition="Middle" Header="Add Custom Sound" Icon="{StaticResource AddIcon}" Command="{Binding AddCustomSoundThemeComponentCommand}" />
</fluent:RibbonGroupBox>
<fluent:RibbonGroupBox Header="Delete">
<fluent:Button Header="Delete Theme Component" Icon="{StaticResource ThemeComponentDeleteIcon}" LargeIcon="{StaticResource ThemeComponentDeleteIcon}" Command="{Binding DeleteThemeComponentCommand}" />