mirror of
https://github.com/DarthAffe/KeyboardAudioVisualizer.git
synced 2026-11-11 13:06:26 +00:00
Added Equalizer-UI
This commit is contained in:
1 parent
4d92282b73
commit
9dcf82e6aa
12 files changed
+392
-175
No files matched your search
@@ -0,0 +1,127 @@
|
||||
<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:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization"
|
||||
xmlns:equalizer="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.Equalizer"
|
||||
xmlns:converter="clr-namespace:KeyboardAudioVisualizer.Converter">
|
||||
|
||||
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
|
||||
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||
|
||||
<converter:OffsetToPosXConverter x:Key="OffsetToPosXConverter" />
|
||||
<converter:ValueToPosYConverter x:Key="ValueToPosYConverter" />
|
||||
<converter:EqualizerBandsToPointsConverter x:Key="EqualizerBandsToPointsConverter" />
|
||||
|
||||
<Style x:Key="StyleEqualizerVisualizer"
|
||||
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||
TargetType="{x:Type visualization:EqualizerVisualizer}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="False" />
|
||||
<Setter Property="UseLayoutRounding" Value="False" />
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type visualization:EqualizerVisualizer}">
|
||||
<Grid x:Name="Container" Background="Transparent">
|
||||
<Polyline x:Name="PART_Line" Stroke="White" StrokeThickness="2" StrokeLineJoin="Round">
|
||||
<Polyline.Points>
|
||||
<MultiBinding Converter="{StaticResource EqualizerBandsToPointsConverter}" ConverterParameter="120">
|
||||
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Equalizer" />
|
||||
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Equalizer.Bands" />
|
||||
<Binding Path="ActualWidth" ElementName="Container" />
|
||||
<Binding Path="ActualHeight" ElementName="Container" />
|
||||
</MultiBinding>
|
||||
</Polyline.Points>
|
||||
</Polyline>
|
||||
|
||||
<ItemsControl x:Name="PART_Grips" Opacity="0"
|
||||
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Equalizer.IsEnabled, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Equalizer.Bands}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Canvas />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="equalizer:EqualizerBand">
|
||||
<Border Width="24" Height="24" CornerRadius="12"
|
||||
BorderThickness="3" BorderBrush="{StaticResource BrushEqualizerBorder}"
|
||||
Background="{StaticResource BrushEqualizerBackground}" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
<ItemsControl.ItemContainerStyle>
|
||||
<Style TargetType="ContentPresenter">
|
||||
<Setter Property="Canvas.Left">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource OffsetToPosXConverter}" ConverterParameter="12">
|
||||
<Binding Path="Offset" />
|
||||
<Binding Path="ActualWidth" ElementName="PART_Grips" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Canvas.Top">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource ValueToPosYConverter}" ConverterParameter="12">
|
||||
<Binding Path="Value" />
|
||||
<Binding Path="ActualHeight" ElementName="PART_Grips" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ItemsControl.ItemContainerStyle>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True" />
|
||||
<!--<Condition Binding="{Binding Path=Equalizer.IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type visualization:EqualizerVisualizer}}}" Value="True" />-->
|
||||
</MultiDataTrigger.Conditions>
|
||||
<MultiDataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0:0:0.2" To="1"
|
||||
Storyboard.TargetName="PART_Grips" Storyboard.TargetProperty="Opacity" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</MultiDataTrigger.EnterActions>
|
||||
<MultiDataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0:0:0.25" To="0"
|
||||
Storyboard.TargetName="PART_Grips" Storyboard.TargetProperty="Opacity" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</MultiDataTrigger.ExitActions>
|
||||
</MultiDataTrigger>
|
||||
|
||||
<!--<DataTrigger Binding="{Binding Path=Equalizer.IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type visualization:EqualizerVisualizer}}}" Value="False">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0:0:0.2" To="1"
|
||||
Storyboard.TargetName="PART_Line" Storyboard.TargetProperty="Opacity" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0:0:0.25" To="0"
|
||||
Storyboard.TargetName="PART_Line" Storyboard.TargetProperty="Opacity" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>-->
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</styles:CachedResourceDictionary>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Equalizer;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
|
||||
namespace KeyboardAudioVisualizer.UI.Visualization
|
||||
{
|
||||
//[TemplatePart(Name = "PART_Grips", Type = typeof(Canvas))]
|
||||
[TemplatePart(Name = "PART_Grips", Type = typeof(ItemsControl))]
|
||||
public class EqualizerVisualizer : Control
|
||||
{
|
||||
#region DependencyProperties
|
||||
@@ -19,82 +22,103 @@ namespace KeyboardAudioVisualizer.UI.Visualization
|
||||
set => SetValue(EqualizerProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ReferenceLevelProperty = DependencyProperty.Register(
|
||||
"ReferenceLevel", typeof(double), typeof(EqualizerVisualizer), new PropertyMetadata(default(double)));
|
||||
|
||||
public double ReferenceLevel
|
||||
{
|
||||
get => (double)GetValue(ReferenceLevelProperty);
|
||||
set => SetValue(ReferenceLevelProperty, value);
|
||||
}
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
//private Canvas _canvas;
|
||||
private ItemsControl _grips;
|
||||
private EqualizerBand _draggingBand;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
//public EqualizerVisualizer()
|
||||
//{
|
||||
// SizeChanged += (sender, args) => Update();
|
||||
// Update();
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
//public override void OnApplyTemplate()
|
||||
//{
|
||||
// base.OnApplyTemplate();
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
// _canvas = GetTemplateChild("PART_Grips") as Canvas;
|
||||
//}
|
||||
_grips = GetTemplateChild("PART_Grips") as ItemsControl;
|
||||
}
|
||||
|
||||
//private static void EqualizerChanged(DependencyObject dependencyObject,
|
||||
// DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||
//{
|
||||
// EqualizerVisualizer visualizer = dependencyObject as EqualizerVisualizer;
|
||||
// if (visualizer == null) return;
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseLeftButtonDown(e);
|
||||
|
||||
// void BandsChanged(object sender, NotifyCollectionChangedEventArgs args) => visualizer.Update();
|
||||
EqualizerBand band = GetClickedBand();
|
||||
if (band != null)
|
||||
_draggingBand = band;
|
||||
}
|
||||
|
||||
// if (dependencyPropertyChangedEventArgs.OldValue is IEqualizer oldEqualizer)
|
||||
// oldEqualizer.Bands.CollectionChanged -= BandsChanged;
|
||||
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseLeftButtonUp(e);
|
||||
|
||||
// if (dependencyPropertyChangedEventArgs.NewValue is IEqualizer newEqualizer)
|
||||
// newEqualizer.Bands.CollectionChanged += BandsChanged;
|
||||
//}
|
||||
_draggingBand = null;
|
||||
}
|
||||
|
||||
//private void Update()
|
||||
//{
|
||||
// if (_canvas == null) return;
|
||||
protected override void OnMouseLeave(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
|
||||
// void OnBandChanged(object sender, PropertyChangedEventArgs args) => Update();
|
||||
_draggingBand = null;
|
||||
}
|
||||
|
||||
// foreach (object child in _canvas.Children)
|
||||
// {
|
||||
// EqualizerBand band = (child as ContentControl)?.Content as EqualizerBand;
|
||||
// if (band == null) continue;
|
||||
// band.PropertyChanged -= OnBandChanged;
|
||||
// }
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
// _canvas.Children.Clear();
|
||||
if (_draggingBand == null) return;
|
||||
|
||||
// foreach (EqualizerBand band in Equalizer.Bands)
|
||||
// {
|
||||
// ContentControl ctrl = new ContentControl();
|
||||
UpdateBand(_draggingBand, e.GetPosition(_grips));
|
||||
}
|
||||
|
||||
// ctrl.Content = band;
|
||||
protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseRightButtonDown(e);
|
||||
|
||||
// _canvas.Children.Add(ctrl);
|
||||
// }
|
||||
//}
|
||||
if (_grips == null) return;
|
||||
|
||||
EqualizerBand band = GetClickedBand();
|
||||
if (band == null)
|
||||
{
|
||||
EqualizerBand newBand = Equalizer.AddBand(0, 0);
|
||||
UpdateBand(newBand, e.GetPosition(_grips));
|
||||
}
|
||||
else
|
||||
Equalizer.RemoveBandBand(band);
|
||||
}
|
||||
|
||||
private void UpdateBand(EqualizerBand band, Point position)
|
||||
{
|
||||
double halfHeight = _grips.ActualHeight / 2.0;
|
||||
|
||||
band.Offset = (float)(position.X / _grips.ActualWidth);
|
||||
band.Value = (float)(-(position.Y - halfHeight) / halfHeight);
|
||||
}
|
||||
|
||||
private EqualizerBand GetClickedBand()
|
||||
{
|
||||
ItemsPresenter itemsPresenter = _grips.GetVisualChild<ItemsPresenter>();
|
||||
if (itemsPresenter == null) return null;
|
||||
|
||||
Panel panel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel;
|
||||
if (panel == null) return null;
|
||||
|
||||
foreach (UIElement element in panel.Children)
|
||||
if (element.IsMouseOver)
|
||||
{
|
||||
EqualizerBand band = ((element as ContentPresenter)?.Content as EqualizerBand);
|
||||
if (band != null) return band;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
|
||||
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
|
||||
xmlns:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization"
|
||||
xmlns:equalizer="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.Equalizer"
|
||||
xmlns:converter="clr-namespace:KeyboardAudioVisualizer.Converter">
|
||||
|
||||
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/FrameworkElement.xaml" />
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/Styles/Theme.xaml" />
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Visualization/EqualizerVisualization.xaml" />
|
||||
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||
|
||||
<converter:OffsetToPosXConverter x:Key="OffsetToPosXConverter" />
|
||||
@@ -29,86 +29,10 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StyleEqualizerVisualizer"
|
||||
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||
TargetType="{x:Type visualization:EqualizerVisualizer}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="False" />
|
||||
<Setter Property="UseLayoutRounding" Value="False" />
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type visualization:EqualizerVisualizer}">
|
||||
<Grid Background="Transparent">
|
||||
<ItemsControl x:Name="PART_Grips" Opacity="0" Margin="-12,-12,12,12"
|
||||
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Equalizer.IsEnabled, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Equalizer.Bands}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Canvas />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="equalizer:EqualizerBand">
|
||||
<Border Width="24" Height="24" CornerRadius="12"
|
||||
BorderThickness="3" BorderBrush="{StaticResource BrushEqualizerBorder}"
|
||||
Background="{StaticResource BrushEqualizerBackground}" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
<ItemsControl.ItemContainerStyle>
|
||||
<Style TargetType="ContentPresenter">
|
||||
<Setter Property="Canvas.Left">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource OffsetToPosXConverter}">
|
||||
<Binding Path="Offset" />
|
||||
<Binding Path="ActualWidth" ElementName="PART_Grips" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Canvas.Top">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource ValueToPosYConverter}">
|
||||
<Binding Path="Value" />
|
||||
<Binding Path="ActualHeight" ElementName="PART_Grips" />
|
||||
<Binding Path="ReferenceLevel" RelativeSource="{RelativeSource AncestorType={x:Type visualization:EqualizerVisualizer}}" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ItemsControl.ItemContainerStyle>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0:0:0.2" To="1"
|
||||
Storyboard.TargetName="PART_Grips" Storyboard.TargetProperty="Opacity" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0:0:0.25" To="0"
|
||||
Storyboard.TargetName="PART_Grips" Storyboard.TargetProperty="Opacity" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<DataTemplate DataType="{x:Type visualizationProvider:FrequencyBarsVisualizationProvider}">
|
||||
<Grid>
|
||||
<visualization:FrequencyBarsVisualizer Style="{StaticResource StyleFrequencyBarsVisualizer}" VisualizationProvider="{Binding}" />
|
||||
<visualization:EqualizerVisualizer Style="{StaticResource StyleEqualizerVisualizer}" Equalizer="{Binding Equalizer}" ReferenceLevel="{Binding Configuration.ReferenceLevel}" />
|
||||
<visualization:EqualizerVisualizer Style="{StaticResource StyleEqualizerVisualizer}" Equalizer="{Binding Equalizer}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
|
||||
Reference in new issue
Block a user