Added tons of UI-stuff (working configuration and visualization for all providers)

This commit is contained in:
Darth Affe 2017-08-12 19:19:25 +02:00
parent 111cc52e71
commit 427d42f1bb
25 changed files with 951 additions and 62 deletions

View File

@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -91,12 +91,12 @@ namespace KeyboardAudioVisualizer
//new ListLedGroup(device).Brush = new BeatBrush(AudioProcessor.Instance.PrimaryVisualizationProvider, new Color(255, 255, 255));
//{
// ILedGroup left = new RectangleLedGroup(new Rectangle(device.Location.X, device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
// ILedGroup right = new RectangleLedGroup(new Rectangle(device.Location.X + (device.Size.Width / 2.0), device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
// ILedGroup left1 = new RectangleLedGroup(new Rectangle(device.Location.X, device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
// ILedGroup right1 = new RectangleLedGroup(new Rectangle(device.Location.X + (device.Size.Width / 2.0), device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
// IGradient levelGradient = new LinearGradient(new GradientStop(0, new Color(0, 0, 255)), new GradientStop(1, new Color(255, 0, 0)));
// left.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Left, 0);
// right.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Right, 1);
// left1.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Left, 0);
// right1.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Right, 1);
//}
break;
@ -105,8 +105,14 @@ namespace KeyboardAudioVisualizer
ILedGroup right = new RectangleLedGroup(new Rectangle(device.Location.X + (device.Size.Width / 2.0), device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
IGradient mousematLevelGradient = new LinearGradient(new GradientStop(0, new Color(0, 0, 255)), new GradientStop(1, new Color(255, 0, 0)));
left.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 0);
right.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 1);
left.Brush = new LevelBarBrush(AudioProcessor.Instance.TertiaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 0);
right.Brush = new LevelBarBrush(AudioProcessor.Instance.TertiaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 1);
break;
case RGBDeviceType.Mouse:
case RGBDeviceType.Headset:
ILedGroup deviceGroup = new ListLedGroup(device);
deviceGroup.Brush = new BeatBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, new Color(255, 255, 255));
break;
}

View File

