Added value-indicator for sliders

This commit is contained in:
Darth Affe 2017-09-29 16:56:00 +02:00
parent c72e8497ab
commit e35e70d0bb
6 changed files with 352 additions and 117 deletions

View File

@ -0,0 +1,111 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace KeyboardAudioVisualizer.Attached
{
public static class SliderValue
{
#region Properties & Fields
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty UnitProperty = DependencyProperty.RegisterAttached(
"Unit", typeof(string), typeof(SliderValue), new PropertyMetadata(default(string)));
public static void SetUnit(DependencyObject element, string value) => element.SetValue(UnitProperty, value);
public static string GetUnit(DependencyObject element) => (string)element.GetValue(UnitProperty);
public static readonly DependencyProperty IsShownProperty = DependencyProperty.RegisterAttached(
"IsShown", typeof(bool), typeof(SliderValue), new PropertyMetadata(default(bool), IsShownChanged));
public static void SetIsShown(DependencyObject element, bool value) => element.SetValue(IsShownProperty, value);
public static bool GetIsShown(DependencyObject element) => (bool)element.GetValue(IsShownProperty);
public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.RegisterAttached(
"BorderBrush", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
public static void SetBorderBrush(DependencyObject element, Brush value) => element.SetValue(BorderBrushProperty, value);
public static Brush GetBorderBrush(DependencyObject element) => (Brush)element.GetValue(BorderBrushProperty);
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.RegisterAttached(
"Background", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
public static void SetBackground(DependencyObject element, Brush value) => element.SetValue(BackgroundProperty, value);
public static Brush GetBackground(DependencyObject element) => (Brush)element.GetValue(BackgroundProperty);
public static readonly DependencyProperty ForegroundProperty = DependencyProperty.RegisterAttached(
"Foreground", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
public static void SetForeground(DependencyObject element, Brush value) => element.SetValue(ForegroundProperty, value);
public static Brush GetForeground(DependencyObject element) => (Brush)element.GetValue(ForegroundProperty);
public static readonly DependencyProperty FontProperty = DependencyProperty.RegisterAttached(
"Font", typeof(FontFamily), typeof(SliderValue), new PropertyMetadata(default(FontFamily)));
public static void SetFont(DependencyObject element, FontFamily value) => element.SetValue(FontProperty, value);
public static FontFamily GetFont(DependencyObject element) => (FontFamily)element.GetValue(FontProperty);
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.RegisterAttached(
"FontSize", typeof(double), typeof(SliderValue), new PropertyMetadata(default(double)));
public static void SetFontSize(DependencyObject element, double value) => element.SetValue(FontSizeProperty, value);
public static double GetFontSize(DependencyObject element) => (double)element.GetValue(FontSizeProperty);
// ReSharper enable InconsistentNaming
#endregion
#region Methods
private static void IsShownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (!(dependencyObject is Slider slider)) return;
if (dependencyPropertyChangedEventArgs.NewValue as bool? == true)
{
slider.MouseEnter += SliderOnMouseEnter;
slider.MouseLeave += SliderOnMouseLeave;
}
else
{
slider.MouseEnter -= SliderOnMouseEnter;
slider.MouseLeave -= SliderOnMouseLeave;
RemoveAdorner(slider);
}
}
private static void SliderOnMouseEnter(object sender, MouseEventArgs mouseEventArgs)
{
if (!(sender is Slider slider)) return;
AdornerLayer.GetAdornerLayer(slider)?.Add(new SliderValueAdorner(slider, GetUnit(slider))
{
BorderBrush = GetBorderBrush(slider),
Background = GetBackground(slider),
Foreground = GetForeground(slider),
Font = GetFont(slider),
FontSize = GetFontSize(slider)
});
}
private static void SliderOnMouseLeave(object sender, MouseEventArgs mouseEventArgs)
{
if (!(sender is Slider slider)) return;
RemoveAdorner(slider);
}
private static void RemoveAdorner(Slider slider)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(slider);
Adorner adorner = adornerLayer?.GetAdorners(slider)?.FirstOrDefault(x => x is SliderValueAdorner);
if (adorner != null)
{
adornerLayer.Remove(adorner);
(adorner as SliderValueAdorner)?.Cleanup();
}
}
#endregion
}
}

View File

@ -0,0 +1,99 @@
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using Point = System.Windows.Point;
namespace KeyboardAudioVisualizer.Attached
{
public class SliderValueAdorner : System.Windows.Documents.Adorner
{
#region Properties & Fields
private readonly string _unit;
private readonly Slider _slider;
private readonly Thumb _thumb;
private readonly RepeatButton _decreaseRepeatButton;
public Brush BorderBrush { get; set; } = Brushes.Black;
public Brush Background { get; set; } = Brushes.Black;
public Brush Foreground { get; set; } = Brushes.White;
public FontFamily Font { get; set; } = new FontFamily("Verdana");
public double FontSize { get; set; } = 14;
#endregion
#region Constructors
public SliderValueAdorner(UIElement adornedElement, string unit)
: base(adornedElement)
{
this._unit = unit;
_slider = (Slider)adornedElement;
Track track = (Track)_slider.Template.FindName("PART_Track", _slider);
_thumb = track.Thumb;
_decreaseRepeatButton = track.DecreaseRepeatButton;
_decreaseRepeatButton.SizeChanged += OnButtonSizeChanged;
}
#endregion
#region Methods
public void Cleanup()
{
_decreaseRepeatButton.SizeChanged -= OnButtonSizeChanged;
}
private void OnButtonSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs) => InvalidateVisual();
protected override void OnRender(DrawingContext drawingContext)
{
double offset = _decreaseRepeatButton.ActualWidth + (_thumb.ActualWidth / 2.0);
FormattedText text = new FormattedText(GetText(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface(Font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), FontSize, Foreground);
Geometry border = CreateBorder(offset, text.Width, text.Height);
drawingContext.DrawGeometry(Background, new Pen(BorderBrush, 1), border);
drawingContext.DrawText(text, new Point(offset - (text.Width / 2.0), -26));
}
private string GetText()
{
string valueText = _slider.Value.ToString();
if (!string.IsNullOrWhiteSpace(_unit))
valueText += " " + _unit;
return valueText;
}
private Geometry CreateBorder(double offset, double width, double height)
{
double halfWidth = width / 2.0;
PathGeometry borderGeometry = new PathGeometry();
PathFigure border = new PathFigure
{
StartPoint = new Point(offset, 0),
IsClosed = true,
IsFilled = true
};
border.Segments.Add(new LineSegment(new Point(offset + 4, -6), true));
border.Segments.Add(new LineSegment(new Point(offset + 4 + halfWidth, -6), true));
border.Segments.Add(new LineSegment(new Point(offset + 4 + halfWidth, -10 - height), true));
border.Segments.Add(new LineSegment(new Point(offset - 4 - halfWidth, -10 - height), true));
border.Segments.Add(new LineSegment(new Point(offset - 4 - halfWidth, -6), true));
border.Segments.Add(new LineSegment(new Point(offset - 4, -6), true));
borderGeometry.Figures.Add(border);
return borderGeometry;
}
#endregion
}
}

View File

@ -108,6 +108,8 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Attached\SliderValue.cs" />
<Compile Include="Attached\SliderValueAdorner.cs" />
<Compile Include="App.xaml.cs"> <Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>

View File

@ -1,15 +1,24 @@
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"> xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:attached="clr-namespace:KeyboardAudioVisualizer.Attached">
<styles:CachedResourceDictionary.MergedDictionaries> <styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" /> <styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
</styles:CachedResourceDictionary.MergedDictionaries> </styles:CachedResourceDictionary.MergedDictionaries>
<Style x:Key="StyleSlider" <Style x:Key="StyleSlider"
BasedOn="{StaticResource {x:Type Slider}}" BasedOn="{StaticResource {x:Type Slider}}"
TargetType="Slider"> TargetType="Slider">
<!-- ReSharper disable Xaml.RedundantStyledValue - -->
<Setter Property="attached:SliderValue.IsShown" Value="True" />
<Setter Property="attached:SliderValue.Background" Value="{StaticResource BrushTooltipBackground}" />
<Setter Property="attached:SliderValue.BorderBrush" Value="{StaticResource BrushTooltipBorder}" />
<Setter Property="attached:SliderValue.Foreground" Value="{StaticResource BrushTooltipForeground}" />
<Setter Property="attached:SliderValue.FontSize" Value="{StaticResource FontSizeTooltip}" />
<Setter Property="attached:SliderValue.Font" Value="pack://application:,,,/Resources/#Cinzel" />
<!-- ReSharper restore Xaml.RedundantStyledValue -->
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsEnabled" Value="False"> <Trigger Property="IsEnabled" Value="False">

View File

@ -3,7 +3,8 @@
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles" xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider" xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls" xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"> xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:attached="clr-namespace:KeyboardAudioVisualizer.Attached">
<styles:CachedResourceDictionary.MergedDictionaries> <styles:CachedResourceDictionary.MergedDictionaries>
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" /> <styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
@ -61,11 +62,13 @@
<Label controls:Formular.IsLabel="True" Content="Min Freq.:" /> <Label controls:Formular.IsLabel="True" Content="Min Freq.:" />
<Slider controls:Formular.Fill="True" Minimum="0" Maximum="22100" IsSnapToTickEnabled="True" TickFrequency="10" TickPlacement="None" <Slider controls:Formular.Fill="True" Minimum="0" Maximum="22100" IsSnapToTickEnabled="True" TickFrequency="10" TickPlacement="None"
Value="{Binding MinFrequency}" Value="{Binding MinFrequency}"
attached:SliderValue.Unit="Hz"
ToolTip="The minimum frequency used in the graph." /> ToolTip="The minimum frequency used in the graph." />
<Label controls:Formular.IsLabel="True" Content="Max Freq.:" /> <Label controls:Formular.IsLabel="True" Content="Max Freq.:" />
<Slider controls:Formular.Fill="True" Minimum="0" Maximum="22100" IsSnapToTickEnabled="True" TickFrequency="10" TickPlacement="None" <Slider controls:Formular.Fill="True" Minimum="0" Maximum="22100" IsSnapToTickEnabled="True" TickFrequency="10" TickPlacement="None"
Value="{Binding MaxFrequency}" Value="{Binding MaxFrequency}"
attached:SliderValue.Unit="Hz"
ToolTip="The maximum frequency used in the graph." /> ToolTip="The maximum frequency used in the graph." />
<Label controls:Formular.IsLabel="True" Content="Gamma:" /> <Label controls:Formular.IsLabel="True" Content="Gamma:" />
@ -79,6 +82,7 @@
<Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Reference:" /> <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" <Slider controls:Formular.Fill="True" Minimum="1" Maximum="240" IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="None"
Value="{Binding ReferenceLevel}" Value="{Binding ReferenceLevel}"
attached:SliderValue.Unit="dB"
ToolTip="The reference value used to calculate the power of each bar.&#x0a;(You can read this as 'scaling')" /> ToolTip="The reference value used to calculate the power of each bar.&#x0a;(You can read this as 'scaling')" />
<Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Smoothing:" /> <Label controls:Formular.IsLabel="True" controls:Formular.LineBreaks="1" Content="Smoothing:" />

View File

@ -12,6 +12,7 @@
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider" xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
xmlns:helper="clr-namespace:KeyboardAudioVisualizer.Helper" xmlns:helper="clr-namespace:KeyboardAudioVisualizer.Helper"
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:attached="clr-namespace:KeyboardAudioVisualizer.Attached"
mc:Ignorable="d" mc:Ignorable="d"
Title="Keyboard Audio-Visualizer # Configuration" Title="Keyboard Audio-Visualizer # Configuration"
Icon="pack://application:,,,/KeyboardAudioVisualizer;component/Resources/Icon.ico" Icon="pack://application:,,,/KeyboardAudioVisualizer;component/Resources/Icon.ico"
@ -37,7 +38,7 @@
<DataTemplate x:Key="DataTemplateVisualizationSelection" DataType="{x:Type visualizationProvider:VisualizationType}"> <DataTemplate x:Key="DataTemplateVisualizationSelection" DataType="{x:Type visualizationProvider:VisualizationType}">
<TextBlock Text="{Binding Converter={StaticResource VisualizationProviderDisplayNameConverter}}" /> <TextBlock Text="{Binding Converter={StaticResource VisualizationProviderDisplayNameConverter}}" />
</DataTemplate> </DataTemplate>
<ObjectDataProvider x:Key="DataProviderVisualizationTypes" ObjectType="{x:Type sys:Enum}" MethodName="GetValues"> <ObjectDataProvider x:Key="DataProviderVisualizationTypes" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
<ObjectDataProvider.MethodParameters> <ObjectDataProvider.MethodParameters>
<x:Type TypeName="visualizationProvider:VisualizationType" /> <x:Type TypeName="visualizationProvider:VisualizationType" />
@ -52,142 +53,151 @@
<TabControl Style="{StaticResource StyleTabControlNavigation}"> <TabControl Style="{StaticResource StyleTabControlNavigation}">
<TabItem Header="Keyboard"> <TabItem Header="Keyboard">
<DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary], Converter={StaticResource VisualizationToLastChildFillConverter}}"> <AdornerDecorator>
<GroupBox DockPanel.Dock="Top"> <DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary], Converter={StaticResource VisualizationToLastChildFillConverter}}">
<controls:Formular> <GroupBox DockPanel.Dock="Top">
<controls:Formular.Resources> <controls:Formular>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" /> <controls:Formular.Resources>
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" /> <Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" /> <Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
</controls:Formular.Resources> <Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</controls:Formular.Resources>
<Label controls:Formular.IsLabel="True" Content="Visualization: " /> <Label controls:Formular.IsLabel="True" Content="Visualization: " />
<ComboBox controls:Formular.Fill="True" SelectedIndex="0" <ComboBox controls:Formular.Fill="True" SelectedIndex="0"
ItemTemplate="{StaticResource DataTemplateVisualizationSelection}" ItemTemplate="{StaticResource DataTemplateVisualizationSelection}"
ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes}, ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes},
Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Keyboard}}" Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Keyboard}}"
SelectedItem="{Binding SelectedPrimaryVisualization}" SelectedItem="{Binding SelectedPrimaryVisualization}"
ToolTip="The visualization shown on the device.&#x0a; - Frequency Bars: Shows vertical bars representing the frequencies of the song.&#x0a; - Level: Shows two horizontal bars representing the loudness of the song (left and right).&#x0a; - Beat: Shows a flash to the beat of the song (this doesn't work too well right now :()" /> ToolTip="The visualization shown on the device.&#x0a; - Frequency Bars: Shows vertical bars representing the frequencies of the song.&#x0a; - Level: Shows two horizontal bars representing the loudness of the song (left and right).&#x0a; - Beat: Shows a flash to the beat of the song (this doesn't work too well right now :()" />
</controls:Formular> </controls:Formular>
</GroupBox> </GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top"> <GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary].Configuration}" /> <ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary].Configuration}" />
</GroupBox> </GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top"> <GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary]}" /> <ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary]}" />
</GroupBox> </GroupBox>
</DockPanel> </DockPanel>
</AdornerDecorator>
</TabItem> </TabItem>
<TabItem Header="Mouse/Headset"> <TabItem Header="Mouse/Headset">
<DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary], Converter={StaticResource VisualizationToLastChildFillConverter}}"> <AdornerDecorator>
<GroupBox DockPanel.Dock="Top"> <DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary], Converter={StaticResource VisualizationToLastChildFillConverter}}">
<controls:Formular> <GroupBox DockPanel.Dock="Top">
<controls:Formular.Resources> <controls:Formular>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" /> <controls:Formular.Resources>
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" /> <Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" /> <Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
</controls:Formular.Resources> <Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</controls:Formular.Resources>
<Label controls:Formular.IsLabel="True" Content="Visualization: " /> <Label controls:Formular.IsLabel="True" Content="Visualization: " />
<ComboBox controls:Formular.Fill="True" SelectedIndex="0" <ComboBox controls:Formular.Fill="True" SelectedIndex="0"
ItemTemplate="{StaticResource DataTemplateVisualizationSelection}" ItemTemplate="{StaticResource DataTemplateVisualizationSelection}"
ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes}, ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes},
Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Mouse}}" Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Mouse}}"
SelectedItem="{Binding SelectedSecondaryVisualization}" /> SelectedItem="{Binding SelectedSecondaryVisualization}" />
</controls:Formular> </controls:Formular>
</GroupBox> </GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top"> <GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary].Configuration}" /> <ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary].Configuration}" />
</GroupBox> </GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top"> <GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary]}" /> <ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary]}" />
</GroupBox> </GroupBox>
</DockPanel> </DockPanel>
</AdornerDecorator>
</TabItem> </TabItem>
<TabItem Header="Lightbar/Mousepad"> <TabItem Header="Lightbar/Mousepad">
<DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary], Converter={StaticResource VisualizationToLastChildFillConverter}}"> <AdornerDecorator>
<GroupBox DockPanel.Dock="Top"> <DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary], Converter={StaticResource VisualizationToLastChildFillConverter}}">
<controls:Formular> <GroupBox DockPanel.Dock="Top">
<controls:Formular.Resources> <controls:Formular>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" /> <controls:Formular.Resources>
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" /> <Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" /> <Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
</controls:Formular.Resources> <Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</controls:Formular.Resources>
<Label controls:Formular.IsLabel="True" Content="Visualization: " /> <Label controls:Formular.IsLabel="True" Content="Visualization: " />
<ComboBox controls:Formular.Fill="True" SelectedIndex="0" <ComboBox controls:Formular.Fill="True" SelectedIndex="0"
ItemTemplate="{StaticResource DataTemplateVisualizationSelection}" ItemTemplate="{StaticResource DataTemplateVisualizationSelection}"
ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes}, ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes},
Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Mousepad}}" Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Mousepad}}"
SelectedItem="{Binding SelectedTertiaryVisualization}" /> SelectedItem="{Binding SelectedTertiaryVisualization}" />
</controls:Formular> </controls:Formular>
</GroupBox> </GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top"> <GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary].Configuration}" /> <ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary].Configuration}" />
</GroupBox> </GroupBox>
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top"> <GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary]}" /> <ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary]}" />
</GroupBox> </GroupBox>
</DockPanel> </DockPanel>
</AdornerDecorator>
</TabItem> </TabItem>
<TabItem Header="Settings"> <TabItem Header="Settings">
<GroupBox VerticalAlignment="Top"> <AdornerDecorator>
<StackPanel Orientation="Vertical"> <GroupBox VerticalAlignment="Top">
<Grid> <StackPanel Orientation="Vertical">
<Grid.Resources> <Grid>
<Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" /> <Grid.Resources>
<Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" /> <Style BasedOn="{StaticResource StyleLabelFormular}" TargetType="Label" />
<Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" /> <Style BasedOn="{StaticResource StyleTextBlockFormular}" TargetType="TextBlock" />
</Grid.Resources> <Style BasedOn="{StaticResource StyleListBoxFormular}" TargetType="ListBox" />
</Grid.Resources>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="8" /> <ColumnDefinition Width="8" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="8" /> <ColumnDefinition Width="8" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<controls:Formular Grid.Column="0"> <controls:Formular Grid.Column="0">
<Label controls:Formular.IsLabel="True" Content="Version:" /> <Label controls:Formular.IsLabel="True" Content="Version:" />
<TextBlock Text="{Binding Version}" /> <TextBlock Text="{Binding Version}" />
<Label controls:Formular.IsLabel="True" Content="Update-Rate" /> <Label controls:Formular.IsLabel="True" Content="Update-Rate" />
<Slider Minimum="1" Maximum="40" controls:Formular.Fill="True" IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight" <Slider Minimum="1" Maximum="40" controls:Formular.Fill="True" IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight"
Value="{Binding UpdateRate}" Value="{Binding UpdateRate}"
ToolTip="Defines how fast the data is updated.&#x0a;Low values can reduce CPU-usage but will cause stuttering." /> attached:SliderValue.Unit="FPS"
ToolTip="Defines how fast the data is updated.&#x0a;Low values can reduce CPU-usage but will cause stuttering." />
<Label controls:Formular.LineBreaks="1" controls:Formular.IsLabel="True" Content="Devices:" /> <Label controls:Formular.LineBreaks="1" controls:Formular.IsLabel="True" Content="Devices:" />
</controls:Formular> </controls:Formular>
</Grid> </Grid>
<!-- TODO DarthAffe 05.08.2017: Fix the formular to support that use-case --> <!-- TODO DarthAffe 05.08.2017: Fix the formular to support that use-case -->
<ItemsControl VerticalAlignment="Top" HorizontalAlignment="Left" Margin="120,-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> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Style="{StaticResource StyleTextBlockFormular}"> <TextBlock Style="{StaticResource StyleTextBlockFormular}">
<TextBlock.Text> <TextBlock.Text>
<MultiBinding StringFormat="> {0} {1} ({2})"> <MultiBinding StringFormat="> {0} {1} ({2})">
<Binding Path="DeviceInfo.Manufacturer" /> <Binding Path="DeviceInfo.Manufacturer" />
<Binding Path="DeviceInfo.Model" /> <Binding Path="DeviceInfo.Model" />
<Binding Path="DeviceInfo.DeviceType" /> <Binding Path="DeviceInfo.DeviceType" />
</MultiBinding> </MultiBinding>
</TextBlock.Text> </TextBlock.Text>
</TextBlock> </TextBlock>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
</StackPanel> </StackPanel>
</GroupBox> </GroupBox>
</AdornerDecorator>
</TabItem> </TabItem>
</TabControl> </TabControl>