Customisable shortcuts: first bulky implementation
This commit is contained in:
@ -109,11 +109,12 @@
|
||||
</GroupBox.Header>
|
||||
<Grid>
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,5">
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeOffset}" TextWrapping="Wrap" Margin="0,2,0,0"/>
|
||||
<TextBox x:Name="VolumeOffset" TextWrapping="Wrap" Width="25" PreviewTextInput="NumberValidationTextBox" Margin="8,2,0,0"/>
|
||||
</StackPanel>
|
||||
<Grid MinWidth="300" Margin="0,5,0,0">
|
||||
|
||||
<Grid MinWidth="420" Margin="0,5,0,0" x:Name="RebindKeyWrapper">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
@ -126,23 +127,79 @@
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_NextTrack}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="0" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_PreviousTrack}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="1" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_PlayPause}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="2" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeUp}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="3" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeDown}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="4" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeMute}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="5" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_ShowWindow}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="6" Margin="1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_NextTrack}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="0" Margin="1,1,1,1" Grid.RowSpan="2"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_PreviousTrack}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="2" Margin="1,1,1,1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_PlayPause}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="3" Margin="1,1,1,1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeUp}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="4" Margin="1,1,1,1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeDown}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="5" Margin="1,1,1,1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_VolumeMute}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="6" Margin="1,1,1,1"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_ShowWindow}" TextWrapping="Wrap" Grid.Column="0" Grid.Row="7" Margin="1,1,1,1"/>
|
||||
|
||||
<TextBlock Text="ctrl + media_next" TextWrapping="Wrap" Grid.Column="1" Grid.Row="0" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<TextBlock Text="ctrl + media_prev" TextWrapping="Wrap" Grid.Column="1" Grid.Row="1" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<TextBlock Text="ctrl + media_play" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<TextBlock Text="ctrl + volume_up" TextWrapping="Wrap" Grid.Column="1" Grid.Row="3" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<TextBlock Text="ctrl + volume_down" TextWrapping="Wrap" Grid.Column="1" Grid.Row="4" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<TextBlock Text="ctrl + volume_mute" TextWrapping="Wrap" Grid.Column="1" Grid.Row="5" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<TextBlock Text="ctrl + alt + enter" TextWrapping="Wrap" Grid.Column="1" Grid.Row="6" Margin="1" HorizontalAlignment="Right" FontWeight="Bold"/>
|
||||
<StackPanel x:Name="Shortcut_NextTrack" Orientation="Horizontal" Grid.Column="1" Grid.Row="0" Margin="0,0,0,2" Grid.RowSpan="2">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"/>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="Shortcut_PreviousTrack" Orientation="Horizontal" Grid.Column="1" Grid.Row="2" Margin="0,0,0,2">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"></ComboBox>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="Shortcut_PlayPause" Orientation="Horizontal" Grid.Column="1" Grid.Row="3" Margin="0,0,0,2">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"></ComboBox>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="Shortcut_VolumeUp" Orientation="Horizontal" Grid.Column="1" Grid.Row="4" Margin="0,0,0,2">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"></ComboBox>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="Shortcut_VolumeDown" Orientation="Horizontal" Grid.Column="1" Grid.Row="5" Margin="0,0,0,2">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"></ComboBox>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="Shortcut_VolumeMute" Orientation="Horizontal" Grid.Column="1" Grid.Row="6" Margin="0,0,0,2">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"></ComboBox>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="Shortcut_ShowWindow" Orientation="Horizontal" Grid.Column="1" Grid.Row="7">
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD1" FontWeight="Bold"></ComboBox>
|
||||
<ComboBox Margin="0,0,5,0" MinWidth="70" SelectionChanged="MOD_SelectionChanged" Tag="MOD2" FontWeight="Bold"></ComboBox>
|
||||
<Button Click="RemapKey_Clicked" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="[key]" TextAlignment="Center" TextWrapping="Wrap" MinWidth="150" Margin="5,1,5,1" HorizontalAlignment="Stretch" FontWeight="Bold" VerticalAlignment="Stretch"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<TextBlock Text="Please note that if the input key is not recognized, this is due to a limitation on how virtual keys work." TextWrapping="Wrap" Margin="0,2,0,0" MaxWidth="420" />
|
||||
</StackPanel>
|
||||
|
||||
<Button Content="{x:Static properties:Resources.Settings_SnapcastResetButton}" Margin="0,5,0,0" Width="120" Click="ShortcutsReset_Clicked"/>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
@ -2,9 +2,11 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Navigation;
|
||||
@ -13,6 +15,8 @@ namespace unison
|
||||
{
|
||||
public partial class Settings : Window
|
||||
{
|
||||
Key _pressedKey = Key.None;
|
||||
|
||||
public static string GetVersion => Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
|
||||
|
||||
public static string GetLicense
|
||||
@ -49,6 +53,52 @@ namespace unison
|
||||
SnapcastPath.Text = Properties.Settings.Default.snapcast_path;
|
||||
SnapcastPort.Text = Properties.Settings.Default.snapcast_port.ToString();
|
||||
VolumeOffset.Text = Properties.Settings.Default.volume_offset.ToString();
|
||||
|
||||
SetupShortcuts();
|
||||
}
|
||||
|
||||
private void SetupShortcuts()
|
||||
{
|
||||
var MODValues = System.Enum.GetValues(typeof(HotkeyHandler.MOD));
|
||||
|
||||
System.Collections.Generic.IEnumerable<StackPanel> stackPanelCollection = RebindKeyWrapper.Children.OfType<StackPanel>();
|
||||
foreach (StackPanel stackPanel in stackPanelCollection)
|
||||
{
|
||||
if (stackPanel.Name.Contains("Shortcut"))
|
||||
{
|
||||
HotkeyHandler.HotkeyPair hotkey = GetHotkeyVariable(stackPanel.Name);
|
||||
System.Collections.Generic.IEnumerable<ComboBox> comboBoxCollection = stackPanel.Children.OfType<ComboBox>();
|
||||
|
||||
HotkeyHandler.MOD[] MODList = System.Enum.GetValues(typeof(HotkeyHandler.MOD))
|
||||
.OfType<HotkeyHandler.MOD>()
|
||||
.Select(x => x & (HotkeyHandler.MOD)hotkey.GetMOD())
|
||||
.Where(x => x != HotkeyHandler.MOD.None)
|
||||
.ToArray();
|
||||
|
||||
foreach (ComboBox comboBox in comboBoxCollection)
|
||||
{
|
||||
foreach (var value in MODValues)
|
||||
{
|
||||
comboBox.Items.Add(value.ToString().ToLower());
|
||||
comboBox.SelectedItem = comboBox.Items[0];
|
||||
comboBox.FontWeight = FontWeights.Light;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < comboBoxCollection.ToArray().Length; i++)
|
||||
{
|
||||
if (i < MODList.Length)
|
||||
{
|
||||
comboBoxCollection.ToArray()[i].SelectedItem = MODList[i].ToString().ToLower();
|
||||
comboBoxCollection.ToArray()[i].FontWeight = FontWeights.Bold;
|
||||
}
|
||||
}
|
||||
|
||||
System.Collections.Generic.IEnumerable<Button> buttonCollection = stackPanel.Children.OfType<Button>();
|
||||
TextBlock textblock = (TextBlock)buttonCollection.First().Content;
|
||||
textblock.Text = ((HotkeyHandler.VK)hotkey.GetVK()).ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
|
||||
@ -88,6 +138,126 @@ namespace unison
|
||||
SnapcastPort.Text = (string)Application.Current.FindResource("snapcastPort");
|
||||
}
|
||||
|
||||
private void HotkeyChanged()
|
||||
{
|
||||
HotkeyHandler hotkeys = (HotkeyHandler)Application.Current.Properties["hotkeys"];
|
||||
hotkeys.RemoveHotkeys();
|
||||
hotkeys.AddHotkeys();
|
||||
}
|
||||
|
||||
private ref HotkeyHandler.HotkeyPair GetHotkeyVariable(string Name)
|
||||
{
|
||||
HotkeyHandler hotkeys = (HotkeyHandler)Application.Current.Properties["hotkeys"];
|
||||
|
||||
if (Name == "Shortcut_NextTrack")
|
||||
return ref hotkeys._NextTrack;
|
||||
if (Name == "Shortcut_PreviousTrack")
|
||||
return ref hotkeys._PreviousTrack;
|
||||
if (Name == "Shortcut_PlayPause")
|
||||
return ref hotkeys._PlayPause;
|
||||
if (Name == "Shortcut_VolumeUp")
|
||||
return ref hotkeys._VolumeUp;
|
||||
if (Name == "Shortcut_VolumeDown")
|
||||
return ref hotkeys._VolumeDown;
|
||||
if (Name == "Shortcut_VolumeMute")
|
||||
return ref hotkeys._VolumeMute;
|
||||
if (Name == "Shortcut_ShowWindow")
|
||||
return ref hotkeys._ShowWindow;
|
||||
return ref hotkeys._NextTrack;
|
||||
}
|
||||
|
||||
private void UpdateHotkey_MOD(string Name, HotkeyHandler.MOD mod) => GetHotkeyVariable(Name).SetMOD(mod);
|
||||
private void UpdateHotkey_VK(string Name, HotkeyHandler.VK vk) => GetHotkeyVariable(Name).SetVK(vk);
|
||||
|
||||
private void MOD_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
ComboBox combobox = (ComboBox)sender;
|
||||
StackPanel stackpanel = (StackPanel)combobox.Parent;
|
||||
System.Collections.Generic.IEnumerable<ComboBox> collection = stackpanel.Children.OfType<ComboBox>();
|
||||
|
||||
HotkeyHandler.MOD MOD1, MOD2;
|
||||
|
||||
// we need to do this because the element is modified -after- this function
|
||||
if (combobox.Tag.ToString() == "MOD1")
|
||||
{
|
||||
MOD1 = GetMOD(e.AddedItems[0].ToString());
|
||||
MOD2 = GetMOD(collection.Last().Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
MOD1 = GetMOD(collection.First().Text);
|
||||
MOD2 = GetMOD(e.AddedItems[0].ToString());
|
||||
}
|
||||
|
||||
if (e.AddedItems[0].ToString() == "none")
|
||||
combobox.FontWeight = FontWeights.Light;
|
||||
else
|
||||
combobox.FontWeight = FontWeights.Bold;
|
||||
|
||||
HotkeyHandler.MOD ModKey = MOD1 | MOD2;
|
||||
|
||||
UpdateHotkey_MOD(stackpanel.Name, ModKey);
|
||||
HotkeyChanged();
|
||||
}
|
||||
|
||||
private void RemapKey_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Button button = (Button)sender;
|
||||
TextBlock textBlock = (TextBlock)button.Content;
|
||||
textBlock.Text = "Enter key...";
|
||||
button.PreviewKeyDown += DetectPressedKey;
|
||||
}
|
||||
|
||||
private void DetectPressedKey(object sender, KeyEventArgs e)
|
||||
{
|
||||
e.Handled = true; // not enough to handle media keys triggering in this setup
|
||||
|
||||
_pressedKey = e.Key;
|
||||
HotkeyHandler.VK VirtualKey = GetVirtualKey(_pressedKey);
|
||||
if (VirtualKey == HotkeyHandler.VK.None)
|
||||
_pressedKey = Key.None;
|
||||
|
||||
Button button = (Button)sender;
|
||||
TextBlock textBlock = (TextBlock)button.Content;
|
||||
StackPanel stackPanel = (StackPanel)button.Parent;
|
||||
|
||||
textBlock.Text = _pressedKey.ToString();
|
||||
button.PreviewKeyDown -= DetectPressedKey;
|
||||
|
||||
UpdateHotkey_VK(stackPanel.Name, VirtualKey);
|
||||
HotkeyChanged();
|
||||
}
|
||||
|
||||
private HotkeyHandler.VK GetVirtualKey(Key key)
|
||||
{
|
||||
var values = System.Enum.GetValues(typeof(HotkeyHandler.VK));
|
||||
foreach (object value in values)
|
||||
{
|
||||
if (key.ToString().ToLower() == value.ToString().ToLower())
|
||||
return (HotkeyHandler.VK)value;
|
||||
}
|
||||
return HotkeyHandler.VK.None;
|
||||
}
|
||||
|
||||
private HotkeyHandler.MOD GetMOD(string str)
|
||||
{
|
||||
var values = System.Enum.GetValues(typeof(HotkeyHandler.MOD));
|
||||
foreach (object value in values)
|
||||
{
|
||||
if (str.ToLower() == value.ToString().ToLower())
|
||||
return (HotkeyHandler.MOD)value;
|
||||
}
|
||||
return HotkeyHandler.MOD.None;
|
||||
}
|
||||
|
||||
private void ShortcutsReset_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
public void UpdateStats()
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
@ -100,6 +270,8 @@ namespace unison
|
||||
StatDatabaseUpdate.Text = mpd.GetStats().DatabaseUpdate.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
Properties.Settings.Default.mpd_host = MpdHost.Text;
|
||||
@ -110,6 +282,23 @@ namespace unison
|
||||
Properties.Settings.Default.snapcast_path = SnapcastPath.Text;
|
||||
Properties.Settings.Default.snapcast_port = int.Parse(SnapcastPort.Text, CultureInfo.InvariantCulture);
|
||||
Properties.Settings.Default.volume_offset = int.Parse(VolumeOffset.Text, CultureInfo.InvariantCulture);
|
||||
|
||||
// todo
|
||||
Properties.Settings.Default.nextTrack_mod = (uint)(GetMOD(Shortcut_NextTrack.Children.OfType<ComboBox>().First().SelectedItem.ToString()) | GetMOD(Shortcut_NextTrack.Children.OfType<ComboBox>().Last().SelectedItem.ToString()));
|
||||
/*Properties.Settings.Default.nextTrack_vk) = (uint)GetVirtualKey(Shortcut_NextTrack.Children.OfType<Button>().First().)
|
||||
Properties.Settings.Default.previousTrack_mod;
|
||||
Properties.Settings.Default.previousTrack_vk);
|
||||
Properties.Settings.Default.playPause_mod;
|
||||
Properties.Settings.Default.playPause_vk);
|
||||
Properties.Settings.Default.volumeUp_mod;
|
||||
Properties.Settings.Default.volumeUp_vk);
|
||||
Properties.Settings.Default.volumeDown_mod;
|
||||
Properties.Settings.Default.volumeDown_vk);
|
||||
Properties.Settings.Default.volumeMute_mod;
|
||||
Properties.Settings.Default.volumeMute_vk);
|
||||
Properties.Settings.Default.showWindow_mod;
|
||||
Properties.Settings.Default.showWindow_vk);*/
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user