@ -8,12 +8,6 @@ namespace KeyboardAudioVisualizer.AudioProcessing
{
public class AudioProcessor : IDisposable
{
#region Constants
private const int MAXIMUM_UPDATE_RATE = 40; // We won't allow to change the FPS beyond this
#endregion
#region Properties & Fields
public static AudioProcessor Instance { get; private set; }
@ -24,6 +18,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing
public IVisualizationProvider PrimaryVisualizationProvider { get; private set; }
public IVisualizationProvider SecondaryVisualizationProvider { get; private set; }
public IVisualizationProvider TertiaryVisualizationProvider { get; private set; }
#endregion
@ -38,8 +33,10 @@ namespace KeyboardAudioVisualizer.AudioProcessing
public void Update()
{
_spectrumProvider.Update();
PrimaryVisualizationProvider.Update();
SecondaryVisualizationProvider.Update();
PrimaryVisualizationProvider?.Update();
SecondaryVisualizationProvider?.Update();
TertiaryVisualizationProvider?.Update();
}
public static void Initialize()
@ -67,8 +64,11 @@ namespace KeyboardAudioVisualizer.AudioProcessing
//PrimaryVisualizationProvider = new BeatVisualizationProvider(new BeatVisualizationProviderConfiguration(), _spectrumProvider);
PrimaryVisualizationProvider.Initialize();
SecondaryVisualizationProvider = new LevelVisualizationProvider(new LevelVisualizationProviderConfiguration(), _audioBuffer);
SecondaryVisualizationProvider = new BeatVisualizationProvider(new BeatVisualizationProviderConfiguration(), _spectrumProvider);
SecondaryVisualizationProvider.Initialize();
TertiaryVisualizationProvider = new LevelVisualizationProvider(new LevelVisualizationProviderConfiguration(), _audioBuffer);
TertiaryVisualizationProvider.Initialize();
}
public void Dispose() => _audioInput.Dispose();

View File

@ -12,14 +12,14 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
public class FrequencyBarsVisualizationProviderConfiguration : AbstractConfiguration
{
private ValueMode _valueMode = ValueMode.Max;
private ValueMode _valueMode = ValueMode.Sum;
public ValueMode ValueMode
{
get => _valueMode;
set => SetProperty(ref _valueMode, value);
}
private SpectrumMode _spectrumMode = SpectrumMode.Gamma;
private SpectrumMode _spectrumMode = SpectrumMode.Logarithmic;
public SpectrumMode SpectrumMode
{
get => _spectrumMode;
@ -40,15 +40,15 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
set => SetProperty(ref _smoothing, value);
}
private float _minFrequency = 60;
public float MinFrequency
private double _minFrequency = 60;
public double MinFrequency
{
get => _minFrequency;
set => SetProperty(ref _minFrequency, value);
}
private float _maxFrequency = 15000;
public float MaxFrequency
private double _maxFrequency = 15000;
public double MaxFrequency
{
get => _maxFrequency;
set => SetProperty(ref _maxFrequency, value);
@ -61,8 +61,8 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
set => SetProperty(ref _referenceLevel, value);
}
private float _emphasisePeaks = 0.5f;
public float EmphasisePeaks
private double _emphasisePeaks = 0.5f;
public double EmphasisePeaks
{
get => _emphasisePeaks;
set => SetProperty(ref _emphasisePeaks, value);
@ -147,8 +147,11 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
if (_configuration.EmphasisePeaks > 0.001)
binPower = Math.Pow(binPower, 1 + _configuration.EmphasisePeaks) * _emphasiseFactor;
VisualizationData[i] = (float)((VisualizationData[i] * _smoothingFactor) + (binPower * (1.0 - _smoothingFactor)));
if (float.IsNaN(VisualizationData[i])) VisualizationData[i] = 0;
if (i < VisualizationData.Length)
{
VisualizationData[i] = (float)((VisualizationData[i] * _smoothingFactor) + (binPower * (1.0 - _smoothingFactor)));
if (float.IsNaN(VisualizationData[i])) VisualizationData[i] = 0;
}
}
}
@ -157,11 +160,11 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
switch (_configuration.SpectrumMode)
{
case SpectrumMode.Gamma:
return _spectrumProvider.GetGammaSpectrum(_configuration.Bars, _configuration.Gamma, _configuration.MinFrequency, _configuration.MaxFrequency);
return _spectrumProvider.GetGammaSpectrum(_configuration.Bars, _configuration.Gamma, (float)_configuration.MinFrequency, (float)_configuration.MaxFrequency);
case SpectrumMode.Logarithmic:
return _spectrumProvider.GetLogarithmicSpectrum(_configuration.Bars, _configuration.MinFrequency, _configuration.MaxFrequency);
return _spectrumProvider.GetLogarithmicSpectrum(_configuration.Bars, (float)_configuration.MinFrequency, (float)_configuration.MaxFrequency);
case SpectrumMode.Linear:
return _spectrumProvider.GetLinearSpectrum(_configuration.Bars, _configuration.MinFrequency, _configuration.MaxFrequency);
return _spectrumProvider.GetLinearSpectrum(_configuration.Bars, (float)_configuration.MinFrequency, (float)_configuration.MaxFrequency);
default:
return null;
}

View File

@ -2,6 +2,7 @@
using System.Linq;
using KeyboardAudioVisualizer.AudioCapture;
using KeyboardAudioVisualizer.Configuration;
using KeyboardAudioVisualizer.Helper;
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
{
@ -89,7 +90,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
private void RecalculateConfigValues(string changedPropertyName)
{
if ((changedPropertyName == null) || (changedPropertyName == nameof(LevelVisualizationProviderConfiguration.Smoothing)))
_smoothingFactor = Math.Log10(_configuration.Smoothing);
_smoothingFactor = Math.Log10(MathHelper.Clamp(_configuration.Smoothing, 0.001, 9.5));
if ((changedPropertyName == null) || (changedPropertyName == nameof(LevelVisualizationProviderConfiguration.Scale))
|| (changedPropertyName == nameof(LevelVisualizationProviderConfiguration.ConversionMode)))

View File

@ -1,5 +1,7 @@
namespace KeyboardAudioVisualizer.Configuration
using System.ComponentModel;
namespace KeyboardAudioVisualizer.Configuration
{
// DarthAffe 05.08.2017: Marker interface
public interface IConfiguration { }
public interface IConfiguration : INotifyPropertyChanged { }
}

View File

@ -77,6 +77,12 @@ namespace KeyboardAudioVisualizer.Controls
public static void SetRowSpan(DependencyObject element, int value) => element.SetValue(RowSpanProperty, value);
public static int GetRowSpan(DependencyObject element) => (int)element.GetValue(RowSpanProperty);
public static readonly DependencyProperty FillProperty = DependencyProperty.RegisterAttached("Fill", typeof(bool), typeof(Formular),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
public static void SetFill(DependencyObject element, bool value) => element.SetValue(FillProperty, value);
public static bool GetFill(DependencyObject element) => (bool)element.GetValue(FillProperty);
// ReSharper restore InconsistentNaming
#endregion
@ -91,7 +97,7 @@ namespace KeyboardAudioVisualizer.Controls
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
layout.AddElement(child);
layout.AddElement(child, 0);
}
return new Size(layout.Width, layout.Height);
@ -104,9 +110,9 @@ namespace KeyboardAudioVisualizer.Controls
FormularLayout layout = new FormularLayout(RowHeight, LabelWidth, ElementSpacing, RowSpacing);
foreach (UIElement child in InternalChildren)
child.Arrange(layout.AddElement(child));
child.Arrange(layout.AddElement(child, finalSize.Width));
return new Size(layout.Width, layout.Height);
return new Size(finalSize.Width, layout.Height);
}
#endregion
@ -146,7 +152,7 @@ namespace KeyboardAudioVisualizer.Controls
#region Methods
public Rect AddElement(UIElement element)
public Rect AddElement(UIElement element, double targetWidth)
{
bool isLabel = GetIsLabel(element);
int lineBreaks = GetLineBreaks(element);
@ -177,9 +183,13 @@ namespace KeyboardAudioVisualizer.Controls
if (element is FrameworkElement fe)
fe.MaxHeight = height;
Rect rect = new Rect(new Point(_currentRowWidth, (_rows * _rowHeight) + (_rows * _rowSpacing)), new Size(elementWidth, height));
double width = elementWidth;
if ((targetWidth >= 1) && GetFill(element))
width = targetWidth - _currentRowWidth;
_currentRowWidth += elementWidth + _elementSpacing;
Rect rect = new Rect(new Point(_currentRowWidth, (_rows * _rowHeight) + (_rows * _rowSpacing)), new Size(width, height));
_currentRowWidth += width + _elementSpacing;
return rect;
}

View File

@ -0,0 +1,18 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace KeyboardAudioVisualizer.Converter
{
[ValueConversion(typeof(object), typeof(bool))]
public class EqualsToBoolConverter : IValueConverter
{
#region Methods
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => Equals(value, parameter);
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
#endregion
}
}

View File

@ -73,8 +73,8 @@
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Numerics" />
<Reference Include="System.ValueTuple, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
@ -129,6 +129,7 @@
<Compile Include="Configuration\IConfiguration.cs" />
<Compile Include="Controls\Formular.cs" />
<Compile Include="Controls\ImageButton.cs" />
<Compile Include="Converter\EqualsToBoolConverter.cs" />
<Compile Include="Helper\ActionCommand.cs" />
<Compile Include="Helper\ExceptionExtension.cs" />
<Compile Include="Helper\FrequencyHelper.cs" />
@ -140,6 +141,9 @@
<DependentUpon>ConfigurationWindow.xaml</DependentUpon>
</Compile>
<Compile Include="UI\ConfigurationViewModel.cs" />
<Compile Include="UI\Visualization\BeatVisualizer.cs" />
<Compile Include="UI\Visualization\FrequencyBarsVisualizer.cs" />
<Compile Include="UI\Visualization\LevelVisualizer.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Helper\SerializationHelper.cs" />
@ -191,6 +195,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\ComboBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\ImageButton.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@ -219,19 +227,37 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UI\Configuration\BeatConfiguration.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Configuration\LevelConfiguration.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Configuration\FrequencyBarsConfiguration.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Visualization\BeatVisualization.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Visualization\FrequencyBarsVisualization.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Visualization\LevelVisualization.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\background.png" />
<Resource Include="Resources\close.png" />
<Resource Include="Resources\minimize.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="UI\Visualization\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\RGB.NET.Devices.Corsair.1.0.0\build\net45\RGB.NET.Devices.Corsair.targets" Condition="Exists('..\packages\RGB.NET.Devices.Corsair.1.0.0\build\net45\RGB.NET.Devices.Corsair.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@ -2,7 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:KeyboardAudioVisualizer.UI"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls">
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
xmlns:converter="clr-namespace:KeyboardAudioVisualizer.Converter">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/BlurredDecorationWindow.xaml" />
@ -10,14 +11,18 @@
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Formular.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/GroupBox.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/ToolTip.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/ComboBox.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<converter:EqualsToBoolConverter x:Key="EqualsToBoolConverter" />
<Style TargetType="{x:Type controls:BlurredDecorationWindow}" BasedOn="{StaticResource StyleBlurredDecorationWindow}" />
<Style TargetType="{x:Type ui:ConfigurationWindow}" BasedOn="{StaticResource StyleBlurredDecorationWindow}" />
<Style TargetType="{x:Type controls:ImageButton}" BasedOn="{StaticResource StyleImageButton}" />
<Style TargetType="{x:Type controls:Formular}" BasedOn="{StaticResource StyleFormular}" />
<Style TargetType="GroupBox" BasedOn="{StaticResource StyleGroupBoxBox}" />
<Style TargetType="ToolTip" BasedOn="{StaticResource StyleToolTip}" />
<Style TargetType="ComboBox" BasedOn="{StaticResource StyleComboBox}" />
</styles:CachedResourceDictionary>

View File

@ -0,0 +1,144 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<Style x:Key="StyleComboBoxItem"
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type ComboBoxItem}">
<Setter Property="Foreground" Value="{StaticResource BrushComboBoxForeground}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushComboBoxHover}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxToggleButton"
TargetType="{x:Type ToggleButton}">
<Border x:Name="Border"
CornerRadius="0"
Background="{StaticResource BrushComboBoxBackground}"
BorderBrush="{StaticResource BrushComboBoxBorder}"
BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0"
CornerRadius="0"
Margin="1"
Background="Transparent"
BorderBrush="{StaticResource BrushComboBoxBorder}"
BorderThickness="0,0,1,0" />
<Path x:Name="Arrow"
Grid.Column="1"
Fill="{StaticResource BrushComboBoxForeground}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushComboBoxHover}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox"
TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost"
Focusable="False"
Background="{TemplateBinding Background}" />
</ControlTemplate>
<Style x:Key="StyleComboBox"
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type ComboBox}" >
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Foreground" Value="{StaticResource BrushComboBoxForeground}"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource StyleComboBoxItem}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Focusable="False"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="6,3,26,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<Popup Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder"
Background="{StaticResource BrushComboBoxBackgroundPopup}"
BorderThickness="1"
BorderBrush="{StaticResource BrushComboBoxBorder}"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</styles:CachedResourceDictionary>

View File

@ -11,9 +11,10 @@
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type controls:Formular}">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="LabelWidth" Value="160" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="LabelWidth" Value="112" />
<Setter Property="ElementSpacing" Value="8" />
<Setter Property="RowSpacing" Value="8" />
</Style>
<Style x:Key="StyleLabelFormular"

