new folder structure and new C# script host
This commit is contained in:
24
src/WPF/AboutWindow.xaml
Normal file
24
src/WPF/AboutWindow.xaml
Normal file
@@ -0,0 +1,24 @@
|
||||
<Window x:Class="mpvnet.AboutWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="About mpv.net"
|
||||
FontSize="16"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ResizeMode="NoResize"
|
||||
SizeToContent="WidthAndHeight"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}">
|
||||
|
||||
<Grid>
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBlock FontSize="30" TextAlignment="Center" Margin="10,10,10,0">mpv.net</TextBlock>
|
||||
<TextBlock Name="ContentBlock" TextAlignment="Center" Margin="20,10,20,20"></TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
18
src/WPF/AboutWindow.xaml.cs
Normal file
18
src/WPF/AboutWindow.xaml.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class AboutWindow : Window
|
||||
{
|
||||
public AboutWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
ContentBlock.Text = App.Version;
|
||||
}
|
||||
|
||||
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e) => Close();
|
||||
}
|
||||
}
|
||||
60
src/WPF/CommandPaletteWindow.xaml
Normal file
60
src/WPF/CommandPaletteWindow.xaml
Normal file
@@ -0,0 +1,60 @@
|
||||
<Window x:Class="mpvnet.CommandPaletteWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Command Palette"
|
||||
Height="295"
|
||||
Width="400"
|
||||
FontSize="13"
|
||||
ResizeMode="NoResize"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Loaded="Window_Loaded">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox Name="FilterTextBox"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
PreviewKeyDown="FilterTextBox_PreviewKeyDown"
|
||||
TextChanged="FilterTextBox_TextChanged"/>
|
||||
|
||||
<ListView Name="ListView"
|
||||
Grid.Row="1"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
MouseUp="ListView_MouseUp">
|
||||
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Text="{Binding Display}"></TextBlock>
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding Input}"
|
||||
HorizontalAlignment="Right"></TextBlock>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Window>
|
||||
125
src/WPF/CommandPaletteWindow.xaml.cs
Normal file
125
src/WPF/CommandPaletteWindow.xaml.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
|
||||
using static mpvnet.Core;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class CommandPaletteWindow : Window
|
||||
{
|
||||
ICollectionView CollectionView;
|
||||
|
||||
public CommandPaletteWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
CollectionViewSource collectionViewSource = new CollectionViewSource() { Source = CommandItem.Items };
|
||||
CollectionView = collectionViewSource.View;
|
||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||
CollectionView.Filter = yourCostumFilter;
|
||||
ListView.ItemsSource = CollectionView;
|
||||
}
|
||||
|
||||
bool Filter(CommandItem item)
|
||||
{
|
||||
if (item.Command == "")
|
||||
return false;
|
||||
|
||||
string filter = FilterTextBox.Text.ToLower();
|
||||
|
||||
if (filter == "")
|
||||
return true;
|
||||
|
||||
if (item.Command.ToLower().Contains(filter) ||
|
||||
item.Input.ToLower().Contains(filter) ||
|
||||
item.Path.ToLower().Contains(filter))
|
||||
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(new HwndSourceHook(WndProc));
|
||||
Keyboard.Focus(FilterTextBox);
|
||||
SelectFirst();
|
||||
}
|
||||
|
||||
void SelectFirst()
|
||||
{
|
||||
if (ListView.Items.Count > 0)
|
||||
ListView.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||
handled = true;
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up:
|
||||
{
|
||||
int index = ListView.SelectedIndex;
|
||||
index -= 1;
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
ListView.SelectedIndex = index;
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Down:
|
||||
{
|
||||
int index = ListView.SelectedIndex;
|
||||
|
||||
if (++index > ListView.Items.Count - 1)
|
||||
index = ListView.Items.Count - 1;
|
||||
|
||||
ListView.SelectedIndex = index;
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Escape:
|
||||
Close();
|
||||
break;
|
||||
case Key.Enter:
|
||||
Execute();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Execute()
|
||||
{
|
||||
if (ListView.SelectedItem != null)
|
||||
{
|
||||
CommandItem item = ListView.SelectedItem as CommandItem;
|
||||
Close();
|
||||
core.command(item.Command);
|
||||
}
|
||||
}
|
||||
|
||||
void ListView_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Execute();
|
||||
}
|
||||
|
||||
void FilterTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
CollectionView.Refresh();
|
||||
SelectFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/WPF/ConfWindow.xaml
Normal file
66
src/WPF/ConfWindow.xaml
Normal file
@@ -0,0 +1,66 @@
|
||||
<Window xmlns:Controls="clr-namespace:Controls" x:Name="ConfWindow1" x:Class="mpvnet.ConfWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Config Editor"
|
||||
Height="530"
|
||||
Width="700"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Loaded="ConfWindow1_Loaded">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Controls:SearchTextBoxUserControl
|
||||
x:Name="SearchControl"
|
||||
HintText="Find a setting"
|
||||
Width="250"
|
||||
Margin="0,20,0,0"
|
||||
Grid.ColumnSpan="2"/>
|
||||
|
||||
<ScrollViewer Name="MainScrollViewer"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,0,10">
|
||||
|
||||
<StackPanel x:Name="MainStackPanel"></StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
||||
<ListBox Name="FilterListBox"
|
||||
ItemsSource="{Binding FilterStrings}"
|
||||
BorderThickness="0"
|
||||
SelectionChanged="FilterListBox_SelectionChanged"
|
||||
Foreground="{x:Static mpvnet:Theme.Heading}"
|
||||
Background="{x:Static mpvnet:Theme.Background}">
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" FontSize="16" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<TextBlock Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static mpvnet:Theme.Heading}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
|
||||
<TextBlock Name="PreviewTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static mpvnet:Theme.Heading}" MouseUp="PreviewTextBlock_MouseUp">Preview mpv.conf</TextBlock>
|
||||
<TextBlock Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static mpvnet:Theme.Heading}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
|
||||
<TextBlock Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static mpvnet:Theme.Heading}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
321
src/WPF/ConfWindow.xaml.cs
Normal file
321
src/WPF/ConfWindow.xaml.cs
Normal file
@@ -0,0 +1,321 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
using DynamicGUI;
|
||||
|
||||
using static mpvnet.Core;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class ConfWindow : Window
|
||||
{
|
||||
List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.editor_toml);
|
||||
List<ConfItem> ConfItems = new List<ConfItem>();
|
||||
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
||||
string InitialContent;
|
||||
|
||||
public ConfWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||
LoadConf(core.ConfPath);
|
||||
LoadConf(App.ConfPath);
|
||||
LoadSettings();
|
||||
InitialContent = GetCompareString();
|
||||
SearchControl.Text = RegistryHelp.GetString(App.RegPath, "ConfigEditorSearch");
|
||||
FilterListBox.SelectedItem = SearchControl.Text.TrimEnd(':');
|
||||
}
|
||||
|
||||
void LoadSettings()
|
||||
{
|
||||
foreach (SettingBase setting in SettingsDefinitions)
|
||||
{
|
||||
if (!FilterStrings.Contains(setting.Filter))
|
||||
FilterStrings.Add(setting.Filter);
|
||||
|
||||
foreach (ConfItem confItem in ConfItems)
|
||||
{
|
||||
if (setting.Name == confItem.Name && confItem.Section == "" && !confItem.IsSectionItem)
|
||||
{
|
||||
setting.Value = confItem.Value.Trim('\'', '"');
|
||||
setting.ConfItem = confItem;
|
||||
confItem.SettingBase = setting;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (setting)
|
||||
{
|
||||
case StringSetting s:
|
||||
MainStackPanel.Children.Add(new StringSettingControl(s));
|
||||
break;
|
||||
case OptionSetting s:
|
||||
MainStackPanel.Children.Add(new OptionSettingControl(s));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
RegistryHelp.SetValue(App.RegPath, "ConfigEditorSearch", SearchControl.Text);
|
||||
|
||||
if (InitialContent == GetCompareString())
|
||||
return;
|
||||
|
||||
File.WriteAllText(core.ConfPath, GetContent("mpv"));
|
||||
File.WriteAllText(App.ConfPath, GetContent("mpvnet"));
|
||||
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||
}
|
||||
|
||||
string GetCompareString()
|
||||
{
|
||||
return string.Join("", SettingsDefinitions.Select(item => item.Name + item.Value).ToArray());
|
||||
}
|
||||
|
||||
void LoadConf(string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return;
|
||||
|
||||
string comment = "";
|
||||
string section = "";
|
||||
bool isSectionItem = false;
|
||||
|
||||
foreach (string currentLine in File.ReadAllLines(file))
|
||||
{
|
||||
string line = currentLine.Trim();
|
||||
|
||||
if (line == "")
|
||||
{
|
||||
comment += "\r\n";
|
||||
}
|
||||
else if (line.StartsWith("#"))
|
||||
{
|
||||
comment += line.Trim() + "\r\n";
|
||||
}
|
||||
else if (line.StartsWith("[") && line.Contains("]"))
|
||||
{
|
||||
if (!isSectionItem && comment != "" && comment != "\r\n")
|
||||
ConfItems.Add(new ConfItem() {
|
||||
Comment = comment, File = Path.GetFileNameWithoutExtension(file)});
|
||||
|
||||
section = line.Substring(0, line.IndexOf("]") + 1);
|
||||
comment = "";
|
||||
isSectionItem = true;
|
||||
}
|
||||
else if (line.Contains("="))
|
||||
{
|
||||
ConfItem item = new ConfItem();
|
||||
item.File = Path.GetFileNameWithoutExtension(file);
|
||||
item.IsSectionItem = isSectionItem;
|
||||
item.Comment = comment;
|
||||
comment = "";
|
||||
item.Section = section;
|
||||
section = "";
|
||||
|
||||
if (line.Contains("#") && !line.Contains("'") && !line.Contains("\""))
|
||||
{
|
||||
item.LineComment = line.Substring(line.IndexOf("#")).Trim();
|
||||
line = line.Substring(0, line.IndexOf("#")).Trim();
|
||||
}
|
||||
|
||||
int pos = line.IndexOf("=");
|
||||
string left = line.Substring(0, pos).Trim().ToLower();
|
||||
string right = line.Substring(pos + 1).Trim();
|
||||
|
||||
if (left == "fs")
|
||||
left = "fullscreen";
|
||||
|
||||
if (left == "loop")
|
||||
left = "loop-file";
|
||||
|
||||
item.Name = left;
|
||||
item.Value = right;
|
||||
ConfItems.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string GetContent(string filename)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<string> namesWritten = new List<string>();
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
{
|
||||
if (filename != item.File || item.Section != "" || item.IsSectionItem)
|
||||
continue;
|
||||
|
||||
if (item.Comment != "")
|
||||
sb.Append(item.Comment);
|
||||
|
||||
if (item.SettingBase == null)
|
||||
{
|
||||
if (item.Name != "")
|
||||
{
|
||||
sb.Append(item.Name + " = " + item.Value);
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
|
||||
sb.AppendLine();
|
||||
namesWritten.Add(item.Name);
|
||||
}
|
||||
}
|
||||
else if ((item.SettingBase.Value ?? "") != item.SettingBase.Default)
|
||||
{
|
||||
string value = "";
|
||||
|
||||
if (item.SettingBase.Type == "string" ||
|
||||
item.SettingBase.Type == "folder" ||
|
||||
item.SettingBase.Type == "color")
|
||||
|
||||
value = "'" + item.SettingBase.Value + "'";
|
||||
else
|
||||
value = item.SettingBase.Value;
|
||||
|
||||
sb.Append(item.Name + " = " + value);
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
|
||||
sb.AppendLine();
|
||||
namesWritten.Add(item.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sb.ToString().Contains("# Editor"))
|
||||
sb.AppendLine("# Editor");
|
||||
|
||||
foreach (SettingBase setting in SettingsDefinitions)
|
||||
{
|
||||
if (filename != setting.File || namesWritten.Contains(setting.Name))
|
||||
continue;
|
||||
|
||||
if ((setting.Value ?? "") != setting.Default)
|
||||
{
|
||||
string value = "";
|
||||
|
||||
if (setting.Type == "string" ||
|
||||
setting.Type == "folder" ||
|
||||
setting.Type == "color")
|
||||
|
||||
value = "'" + setting.Value + "'";
|
||||
else
|
||||
value = setting.Value;
|
||||
|
||||
sb.AppendLine(setting.Name + " = " + value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
{
|
||||
if (filename != item.File || (item.Section == "" && !item.IsSectionItem))
|
||||
continue;
|
||||
|
||||
if (item.Section != "")
|
||||
{
|
||||
if (!sb.ToString().EndsWith("\r\n\r\n"))
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine(item.Section);
|
||||
}
|
||||
|
||||
if (item.Comment != "")
|
||||
sb.Append(item.Comment);
|
||||
|
||||
sb.Append(item.Name + " = " + item.Value);
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
|
||||
sb.AppendLine();
|
||||
namesWritten.Add(item.Name);
|
||||
}
|
||||
|
||||
return "\r\n" + sb.ToString().Trim() + "\r\n";
|
||||
}
|
||||
|
||||
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
string activeFilter = "";
|
||||
|
||||
foreach (var i in FilterStrings)
|
||||
if (SearchControl.Text == i + ":")
|
||||
activeFilter = i;
|
||||
|
||||
if (activeFilter == "")
|
||||
{
|
||||
foreach (UIElement i in MainStackPanel.Children)
|
||||
if ((i as ISettingControl).Contains(SearchControl.Text))
|
||||
i.Visibility = Visibility.Visible;
|
||||
else
|
||||
i.Visibility = Visibility.Collapsed;
|
||||
|
||||
FilterListBox.SelectedItem = null;
|
||||
}
|
||||
else
|
||||
foreach (UIElement i in MainStackPanel.Children)
|
||||
if ((i as ISettingControl).SettingBase.Filter == activeFilter)
|
||||
i.Visibility = Visibility.Visible;
|
||||
else
|
||||
i.Visibility = Visibility.Collapsed;
|
||||
|
||||
MainScrollViewer.ScrollToTop();
|
||||
}
|
||||
|
||||
void ConfWindow1_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SearchControl.SearchTextBox.SelectAll();
|
||||
Keyboard.Focus(SearchControl.SearchTextBox);
|
||||
|
||||
foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>())
|
||||
i.Update();
|
||||
}
|
||||
|
||||
void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0)
|
||||
SearchControl.Text = e.AddedItems[0] + ":";
|
||||
}
|
||||
|
||||
void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ProcessHelp.ShellExecute(Path.GetDirectoryName(core.ConfPath));
|
||||
}
|
||||
|
||||
void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Msg.Show("mpv.conf Preview", GetContent("mpv"));
|
||||
}
|
||||
|
||||
void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ProcessHelp.ShellExecute("https://mpv.io/manual/master/");
|
||||
}
|
||||
|
||||
void SupportTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ProcessHelp.ShellExecute("https://github.com/stax76/mpv.net#Support");
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/WPF/EverythingWindow.xaml
Normal file
44
src/WPF/EverythingWindow.xaml
Normal file
@@ -0,0 +1,44 @@
|
||||
<Window x:Class="mpvnet.EverythingWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Media File Search"
|
||||
FontSize="13"
|
||||
Height="300"
|
||||
Width="600"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Loaded="Window_Loaded">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox Name="FilterTextBox"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
PreviewKeyDown="FilterTextBox_PreviewKeyDown"
|
||||
TextChanged="FilterTextBox_TextChanged"/>
|
||||
|
||||
<ListView Name="ListView"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
Grid.Row="1"
|
||||
MouseUp="ListView_MouseUp"
|
||||
PreviewKeyDown="ListView_PreviewKeyDown">
|
||||
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Window>
|
||||
165
src/WPF/EverythingWindow.xaml.cs
Normal file
165
src/WPF/EverythingWindow.xaml.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
|
||||
using static mpvnet.Core;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class EverythingWindow : Window
|
||||
{
|
||||
public EverythingWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
const int EVERYTHING_REQUEST_FILE_NAME = 0x00000001;
|
||||
const int EVERYTHING_REQUEST_PATH = 0x00000002;
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int Everything_SetSearch(string lpSearchString);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern void Everything_SetRequestFlags(UInt32 dwRequestFlags);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern void Everything_SetSort(UInt32 dwSortType);
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern bool Everything_Query(bool bWait);
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern void Everything_GetResultFullPathName(UInt32 nIndex, StringBuilder lpString, UInt32 nMaxCount);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern bool Everything_GetResultSize(UInt32 nIndex, out long lpFileSize);
|
||||
|
||||
[DllImport("Everything.dll")]
|
||||
public static extern UInt32 Everything_GetNumResults();
|
||||
|
||||
void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(new HwndSourceHook(WndProc));
|
||||
Keyboard.Focus(FilterTextBox);
|
||||
}
|
||||
|
||||
void SelectFirst()
|
||||
{
|
||||
if (ListView.Items.Count > 0)
|
||||
ListView.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||
handled = true;
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up:
|
||||
{
|
||||
int index = ListView.SelectedIndex;
|
||||
|
||||
if (--index < 0)
|
||||
index = 0;
|
||||
|
||||
ListView.SelectedIndex = index;
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Down:
|
||||
{
|
||||
int index = ListView.SelectedIndex;
|
||||
|
||||
if (++index > ListView.Items.Count - 1)
|
||||
index = ListView.Items.Count - 1;
|
||||
|
||||
ListView.SelectedIndex = index;
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Escape: Close(); break;
|
||||
case Key.Enter: Execute(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
|
||||
if (e.Key == Key.Enter)
|
||||
Execute();
|
||||
}
|
||||
|
||||
void Execute()
|
||||
{
|
||||
if (ListView.SelectedItem != null)
|
||||
core.LoadFiles(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
||||
|
||||
Keyboard.Focus(FilterTextBox);
|
||||
}
|
||||
|
||||
void ListView_MouseUp(object sender, MouseButtonEventArgs e) => Execute();
|
||||
|
||||
void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
string searchtext = FilterTextBox.Text;
|
||||
App.RunTask(() => Search(searchtext));
|
||||
}
|
||||
|
||||
object LockObject = new object();
|
||||
|
||||
void Search(string searchText)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<string> items = new List<string>();
|
||||
StringBuilder sb = new StringBuilder(500);
|
||||
Everything_SetSearch(searchText);
|
||||
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
|
||||
Everything_Query(true);
|
||||
uint count = Everything_GetNumResults();
|
||||
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
Everything_GetResultFullPathName(i, sb, (uint)sb.Capacity);
|
||||
string ext = sb.ToString().Ext();
|
||||
|
||||
if (Core.AudioTypes.Contains(ext) || Core.VideoTypes.Contains(ext) || Core.ImageTypes.Contains(ext))
|
||||
items.Add(sb.ToString());
|
||||
|
||||
if (items.Count > 100)
|
||||
break;
|
||||
}
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() => {
|
||||
ListView.ItemsSource = items;
|
||||
SelectFirst();
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Msg.ShowError("Search query failed.",
|
||||
"The search feature depends on [Everything](https://www.voidtools.com) being installed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
src/WPF/InputWindow.xaml
Normal file
70
src/WPF/InputWindow.xaml
Normal file
@@ -0,0 +1,70 @@
|
||||
<Window xmlns:Controls="clr-namespace:Controls" x:Class="mpvnet.InputWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Input Editor"
|
||||
Height="500"
|
||||
Width="750"
|
||||
FontSize="13"
|
||||
ShowInTaskbar="False"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
Loaded="Window_Loaded"
|
||||
Closed="Window_Closed">
|
||||
|
||||
<Window.Resources>
|
||||
<Style x:Key="DataGrid_Font_Centering" TargetType="{x:Type DataGridCell}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type DataGridCell}">
|
||||
<Grid Background="{TemplateBinding Background}">
|
||||
<ContentPresenter VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Controls:SearchTextBoxUserControl
|
||||
HintText="Type ? to get help."
|
||||
x:Name="SearchControl"
|
||||
Width="300"
|
||||
Margin="0,20,0,20"
|
||||
Grid.ColumnSpan="2" />
|
||||
|
||||
<DataGrid x:Name="DataGrid"
|
||||
Grid.Row="1"
|
||||
CommandManager.PreviewCanExecute="DataGrid_PreviewCanExecute"
|
||||
AutoGenerateColumns="False"
|
||||
CellStyle="{StaticResource DataGrid_Font_Centering}" >
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Menu" Binding="{Binding Path}"/>
|
||||
|
||||
<DataGridTemplateColumn Header="Input">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button MinHeight="20" Click="ButtonClick">
|
||||
<TextBlock Text="{Binding Input}"></TextBlock>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTextColumn Header="Command" Binding="{Binding Command}" MaxWidth="330" />
|
||||
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</Window>
|
||||
149
src/WPF/InputWindow.xaml.cs
Normal file
149
src/WPF/InputWindow.xaml.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
|
||||
using static mpvnet.Core;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class InputWindow : Window
|
||||
{
|
||||
ICollectionView CollectionView;
|
||||
string InitialInputConfContent;
|
||||
|
||||
public InputWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitialInputConfContent = GetInputConfContent();
|
||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||
DataGrid.SelectionMode = DataGridSelectionMode.Single;
|
||||
CollectionViewSource collectionViewSource = new CollectionViewSource() { Source = CommandItem.Items };
|
||||
CollectionView = collectionViewSource.View;
|
||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||
CollectionView.Filter = yourCostumFilter;
|
||||
DataGrid.ItemsSource = CollectionView;
|
||||
}
|
||||
|
||||
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
CollectionView.Refresh();
|
||||
|
||||
if (SearchControl.SearchTextBox.Text == "?")
|
||||
{
|
||||
SearchControl.SearchTextBox.Text = "";
|
||||
Msg.Show("Filtering", "Reduce the filter scope with:\n\ni input\n\nm menu\n\nc command\n\nIf only one character is entered input search is performed.");
|
||||
}
|
||||
}
|
||||
|
||||
bool Filter(CommandItem item)
|
||||
{
|
||||
if (item.Command == "") return false;
|
||||
string searchText = SearchControl.SearchTextBox.Text.ToLower();
|
||||
if (searchText == "" || searchText == "?") return true;
|
||||
|
||||
if (searchText.Length == 1)
|
||||
return item.Input.ToLower().Replace("ctrl+", "").Replace("shift+", "").Replace("alt+", "") == searchText.ToLower();
|
||||
else if (searchText.StartsWith("i ") || searchText.StartsWith("i:") || searchText.Length == 1)
|
||||
{
|
||||
if (searchText.Length > 1)
|
||||
searchText = searchText.Substring(2).Trim();
|
||||
|
||||
if (searchText.Length < 3)
|
||||
return item.Input.ToLower().Replace("ctrl+", "").Replace("shift+", "").Replace("alt+", "").Contains(searchText);
|
||||
else
|
||||
return item.Input.ToLower().Contains(searchText);
|
||||
}
|
||||
else if (searchText.StartsWith("m ") || searchText.StartsWith("m:"))
|
||||
return item.Path.ToLower().Contains(searchText.Substring(2).Trim());
|
||||
else if (searchText.StartsWith("c ") || searchText.StartsWith("c:"))
|
||||
return item.Command.ToLower().Contains(searchText.Substring(2).Trim());
|
||||
else if (item.Command.ToLower().Contains(searchText) ||
|
||||
item.Path.ToLower().Contains(searchText) ||
|
||||
item.Input.ToLower().Contains(searchText))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
CommandItem item = ((Button)e.Source).DataContext as CommandItem;
|
||||
if (item is null) return;
|
||||
LearnWindow w = new LearnWindow();
|
||||
w.Owner = this;
|
||||
w.InputItem = item;
|
||||
w.ShowDialog();
|
||||
|
||||
var items = new Dictionary<string, CommandItem>();
|
||||
|
||||
foreach (CommandItem i in CommandItem.Items)
|
||||
if (items.ContainsKey(i.Input) && i.Input != "")
|
||||
Msg.Show($"Duplicate found:\n\n{i.Input}: {i.Path}\n\n{items[i.Input].Input}: {items[i.Input].Path}\n\nPlease note that you can chain multiple commands in the same line by using a semicolon as separator.", "Duplicate Found");
|
||||
else
|
||||
items[i.Input] = i;
|
||||
}
|
||||
|
||||
void Window_Loaded(object sender, RoutedEventArgs e) => Keyboard.Focus(SearchControl.SearchTextBox);
|
||||
|
||||
string GetInputConfContent()
|
||||
{
|
||||
string text = null;
|
||||
|
||||
foreach (string line in Properties.Resources.input_conf.Split(new[] { "\r\n" }, StringSplitOptions.None))
|
||||
{
|
||||
string test = line.Trim();
|
||||
if (test == "" || test.StartsWith("#")) text += test + "\r\n";
|
||||
}
|
||||
|
||||
text = "\r\n" + text.Trim() + "\r\n\r\n";
|
||||
|
||||
foreach (CommandItem item in CommandItem.Items)
|
||||
{
|
||||
string input = item.Input == "" ? "_" : item.Input;
|
||||
string line = " " + input.PadRight(10);
|
||||
|
||||
if (item.Command.Trim() == "")
|
||||
line += " ignore";
|
||||
else
|
||||
line += " " + item.Command.Trim();
|
||||
|
||||
if (item.Path.Trim() != "")
|
||||
line = line.PadRight(40) + " #menu: " + item.Path;
|
||||
|
||||
text += line + "\r\n";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
void Window_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (InitialInputConfContent == GetInputConfContent()) return;
|
||||
File.WriteAllText(core.InputConfPath, GetInputConfContent());
|
||||
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||
}
|
||||
|
||||
void DataGrid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
|
||||
{
|
||||
DataGrid grid = (DataGrid)sender;
|
||||
|
||||
if (e.Command == DataGrid.DeleteCommand)
|
||||
if (Msg.ShowQuestion($"Confirm to delete: {(grid.SelectedItem as CommandItem).Input} ({(grid.SelectedItem as CommandItem).Path})") != MsgResult.OK)
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/WPF/LearnWindow.xaml
Normal file
49
src/WPF/LearnWindow.xaml
Normal file
@@ -0,0 +1,49 @@
|
||||
<Window x:Class="mpvnet.LearnWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Learn Input"
|
||||
Height="200"
|
||||
Width="400"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ResizeMode="NoResize"
|
||||
Loaded="Window_Loaded"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
MouseWheel="Window_MouseWheel"
|
||||
MouseUp="Window_MouseUp"
|
||||
MouseDoubleClick="Window_MouseDoubleClick" PreviewKeyDown="Window_PreviewKeyDown">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="40" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock x:Name="MenuTextBlock"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="16"></TextBlock>
|
||||
|
||||
<TextBlock x:Name="KeyTextBlock"
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="16" />
|
||||
|
||||
<Button x:Name="ConfirmButton" Grid.Row="2" Click="ConfirmButton_Click">Confirm</Button>
|
||||
<Button x:Name="ClearButton" Grid.Row="2" Click="ClearButton_Click" Grid.Column="1">Clear</Button>
|
||||
</Grid>
|
||||
</Window>
|
||||
266
src/WPF/LearnWindow.xaml.cs
Normal file
266
src/WPF/LearnWindow.xaml.cs
Normal file
@@ -0,0 +1,266 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class LearnWindow : Window
|
||||
{
|
||||
public CommandItem InputItem { get; set; }
|
||||
string NewKey = "";
|
||||
|
||||
uint MAPVK_VK_TO_VSC = 0;
|
||||
|
||||
int VK_MENU = 0x12;
|
||||
int VK_LMENU = 0xA4;
|
||||
int VK_RMENU = 0xA5;
|
||||
|
||||
int VK_CONTROL = 0x11;
|
||||
int VK_LCONTROL = 0xA2;
|
||||
int VK_RCONTROL = 0xA3;
|
||||
|
||||
public LearnWindow() => InitializeComponent();
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
static extern short GetKeyState(int keyCode);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpKeyState,
|
||||
StringBuilder pwszBuff, int cchBuff, uint wFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool GetKeyboardState(byte[] lpKeyState);
|
||||
|
||||
string ToUnicode(uint vk)
|
||||
{
|
||||
byte[] keys = new byte[256];
|
||||
|
||||
if (!GetKeyboardState(keys))
|
||||
return "";
|
||||
|
||||
if ((keys[VK_CONTROL] & 0x80) != 0 && (keys[VK_MENU] & 0x80) == 0)
|
||||
keys[VK_LCONTROL] = keys[VK_RCONTROL] = keys[VK_CONTROL] = 0;
|
||||
|
||||
uint scanCode = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
|
||||
|
||||
string ret = ToUnicode(vk, scanCode, keys);
|
||||
|
||||
if (ret.Length == 1 && (int)ret[0] < 32)
|
||||
return "";
|
||||
|
||||
if (ret == "" && (keys[VK_MENU] & 0x80) != 0)
|
||||
{
|
||||
keys[VK_LMENU] = keys[VK_RMENU] = keys[VK_MENU] = 0;
|
||||
ret = ToUnicode(vk, scanCode, keys);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public string ToUnicode(uint vk, uint scanCode, byte[] keys)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(10);
|
||||
ToUnicode(vk, scanCode, keys, sb, sb.Capacity, 0);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
Message m = new Message();
|
||||
m.HWnd = hwnd;
|
||||
m.Msg = msg;
|
||||
m.WParam = wParam;
|
||||
m.LParam = lParam;
|
||||
ProcessKeyEventArgs(ref m);
|
||||
return m.Result;
|
||||
}
|
||||
|
||||
void OnKeyDown(uint vk)
|
||||
{
|
||||
Keys key = (Keys)vk;
|
||||
|
||||
if (key == Keys.ControlKey || key == Keys.ShiftKey ||
|
||||
key == Keys.Menu || key == Keys.None)
|
||||
|
||||
return;
|
||||
|
||||
string text = ToUnicode(vk);
|
||||
|
||||
if ((int)key > 111 && (int)key < 136)
|
||||
text = "F" + ((int)key - 111);
|
||||
|
||||
if ((int)key > 95 && (int)key < 106)
|
||||
text = "KP" + ((int)key - 96);
|
||||
|
||||
switch (text)
|
||||
{
|
||||
case "#": text = "SHARP"; break;
|
||||
case "´´": text = "´"; break;
|
||||
case "``": text = "`"; break;
|
||||
case "^^": text = "^"; break;
|
||||
}
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case Keys.Left: text = "LEFT"; break;
|
||||
case Keys.Up: text = "UP"; break;
|
||||
case Keys.Right: text = "RIGHT"; break;
|
||||
case Keys.Down: text = "DOWN"; break;
|
||||
case Keys.Space: text = "SPACE"; break;
|
||||
case Keys.Enter: text = "ENTER"; break;
|
||||
case Keys.Tab: text = "TAB"; break;
|
||||
case Keys.Back: text = "BS"; break;
|
||||
case Keys.Delete: text = "DEL"; break;
|
||||
case Keys.Insert: text = "INS"; break;
|
||||
case Keys.Home: text = "HOME"; break;
|
||||
case Keys.End: text = "END"; break;
|
||||
case Keys.PageUp: text = "PGUP"; break;
|
||||
case Keys.PageDown: text = "PGDWN"; break;
|
||||
case Keys.Escape: text = "ESC"; break;
|
||||
case Keys.Sleep: text = "SLEEP"; break;
|
||||
case Keys.Cancel: text = "CANCEL"; break;
|
||||
case Keys.PrintScreen: text = "PRINT"; break;
|
||||
case Keys.BrowserFavorites: text = "FAVORITES"; break;
|
||||
case Keys.BrowserSearch: text = "SEARCH"; break;
|
||||
case Keys.BrowserHome: text = "HOMEPAGE"; break;
|
||||
case Keys.LaunchMail: text = "MAIL"; break;
|
||||
case Keys.Play: text = "PLAY"; break;
|
||||
case Keys.Pause: text = "PAUSE"; break;
|
||||
case Keys.MediaPlayPause: text = "PLAYPAUSE"; break;
|
||||
case Keys.MediaStop: text = "STOP"; break;
|
||||
case Keys.MediaNextTrack: text = "NEXT"; break;
|
||||
case Keys.MediaPreviousTrack: text = "PREV"; break;
|
||||
|
||||
case Keys.VolumeUp:
|
||||
case Keys.VolumeDown:
|
||||
case Keys.VolumeMute:
|
||||
text = ""; break;
|
||||
}
|
||||
|
||||
bool isAlt = GetKeyState(18) < 0;
|
||||
bool isShift = GetKeyState(16) < 0;
|
||||
bool isCtrl = GetKeyState(17) < 0;
|
||||
|
||||
bool isLetter = (int)key > 64 && (int)key < 91;
|
||||
|
||||
if (isLetter && isShift)
|
||||
text = text.ToUpper();
|
||||
|
||||
string keyString = ToUnicode(vk);
|
||||
|
||||
if (isAlt && !isCtrl)
|
||||
text = "ALT+" + text;
|
||||
|
||||
if (isShift && keyString == "")
|
||||
text = "SHIFT+" + text;
|
||||
|
||||
if (isCtrl && !(keyString != "" && isCtrl && isAlt))
|
||||
text = "CTRL+" + text;
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
SetKey(text);
|
||||
}
|
||||
|
||||
void SetKey(string key)
|
||||
{
|
||||
NewKey = key;
|
||||
MenuTextBlock.Text = InputItem.Path;
|
||||
KeyTextBlock.Text = key;
|
||||
}
|
||||
|
||||
void ProcessKeyEventArgs(ref Message m)
|
||||
{
|
||||
int WM_KEYDOWN = 0x100;
|
||||
int WM_SYSKEYDOWN = 0x104;
|
||||
int WM_APPCOMMAND = 0x319;
|
||||
|
||||
if (m.Msg == WM_KEYDOWN || m.Msg == WM_SYSKEYDOWN)
|
||||
OnKeyDown((uint)m.WParam.ToInt64());
|
||||
else if (m.Msg == WM_APPCOMMAND)
|
||||
{
|
||||
string value = mpvHelp.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000));
|
||||
|
||||
if (value != null)
|
||||
SetKey(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(new HwndSourceHook(WndProc));
|
||||
SetKey(InputItem.Input);
|
||||
}
|
||||
|
||||
void ConfirmButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InputItem.Input = NewKey;
|
||||
Close();
|
||||
}
|
||||
|
||||
void ClearButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InputItem.Input = "_";
|
||||
Close();
|
||||
}
|
||||
|
||||
void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
if (e.Delta > 0)
|
||||
SetKey("WHEEL_UP");
|
||||
else
|
||||
SetKey("WHEEL_DOWN");
|
||||
}
|
||||
|
||||
void Window_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
switch (e.ChangedButton)
|
||||
{
|
||||
case MouseButton.Left:
|
||||
if (BlockMBTN_LEFT)
|
||||
BlockMBTN_LEFT = false;
|
||||
else
|
||||
SetKey("MBTN_LEFT");
|
||||
break;
|
||||
case MouseButton.Middle:
|
||||
SetKey("MBTN_MID");
|
||||
break;
|
||||
case MouseButton.XButton1:
|
||||
SetKey("MBTN_BACK");
|
||||
break;
|
||||
case MouseButton.XButton2:
|
||||
SetKey("MBTN_FORWARD");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BlockMBTN_LEFT;
|
||||
|
||||
void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
SetKey("MBTN_LEFT_DBL");
|
||||
BlockMBTN_LEFT = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Tab)
|
||||
{
|
||||
OnKeyDown((uint)Keys.Tab);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
src/WPF/Resources.xaml
Normal file
120
src/WPF/Resources.xaml
Normal file
@@ -0,0 +1,120 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet">
|
||||
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Border x:Name="border"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
SnapsToDevicePixels="True">
|
||||
|
||||
<ScrollViewer x:Name="PART_ContentHost"
|
||||
Focusable="false"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
VerticalScrollBarVisibility="Hidden"/>
|
||||
</Border>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static mpvnet:Theme.Heading}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="Padding" Value="6 0 0 0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="LeftCol" Width="18" />
|
||||
<ColumnDefinition x:Name="RightCol" Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid x:Name="PART_CHECKBOX">
|
||||
<Ellipse
|
||||
x:Name="normal"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Fill="{x:Static mpvnet:Theme.Background}"
|
||||
Stroke="{x:Static mpvnet:Theme.Heading}"
|
||||
StrokeThickness="2" />
|
||||
<Ellipse
|
||||
x:Name="Checked1"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Opacity="0" />
|
||||
<Ellipse
|
||||
x:Name="disabled"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Fill="{DynamicResource SemiTransparentWhiteBrush}"
|
||||
Opacity="0"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}" />
|
||||
</Grid>
|
||||
|
||||
<ContentPresenter
|
||||
x:Name="contentPresenter"
|
||||
Grid.Column="1"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentStringFormat="{TemplateBinding ContentStringFormat}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
RecognizesAccessKey="True" />
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="contentPresenter"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To=".55"
|
||||
Duration="0" />
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="disabled"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="CheckStates">
|
||||
<VisualState x:Name="Checked">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="Checked1"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Unchecked" />
|
||||
<VisualState x:Name="Indeterminate" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
68
src/WPF/SearchTextBoxUserControl.xaml
Normal file
68
src/WPF/SearchTextBoxUserControl.xaml
Normal file
@@ -0,0 +1,68 @@
|
||||
<UserControl x:Class="Controls.SearchTextBoxUserControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid Name="SearchTextBoxUserControl1"
|
||||
Background="{x:Static mpvnet:Theme.Background}">
|
||||
|
||||
<TextBlock Name="HintTextBlock"
|
||||
Margin="5,2"
|
||||
Text="Find a setting"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground2}"
|
||||
Background="{x:Static mpvnet:Theme.Background}" />
|
||||
|
||||
<TextBox Name="SearchTextBox"
|
||||
Height="25"
|
||||
Padding="1,2,0,0"
|
||||
BorderThickness="2"
|
||||
Background="Transparent"
|
||||
TextChanged="SearchTextBox_TextChanged"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
CaretBrush="{x:Static mpvnet:Theme.Foreground}" />
|
||||
|
||||
<Button Name="SearchClearButton"
|
||||
Background="Transparent"
|
||||
HorizontalAlignment="Right"
|
||||
FontFamily="Marlett"
|
||||
FontSize="10"
|
||||
Width="17"
|
||||
Height="17"
|
||||
Margin="2,0,4,0"
|
||||
Visibility="Hidden"
|
||||
Click="SearchClearButton_Click" >r
|
||||
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{x:Static mpvnet:Theme.Background}"/>
|
||||
<Setter Property="Foreground" Value="{x:Static mpvnet:Theme.Foreground2}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border BorderThickness="1"
|
||||
BorderBrush="{TemplateBinding Foreground}"
|
||||
SnapsToDevicePixels="True">
|
||||
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Foreground" Value="{x:Static mpvnet:Theme.Heading}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
48
src/WPF/SearchTextBoxUserControl.xaml.cs
Normal file
48
src/WPF/SearchTextBoxUserControl.xaml.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Controls
|
||||
{
|
||||
public partial class SearchTextBoxUserControl : UserControl
|
||||
{
|
||||
public SearchTextBoxUserControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public string Text { get => SearchTextBox.Text; set => SearchTextBox.Text = value; }
|
||||
|
||||
string _HintText;
|
||||
|
||||
public string HintText {
|
||||
get => _HintText;
|
||||
set {
|
||||
_HintText = value;
|
||||
UpdateControls();
|
||||
}
|
||||
}
|
||||
|
||||
void SearchClearButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SearchTextBox.Text = "";
|
||||
Keyboard.Focus(SearchTextBox);
|
||||
}
|
||||
|
||||
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
void UpdateControls()
|
||||
{
|
||||
HintTextBlock.Text = SearchTextBox.Text == "" ? HintText : "";
|
||||
|
||||
if (SearchTextBox.Text == "")
|
||||
SearchClearButton.Visibility = Visibility.Hidden;
|
||||
else
|
||||
SearchClearButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/WPF/SetupWindow.xaml
Normal file
69
src/WPF/SetupWindow.xaml
Normal file
@@ -0,0 +1,69 @@
|
||||
<Window x:Class="mpvnet.SetupWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mpvnet="clr-namespace:mpvnet"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="mpv.net Setup"
|
||||
FontSize="13"
|
||||
Foreground="{x:Static mpvnet:Theme.Foreground}"
|
||||
Background="{x:Static mpvnet:Theme.Background}"
|
||||
SizeToContent="WidthAndHeight"
|
||||
WindowStartupLocation="CenterOwner" >
|
||||
|
||||
<Window.Resources>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Margin" Value="3"></Setter>
|
||||
<Setter Property="Height" Value="25"></Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14"></Setter>
|
||||
<Setter Property="Margin" Value="3,0,0,0"></Setter>
|
||||
<Setter Property="TextAlignment" Value="Center"></Setter>
|
||||
</Style>
|
||||
|
||||
<ControlTemplate x:Key = "ShieldButtonTemplate" TargetType = "Button">
|
||||
<Button Margin="0" HorizontalContentAlignment="Stretch">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0"
|
||||
Source="{x:Static mpvnet:SetupWindow.ShieldIcon}"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Margin="3,0,0,0"/>
|
||||
<ContentPresenter Grid.Column="1" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</ControlTemplate>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Width="180" Margin="5">
|
||||
<TextBlock>Start Menu Shortcut</TextBlock>
|
||||
<Button Name="AddStartMenuShortcut" Click="AddStartMenuShortcut_Click">Add</Button>
|
||||
<Button Name="RemoveStartMenuShortcut" Click="RemoveStartMenuShortcut_Click">Remove</Button>
|
||||
</StackPanel>
|
||||
<StackPanel Width="180" Margin="20,5,5,5">
|
||||
<TextBlock>File Extensions</TextBlock>
|
||||
<Button Name="AddVideo" Click="AddVideo_Click" Template="{StaticResource ShieldButtonTemplate}">Add Video</Button>
|
||||
<Button Name="AddAudio" Click="AddAudio_Click" Template="{StaticResource ShieldButtonTemplate}">Add Audio</Button>
|
||||
<Button Name="AddImage" Click="AddImage_Click" Template="{StaticResource ShieldButtonTemplate}">Add Image</Button>
|
||||
<Button Name="RemoveFileAssociations" Margin="3,15,3,3" Click="RemoveFileAssociations_Click" Template="{StaticResource ShieldButtonTemplate}">Remove All</Button>
|
||||
<Button Name="EditDefaultApp" Click="EditDefaultApp_Click">Edit Default App</Button>
|
||||
</StackPanel>
|
||||
<StackPanel Width="180" Margin="20,5,5,5">
|
||||
<TextBlock>Path Environment Variable</TextBlock>
|
||||
<Button Name="AddToPathEnvVar" Click="AddToPathEnvVar_Click">Add</Button>
|
||||
<Button Name="RemoveFromPathEnvVar" Click="RemoveFromPathEnvVar_Click">Remove</Button>
|
||||
<Button Name="ShowEnvVarEditor" Click="ShowEnvVarEditor_Click">Show Editor</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
109
src/WPF/SetupWindow.xaml.cs
Normal file
109
src/WPF/SetupWindow.xaml.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows;
|
||||
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
using static StockIcon;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class SetupWindow : Window
|
||||
{
|
||||
public SetupWindow() => InitializeComponent();
|
||||
|
||||
static BitmapSource _ShieldIcon;
|
||||
|
||||
public static BitmapSource ShieldIcon {
|
||||
get {
|
||||
if (_ShieldIcon == null)
|
||||
{
|
||||
IntPtr icon = GetIcon(SHSTOCKICONID.Shield, SHSTOCKICONFLAGS.SHGSI_ICON);
|
||||
_ShieldIcon = Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
|
||||
DestroyIcon(icon);
|
||||
}
|
||||
return _ShieldIcon;
|
||||
}
|
||||
}
|
||||
|
||||
void RegFileAssoc(string[] extensions)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Process proc = new Process())
|
||||
{
|
||||
proc.StartInfo.FileName = WinForms.Application.ExecutablePath;
|
||||
proc.StartInfo.Arguments = "--reg-file-assoc " + String.Join(" ", extensions);
|
||||
proc.StartInfo.Verb = "runas";
|
||||
proc.StartInfo.UseShellExecute = true;
|
||||
proc.Start();
|
||||
proc.WaitForExit();
|
||||
|
||||
if (proc.ExitCode == 0)
|
||||
Msg.Show("File associations successfully created.");
|
||||
}
|
||||
|
||||
} catch {}
|
||||
}
|
||||
|
||||
void AddVideo_Click(object sender, RoutedEventArgs e) => RegFileAssoc(Core.VideoTypes);
|
||||
void AddAudio_Click(object sender, RoutedEventArgs e) => RegFileAssoc(Core.AudioTypes);
|
||||
void AddImage_Click(object sender, RoutedEventArgs e) => RegFileAssoc(Core.ImageTypes);
|
||||
|
||||
void RemoveFileAssociations_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Process proc = new Process())
|
||||
{
|
||||
proc.StartInfo.FileName = "powershell.exe";
|
||||
proc.StartInfo.Arguments = "-NoLogo -NoExit -NoProfile -ExecutionPolicy Bypass -File \"" +
|
||||
Folder.Startup + "Setup\\remove file associations.ps1\"";
|
||||
proc.StartInfo.Verb = "runas";
|
||||
proc.StartInfo.UseShellExecute = true;
|
||||
proc.Start();
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
void AddToPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ExecutePowerShellScript(Folder.Startup + "Setup\\add environment variable.ps1");
|
||||
}
|
||||
|
||||
void RemoveFromPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ExecutePowerShellScript(Folder.Startup + "Setup\\remove environment variable.ps1");
|
||||
}
|
||||
|
||||
void AddStartMenuShortcut_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ExecutePowerShellScript(Folder.Startup + "Setup\\create start menu shortcut.ps1");
|
||||
}
|
||||
|
||||
void RemoveStartMenuShortcut_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ExecutePowerShellScript(Folder.Startup + "Setup\\remove start menu shortcut.ps1");
|
||||
}
|
||||
|
||||
void ShowEnvVarEditor_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ProcessHelp.Execute("rundll32.exe", "sysdm.cpl,EditEnvironmentVariables");
|
||||
}
|
||||
|
||||
void ExecutePowerShellScript(string file)
|
||||
{
|
||||
ProcessHelp.Execute("powershell.exe",
|
||||
"-NoLogo -NoExit -NoProfile -ExecutionPolicy Bypass -File \"" + file + "\"");
|
||||
}
|
||||
|
||||
void EditDefaultApp_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ProcessHelp.ShellExecute("ms-settings:defaultapps");
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/WPF/WPF.cs
Normal file
23
src/WPF/WPF.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class WPF
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
if (Application.Current == null)
|
||||
{
|
||||
new Application();
|
||||
|
||||
Application.Current.Resources.MergedDictionaries.Add(
|
||||
Application.LoadComponent(new Uri("mpvnet;component/WPF/Resources.xaml",
|
||||
UriKind.Relative)) as ResourceDictionary);
|
||||
|
||||
Application.Current.DispatcherUnhandledException += (sender, e) => App.ShowException(e.Exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user