View File

@ -16,6 +16,7 @@
<Setter Property="Background" Value="{StaticResource BrushBoxBackground}" />
<Setter Property="BorderBrush" Value="{StaticResource BrushBoxBorder}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Padding" Value="6,8" />
<Setter Property="Template">
<Setter.Value>
@ -23,7 +24,7 @@
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter Margin="6,4" />
<ContentPresenter Margin="{TemplateBinding Padding}" />
</Border>
</ControlTemplate>
</Setter.Value>

View File

@ -4,6 +4,8 @@
xmlns:presentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options">
<!-- ### Colors ### -->
<Color x:Key="ColorGainsboro">#FFDCDCDC</Color>
<Color x:Key="ColorBuckinghamGray">#FF2A2A2A</Color>
<Color x:Key="ColorBuckinghamGrayTransparent">#B82A2A2A</Color>
<Color x:Key="ColorJetBlack">#111111</Color>
<Color x:Key="ColorJetBlackTransparent">#B8111111</Color>
<Color x:Key="ColorJetBlackSuperTransparent">#60111111</Color>
@ -27,6 +29,12 @@
<SolidColorBrush x:Key="BrushTooltipBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
<SolidColorBrush x:Key="BrushTooltipBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
<SolidColorBrush x:Key="BrushComboBoxForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
<SolidColorBrush x:Key="BrushComboBoxBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorBuckinghamGrayTransparent}" />
<SolidColorBrush x:Key="BrushComboBoxBackgroundPopup" presentationOptions:Freeze="True" Color="{StaticResource ColorBuckinghamGray}" />
<SolidColorBrush x:Key="BrushComboBoxBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
<SolidColorBrush x:Key="BrushComboBoxHover" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
<!-- Navigation -->
<SolidColorBrush x:Key="BrushNavigationItem" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
<SolidColorBrush x:Key="BrushNavigationItemBlur" presentationOptions:Freeze="True" Color="{StaticResource ColorBananaYellow}" />
@ -39,5 +47,5 @@
<!-- ### Fonts ### -->
<sys:Double x:Key="FontSizeDefault">14</sys:Double>
<sys:Double x:Key="FontSizeTooltip">14</sys:Double>
<sys:Double x:Key="FontSizeNavigation">28</sys:Double>
<sys:Double x:Key="FontSizeNavigation">22</sys:Double>
</ResourceDictionary>

View File

@ -0,0 +1,29 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type visualizationProvider:BeatVisualizationProviderConfiguration}">
<Grid>
<Grid.Resources>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</Grid.Resources>
<controls:Formular LabelWidth="240">
<Label controls:Formular.IsLabel="True" Content="No configuration available ..." />
</controls:Formular>
</Grid>
</DataTemplate>
</styles:CachedResourceDictionary>

View File

@ -1,20 +1,33 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationPRovider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type visualizationPRovider:FrequencyBarsVisualizationProviderConfiguration}">
<DataTemplate DataType="{x:Type visualizationProvider:FrequencyBarsVisualizationProviderConfiguration}">
<Grid>
<Grid.Resources>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
<ObjectDataProvider x:Key="SpectrumModes" MethodName="GetValues" ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="visualizationProvider:SpectrumMode"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ValueModes" MethodName="GetValues" ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="visualizationProvider:ValueMode"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Grid.Resources>
<Grid.ColumnDefinitions>
@ -26,12 +39,48 @@
</Grid.ColumnDefinitions>
<controls:Formular Grid.Column="0">
</controls:Formular>
<Label controls:Formular.IsLabel="True" Content="Spectrum:" />
<ComboBox controls:Formular.Fill="True"
ItemsSource="{Binding Source={StaticResource SpectrumModes}}"
SelectedItem="{Binding SpectrumMode}"/>
<controls:Formular Grid.Column="1">
<Label controls:Formular.IsLabel="True" Content="Value:" />
<ComboBox controls:Formular.Fill="True"
ItemsSource="{Binding Source={StaticResource ValueModes}}"
SelectedItem="{Binding ValueMode}"/>
<Label controls:Formular.IsLabel="True" Content="Bars:" />
<Slider controls:Formular.Fill="True" Minimum="1" Maximum="96" IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight"
Value="{Binding Bars}" />
</controls:Formular>
<controls:Formular Grid.Column="2">
<Label controls:Formular.IsLabel="True" Content="Min Freq.:" />
<Slider controls:Formular.Fill="True" Minimum="0" Maximum="22100" IsSnapToTickEnabled="True" TickFrequency="10" TickPlacement="None"
Value="{Binding MinFrequency}" />
<Label controls:Formular.IsLabel="True" Content="Max Freq.:" />
<Slider controls:Formular.Fill="True" Minimum="0" Maximum="22100" IsSnapToTickEnabled="True" TickFrequency="10" TickPlacement="None"
Value="{Binding MaxFrequency}" />
<Label controls:Formular.IsLabel="True" Content="Gamma:" />
<Slider controls:Formular.Fill="True" Minimum="1" Maximum="6" IsSnapToTickEnabled="True" TickFrequency="0.25" TickPlacement="BottomRight"
IsEnabled="{Binding SpectrumMode, Converter={StaticResource EqualsToBoolConverter}, ConverterParameter={x:Static visualizationProvider:SpectrumMode.Gamma}}"
Value="{Binding Gamma}" />
</controls:Formular>
<controls:Formular Grid.Column="4">
<Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Reference:" />
<Slider controls:Formular.Fill="True" Minimum="1" Maximum="240" IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="None"
Value="{Binding ReferenceLevel}" />
<Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Smoothing:" />
<Slider controls:Formular.Fill="True" Minimum="1" Maximum="10" IsSnapToTickEnabled="True" TickFrequency="0.5" TickPlacement="BottomRight"
Value="{Binding Smoothing}" />
<Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Emphasize:" />
<Slider controls:Formular.Fill="True" Minimum="0" Maximum="2" IsSnapToTickEnabled="True" TickFrequency="0.05" TickPlacement="BottomRight"
Value="{Binding EmphasisePeaks}" />
</controls:Formular>
</Grid>
</DataTemplate>

View File

@ -0,0 +1,57 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type visualizationProvider:LevelVisualizationProviderConfiguration}">
<Grid>
<Grid.Resources>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
<ObjectDataProvider x:Key="ConversionModes" MethodName="GetValues" ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="visualizationProvider:ConversionMode"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<controls:Formular Grid.Column="0">
<Label controls:Formular.IsLabel="True" Content="Calculation:" />
<ComboBox controls:Formular.Fill="True"
ItemsSource="{Binding Source={StaticResource ConversionModes}}"
SelectedItem="{Binding ConversionMode}"/>
</controls:Formular>
<controls:Formular Grid.Column="2">
<Label controls:Formular.IsLabel="True" Content="Scale:" />
<Slider controls:Formular.Fill="True" Minimum="1" Maximum="10" IsSnapToTickEnabled="True" TickFrequency="0.5" TickPlacement="BottomRight"
Value="{Binding Scale}" />
</controls:Formular>
<controls:Formular Grid.Column="4">
<Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Smoothing:" />
<Slider controls:Formular.Fill="True" Minimum="1" Maximum="10" IsSnapToTickEnabled="True" TickFrequency="0.5" TickPlacement="BottomRight"
Value="{Binding Smoothing}" />
</controls:Formular>
</Grid>
</DataTemplate>
</styles:CachedResourceDictionary>

View File

@ -19,6 +19,11 @@
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Navigation.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Configuration/FrequencyBarsConfiguration.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Visualization/FrequencyBarsVisualization.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Configuration/LevelConfiguration.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Visualization/LevelVisualization.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Configuration/BeatConfiguration.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Visualization/BeatVisualization.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
</styles:CachedResourceDictionary>
</controls:BlurredDecorationWindow.Resources>
@ -28,9 +33,26 @@
</controls:BlurredDecorationWindow.DataContext>
<TabControl Style="{StaticResource StyleTabControlNavigation}">
<TabItem Header="Primary">
<TabItem Header="Keyboard">
<DockPanel>
<GroupBox DockPanel.Dock="Top">
<controls:Formular>
<controls:Formular.Resources>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</controls:Formular.Resources>
<Label controls:Formular.IsLabel="True" Content="Visualization: " />
<ComboBox controls:Formular.Fill="True" SelectedIndex="0">
<ComboBox.Items>
<ComboBoxItem>Frequency Bars</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
</controls:Formular>
</GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=PrimaryVisualizationProvider.Configuration}" />
</GroupBox>
@ -40,18 +62,64 @@
</DockPanel>
</TabItem>
<TabItem Header="Secondary">
<DockPanel>
<TabItem Header="Mouse/Headset">
<DockPanel LastChildFill="False">
<GroupBox DockPanel.Dock="Top">
<controls:Formular>
<controls:Formular.Resources>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</controls:Formular.Resources>
<Label controls:Formular.IsLabel="True" Content="Visualization: " />
<ComboBox controls:Formular.Fill="True" SelectedIndex="0">
<ComboBox.Items>
<ComboBoxItem>Beat-Detection</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
</controls:Formular>
</GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=SecondaryVisualizationProvider.Configuration}" />
</GroupBox>
<GroupBox Margin="0,8,0,0">
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=SecondaryVisualizationProvider}" />
</GroupBox>
</DockPanel>
</TabItem>
<TabItem Header="Lightbar/Mousemate">
<DockPanel LastChildFill="False">
<GroupBox DockPanel.Dock="Top">
<controls:Formular>
<controls:Formular.Resources>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</controls:Formular.Resources>
<Label controls:Formular.IsLabel="True" Content="Visualization: " />
<ComboBox controls:Formular.Fill="True" SelectedIndex="0">
<ComboBox.Items>
<ComboBoxItem>Level</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
</controls:Formular>
</GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=TertiaryVisualizationProvider.Configuration}" />
</GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=TertiaryVisualizationProvider}" />
</GroupBox>
</DockPanel>
</TabItem>
<TabItem Header="Settings">
<GroupBox VerticalAlignment="Top">
<StackPanel Orientation="Vertical">
@ -65,11 +133,11 @@
<Label controls:Formular.IsLabel="True" Content="Version:" />
<TextBlock Text="{Binding Version}" />
<Label controls:Formular.LineBreaks="1" controls:Formular.IsLabel="True" Content="Connected Devices:" />
<Label controls:Formular.LineBreaks="1" controls:Formular.IsLabel="True" Content="Devices:" />
</controls:Formular>
<!-- TODO DarthAffe 05.08.2017: Fix the formular to support that use-case -->
<ItemsControl VerticalAlignment="Top" HorizontalAlignment="Left" Margin="168,-22,0,0" ItemsSource="{Binding Source={x:Static core:RGBSurface.Instance}, Path=Devices}">
<ItemsControl VerticalAlignment="Top" HorizontalAlignment="Left" Margin="120,-22,0,0" ItemsSource="{Binding Source={x:Static core:RGBSurface.Instance}, Path=Devices}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource StyleTextBlockFormular}">

View File

@ -0,0 +1,32 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<Style x:Key="StyleBeatVisualizer"
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type visualization:BeatVisualizer}">
<Setter Property="Height" Value="64" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type visualization:BeatVisualizer}">
<Border Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Brush}"
Opacity="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BeatValue}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type visualizationProvider:BeatVisualizationProvider}">
<visualization:BeatVisualizer Style="{StaticResource StyleBeatVisualizer}" VisualizationProvider="{Binding}" />
</DataTemplate>
</styles:CachedResourceDictionary>

View File

@ -0,0 +1,80 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
using RGB.NET.Core;
using Color = System.Windows.Media.Color;
using Point = System.Windows.Point;
namespace KeyboardAudioVisualizer.UI.Visualization
{
public class BeatVisualizer : Control
{
#region DependencyProperties
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty VisualizationProviderProperty = DependencyProperty.Register(
"VisualizationProvider", typeof(IVisualizationProvider), typeof(BeatVisualizer), new PropertyMetadata(default(IVisualizationProvider)));
public IVisualizationProvider VisualizationProvider
{
get => (IVisualizationProvider)GetValue(VisualizationProviderProperty);
set => SetValue(VisualizationProviderProperty, value);
}
public static readonly DependencyProperty BrushProperty = DependencyProperty.Register(
"Brush", typeof(Brush), typeof(BeatVisualizer), new PropertyMetadata(default(Brush)));
public Brush Brush
{
get => (Brush)GetValue(BrushProperty);
set => SetValue(BrushProperty, value);
}
public static readonly DependencyProperty BeatValueProperty = DependencyProperty.Register(
"BeatValue", typeof(float), typeof(BeatVisualizer), new PropertyMetadata(default(float)));
public float BeatValue
{
get => (float)GetValue(BeatValueProperty);
set => SetValue(BeatValueProperty, value);
}
// ReSharper restore InconsistentNaming
#endregion
#region Constructors
public BeatVisualizer()
{
RGBSurface.Instance.Updated += args => Dispatcher.BeginInvoke(new Action(Update), DispatcherPriority.Normal);
//TODO DarthAffe 12.08.2017: Create brush from config
Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
}
#endregion
#region Methods
private void Update()
{
IVisualizationProvider visualizationProvider = VisualizationProvider;
if ((visualizationProvider == null) || (Visibility != Visibility.Visible)) return;
if (visualizationProvider.VisualizationData[0] > 0.9)
BeatValue = 1f;
else if (BeatValue > 0.01f)
{
float newValue = BeatValue * 0.625f;
if (newValue > 0.01f)
BeatValue = newValue;
else BeatValue = 0;
}
}
#endregion
}
}

View File

@ -0,0 +1,32 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<Style x:Key="StyleFrequencyBarsVisualizer"
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type visualization:FrequencyBarsVisualizer}">
<Setter Property="SnapsToDevicePixels" Value="False" />
<Setter Property="UseLayoutRounding" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type visualization:FrequencyBarsVisualizer}">
<StackPanel x:Name="PART_BarsPanel" Orientation="Horizontal" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type visualizationProvider:FrequencyBarsVisualizationProvider}">
<visualization:FrequencyBarsVisualizer Style="{StaticResource StyleFrequencyBarsVisualizer}" VisualizationProvider="{Binding}" />
</DataTemplate>
</styles:CachedResourceDictionary>

View File

@ -0,0 +1,142 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
using RGB.NET.Brushes.Gradients;
using RGB.NET.Core;
using Color = System.Windows.Media.Color;
using Rectangle = System.Windows.Shapes.Rectangle;
namespace KeyboardAudioVisualizer.UI.Visualization
{
[TemplatePart(Name = "PART_BarsPanel", Type = typeof(Panel))]
public class FrequencyBarsVisualizer : Control
{
#region DependencyProperties
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty VisualizationProviderProperty = DependencyProperty.Register(
"VisualizationProvider", typeof(IVisualizationProvider), typeof(FrequencyBarsVisualizer),
new PropertyMetadata(default(IVisualizationProvider), VisualizationProviderChanged));
public IVisualizationProvider VisualizationProvider
{
get => (IVisualizationProvider)GetValue(VisualizationProviderProperty);
set => SetValue(VisualizationProviderProperty, value);
}
// ReSharper restore InconsistentNaming
#endregion
#region Properties & Fields
private IGradient _gradient;
private Panel _panel;
private Rectangle[] _bars = new Rectangle[0];
#endregion
#region Constructors
public FrequencyBarsVisualizer()
{
RGBSurface.Instance.Updated += args => Dispatcher.BeginInvoke(new Action(Update), DispatcherPriority.Normal);
SizeChanged += (sender, args) => UpdateSizes();
//TODO DarthAffe 12.08.2017: Get gradient from config
_gradient = new RainbowGradient(300, -14);
}
#endregion
#region Methods
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_panel = GetTemplateChild("PART_BarsPanel") as Panel;
InitializeBars();
}
private static void VisualizationProviderChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
FrequencyBarsVisualizer visualizer = dependencyObject as FrequencyBarsVisualizer;
if (visualizer == null) return;
void ConfigurationOnPropertyChanged(object sender, PropertyChangedEventArgs args) => visualizer.ConfigurationChanged(args.PropertyName);
if (dependencyPropertyChangedEventArgs.OldValue is IVisualizationProvider oldVisualizationProvider)
oldVisualizationProvider.Configuration.PropertyChanged -= ConfigurationOnPropertyChanged;
if (dependencyPropertyChangedEventArgs.NewValue is IVisualizationProvider newVisualizationProvider)
newVisualizationProvider.Configuration.PropertyChanged += ConfigurationOnPropertyChanged;
}
private void ConfigurationChanged(string changedPropertyName)
{
if ((changedPropertyName == null) || (changedPropertyName == nameof(FrequencyBarsVisualizationProviderConfiguration.Bars)))
InitializeBars();
}
private void InitializeBars()
{
if (_panel == null) return;
_panel.Children.Clear();
_bars = new Rectangle[((FrequencyBarsVisualizationProviderConfiguration)VisualizationProvider.Configuration).Bars];
for (int i = 0; i < _bars.Length; i++)
{
_bars[i] = new Rectangle { VerticalAlignment = VerticalAlignment.Bottom, Width = 0 };
_panel.Children.Add(_bars[i]);
}
UpdateSizes();
UpdateColors();
}
private void UpdateSizes()
{
if (_bars.Length == 0) return;
double barSpacing = ActualWidth / _bars.Length;
double barWidth = (barSpacing * 3.0) / 4.0;
double margin = barSpacing - barWidth;
for (int i = 0; i < _bars.Length; i++)
{
_bars[i].Width = barWidth;
_bars[i].Margin = new Thickness(margin / 2, 0, margin / 2, 0);
}
}
private void UpdateColors()
{
for (int i = 0; i < _bars.Length; i++)
{
RGB.NET.Core.Color color = _gradient.GetColor((double)i / _bars.Length);
_bars[i].Fill = new SolidColorBrush(Color.FromRgb(color.R, color.G, color.B));
}
}
private void Update()
{
IVisualizationProvider visualizationProvider = VisualizationProvider;
if ((visualizationProvider == null) || (Visibility != Visibility.Visible)) return;
int count = Math.Min(_bars.Length, visualizationProvider.VisualizationData.Length);
for (int i = 0; i < count; i++)
{
_bars[i].Height = (float)((_bars[i].Height * 0.5) + ((ActualHeight * visualizationProvider.VisualizationData[i]) * (1.0 - 0.5)));
if (double.IsNaN(_bars[i].Height)) _bars[i].Height = 0;
}
}
#endregion
}
}

View File

@ -0,0 +1,70 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization">
<styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries>
<Style x:Key="StyleLevelVisualizer"
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type visualization:LevelVisualizer}">
<Setter Property="Height" Value="64" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type visualization:LevelVisualizer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderThickness="0,0,1,0" BorderBrush="White">
<Border x:Name="BrdLeft" Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BrushLeft}">
<Border.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<Border Width="{Binding ElementName=BrdLeft, Path=ActualWidth}"
Height="{Binding ElementName=BrdLeft, Path=ActualHeight}"
Background="Transparent">
<Rectangle HorizontalAlignment="Right" Fill="Black"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SizeLeft}" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
</Border>
</Border>
<Border Grid.Column="1" BorderThickness="1,0,0,0" BorderBrush="White">
<Border x:Name="BrdRight" Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BrushRight}">
<Border.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<Border Width="{Binding ElementName=BrdRight, Path=ActualWidth}"
Height="{Binding ElementName=BrdRight, Path=ActualHeight}"
Background="Transparent">
<Rectangle HorizontalAlignment="Left" Fill="Black"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SizeRight}" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
</Border>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type visualizationProvider:LevelVisualizationProvider}">
<visualization:LevelVisualizer Style="{StaticResource StyleLevelVisualizer}" VisualizationProvider="{Binding}" />
</DataTemplate>
</styles:CachedResourceDictionary>

View File

@ -0,0 +1,97 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
using RGB.NET.Core;
using Color = System.Windows.Media.Color;
using Point = System.Windows.Point;
namespace KeyboardAudioVisualizer.UI.Visualization
{
public class LevelVisualizer : Control
{
#region DependencyProperties
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty VisualizationProviderProperty = DependencyProperty.Register(
"VisualizationProvider", typeof(IVisualizationProvider), typeof(LevelVisualizer), new PropertyMetadata(default(IVisualizationProvider)));
public IVisualizationProvider VisualizationProvider
{
get => (IVisualizationProvider)GetValue(VisualizationProviderProperty);
set => SetValue(VisualizationProviderProperty, value);
}
public static readonly DependencyProperty BrushLeftProperty = DependencyProperty.Register(
"BrushLeft", typeof(Brush), typeof(LevelVisualizer), new PropertyMetadata(default(Brush)));
public Brush BrushLeft
{
get => (Brush)GetValue(BrushLeftProperty);
set => SetValue(BrushLeftProperty, value);
}
public static readonly DependencyProperty BrushRightProperty = DependencyProperty.Register(
"BrushRight", typeof(Brush), typeof(LevelVisualizer), new PropertyMetadata(default(Brush)));
public Brush BrushRight
{
get => (Brush)GetValue(BrushRightProperty);
set => SetValue(BrushRightProperty, value);
}
public static readonly DependencyProperty SizeLeftProperty = DependencyProperty.Register(
"SizeLeft", typeof(int), typeof(LevelVisualizer), new PropertyMetadata(default(int)));
public int SizeLeft
{
get => (int)GetValue(SizeLeftProperty);
set => SetValue(SizeLeftProperty, value);
}
public static readonly DependencyProperty SizeRightProperty = DependencyProperty.Register(
"SizeRight", typeof(int), typeof(LevelVisualizer), new PropertyMetadata(default(int)));
public int SizeRight
{
get => (int)GetValue(SizeRightProperty);
set => SetValue(SizeRightProperty, value);
}
// ReSharper restore InconsistentNaming
#endregion
#region Constructors
public LevelVisualizer()
{
RGBSurface.Instance.Updated += args => Dispatcher.BeginInvoke(new Action(Update), DispatcherPriority.Normal);
//TODO DarthAffe 12.08.2017: Create brush from config
BrushLeft = new LinearGradientBrush(Color.FromRgb(255, 0, 0), Color.FromRgb(0, 0, 255), new Point(0, 0.5), new Point(1, 0.5));
BrushRight = new LinearGradientBrush(Color.FromRgb(0, 0, 255), Color.FromRgb(255, 0, 0), new Point(0, 0.5), new Point(1, 0.5));
}
#endregion
#region Methods
private void Update()
{
IVisualizationProvider visualizationProvider = VisualizationProvider;
if ((visualizationProvider == null) || (Visibility != Visibility.Visible)) return;
int horizontalSizeLeft = (int)(visualizationProvider.VisualizationData[0] * (ActualWidth / 2));
if (Math.Abs(SizeLeft - horizontalSizeLeft) > 1)
SizeLeft = horizontalSizeLeft;
int horizontalSizeRight = (int)(visualizationProvider.VisualizationData[1] * (ActualWidth / 2));
if (Math.Abs(SizeRight - horizontalSizeRight) > 1)
SizeRight = horizontalSizeRight;
}
#endregion
}
}

View File

@ -9,5 +9,5 @@
<package id="RGB.NET.Devices.Corsair" version="1.0.0" targetFramework="net461" />
<package id="RGB.NET.Devices.Logitech" version="1.0.0" targetFramework="net461" />
<package id="RGB.NET.Groups" version="1.0.0" targetFramework="net461" />
<package id="System.ValueTuple" version="4.3.1" targetFramework="net461" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net461" />
</packages>