From 1bae00051be0267c3f11b741354ef49bd491868d Mon Sep 17 00:00:00 2001 From: Frank Skare Date: Fri, 12 Apr 2019 16:12:12 +0200 Subject: [PATCH] - --- README.md | 13 +- mpv.net/Command.cs | 28 +-- mpv.net/MainForm.cs | 47 ++-- mpv.net/Menu.cs | 114 ++++----- mpv.net/Misc.cs | 8 + mpv.net/Properties/AssemblyInfo.cs | 6 +- mpv.net/Resources/input.conf.txt | 20 +- mpv.net/mp.cs | 19 ++ mpvConfEdit/Controls.cs | 2 +- mpvConfEdit/DynamicGUI/DynamicGUI.cs | 8 +- .../DynamicGUI/OptionSettingControl.xaml | 8 +- .../DynamicGUI/StringSettingControl.xaml | 6 +- mpvConfEdit/MainWindow.xaml | 10 +- mpvConfEdit/MainWindow.xaml.cs | 227 +++++++++++------- mpvConfEdit/Properties/AssemblyInfo.cs | 6 +- mpvConfEdit/SearchTextBoxUserControl.xaml | 8 +- mpvConfEdit/SearchTextBoxUserControl.xaml.cs | 2 +- .../{mpvConfEdit.toml => mpvConf.toml} | 80 +++--- mpvConfEdit/mpvConfEdit.csproj | 6 +- mpvConfEdit/mpvNetConf.toml | 8 + 20 files changed, 337 insertions(+), 289 deletions(-) rename mpvConfEdit/{mpvConfEdit.toml => mpvConf.toml} (98%) create mode 100644 mpvConfEdit/mpvNetConf.toml diff --git a/README.md b/README.md index c95d098..bfa7683 100644 --- a/README.md +++ b/README.md @@ -70,13 +70,22 @@ https://github.com/stax76/mpv.net/wiki/Scripting-(CSharp,-Python,-JavaScript,-Lu ### Changelog +### 2.7 (2019-04-12) + +- the autofit mpv property was added to the conf editor +- the routine that writes the mpv.conf file in the conf editor was completely rewritten +- the conf editor has a dedicated page for mpv.net specific settings, + these settings are saved in the same folder as mpv.conf using mpvnet.conf as filename, + the first setting there is dark-mode +- new optional dark theme + +[go to download page](https://github.com/stax76/mpv.net/releases) + ### 2.6 (2019-04-09) - on Win 7 controls in the conf editor were using a difficult too read too light color - context menu renderer changed to look like Win 10 design, except colors are still system theme colors -[go to download page](https://github.com/stax76/mpv.net/releases) - ### 2.5 (2019-04-08) - in case the input conf don't contain a menu definition mpv.net creates the default menu instead no menu like before diff --git a/mpv.net/Command.cs b/mpv.net/Command.cs index a7a9ff4..792b416 100644 --- a/mpv.net/Command.cs +++ b/mpv.net/Command.cs @@ -83,33 +83,7 @@ namespace mpvnet File.WriteAllText(fp, ""); } - public static void shell_execute(string[] args) - { - Process.Start(args[0]); - } - - public static void set_setting(string[] args) - { - bool changed = false; - var lines = File.ReadAllLines(mp.mpvConfPath); - - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains("=") && - lines[i].Substring(0, lines[i].IndexOf("=")).Trim("# ".ToCharArray()) == args[0]) - { - lines[i] = args[0] + " = " + args[1]; - changed = true; - } - } - - if (changed) - File.WriteAllText(mp.mpvConfPath, String.Join(Environment.NewLine, lines)); - else - File.WriteAllText(mp.mpvConfPath, File.ReadAllText(mp.mpvConfPath) + Environment.NewLine + args[0] + " = " + args[1]); - - Msg.Show("Changed settings are available on next startup."); - } + public static void shell_execute(string[] args) => Process.Start(args[0]); public static void show_info(string[] args) { diff --git a/mpv.net/MainForm.cs b/mpv.net/MainForm.cs index 7750a0c..525642f 100644 --- a/mpv.net/MainForm.cs +++ b/mpv.net/MainForm.cs @@ -16,12 +16,13 @@ namespace mpvnet public static MainForm Instance { get; set; } public static IntPtr Hwnd; - private Point LastCursorPosChanged; - private int LastCursorChangedTickCount; - private bool IgnoreDpiChanged = true; - private float mpvAutofit = 0.42f; - private bool mpvFullscreen; - private int mpvScreen = -1; + private Point LastCursorPosChanged; + private int LastCursorChangedTickCount; + private bool IgnoreDpiChanged = true; + private float MpvAutofit = 0.50f; + private bool MpvFullscreen; + private int MpvScreen = -1; + private string MpvNetDarkMode = "system"; public ContextMenuStripEx CMS; @@ -43,12 +44,15 @@ namespace mpvnet foreach (var i in mp.mpvConf) ProcessMpvProperty(i.Key, i.Value); + foreach (var i in mp.mpvNetConf) + ProcessMpvNetProperty(i.Key, i.Value); + ProcessCommandLineEarly(); - if (mpvScreen == -1) mpvScreen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen); - SetScreen(mpvScreen); + if (MpvScreen == -1) MpvScreen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen); + SetScreen(MpvScreen); - ChangeFullscreen(mpvFullscreen); + ChangeFullscreen(MpvFullscreen); } catch (Exception ex) { @@ -76,7 +80,7 @@ namespace mpvnet { if (IsFullscreen || mp.VideoSize.Width == 0) return; Screen screen = Screen.FromControl(this); - int height = Convert.ToInt32(screen.Bounds.Height * mpvAutofit); + int height = Convert.ToInt32(screen.Bounds.Height * MpvAutofit); int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height); Point middlePos = new Point(Left + Width / 2, Top + Height / 2); var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height)); @@ -91,7 +95,7 @@ namespace mpvnet if (IsFullscreen || mp.VideoSize.Width == 0) return; Screen screen = Screen.FromControl(this); int height = ClientSize.Height; - if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * mpvAutofit); + if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * MpvAutofit); int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height); Point middlePos = new Point(Left + Width / 2, Top + Height / 2); var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height)); @@ -118,6 +122,7 @@ namespace mpvnet string left = i.Substring(2, i.IndexOf("=") - 2); string right = i.Substring(left.Length + 3); ProcessMpvProperty(left, right); + ProcessMpvNetProperty(left, right); } else { @@ -127,7 +132,7 @@ namespace mpvnet { case "fs": case "fullscreen": - mpvFullscreen = true; + MpvFullscreen = true; break; } } @@ -142,14 +147,24 @@ namespace mpvnet case "autofit": if (value.Length == 3 && value.EndsWith("%")) if (int.TryParse(value.Substring(0, 2), out int result)) - mpvAutofit = result / 100f; + MpvAutofit = result / 100f; break; case "fs": case "fullscreen": - mpvFullscreen = value == "yes"; + MpvFullscreen = value == "yes"; break; case "screen": - mpvScreen = Convert.ToInt32(value); + MpvScreen = Convert.ToInt32(value); + break; + } + } + + void ProcessMpvNetProperty(string name, string value) + { + switch (name) + { + case "dark-mode": + MpvNetDarkMode = value; break; } } @@ -425,6 +440,8 @@ namespace mpvnet protected override void OnShown(EventArgs e) { base.OnShown(e); + if ((MpvNetDarkMode == "system" && Misc.IsDarkTheme) || MpvNetDarkMode == "always") + ToolStripRendererEx.ColorTheme = Color.Black; CMS = new ContextMenuStripEx(components); CMS.Opened += CMS_Opened; ContextMenuStrip = CMS; diff --git a/mpv.net/Menu.cs b/mpv.net/Menu.cs index a49f798..73b3c6e 100644 --- a/mpv.net/Menu.cs +++ b/mpv.net/Menu.cs @@ -6,6 +6,7 @@ using System.Drawing.Text; using Microsoft.Win32; using System.Windows.Forms; using System.Drawing; +using System.Diagnostics; public class ContextMenuStripEx : ContextMenuStrip { @@ -168,10 +169,12 @@ public class MenuItemEx : ToolStripMenuItem public class ToolStripRendererEx : ToolStripSystemRenderer { + public static Color ColorForeground { get; set; } = Color.Black; + public static Color ColorTheme { get; set; } = Color.Empty; public static Color ColorChecked { get; set; } public static Color ColorBorder { get; set; } public static Color ColorTop { get; set; } - public static Color ColorBottom { get; set; } + public static Color ColorSelection { get; set; } public static Color ColorBackground { get; set; } public static Color ColorToolStrip1 { get; set; } @@ -186,17 +189,28 @@ public class ToolStripRendererEx : ToolStripSystemRenderer var argb = Convert.ToInt32(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", 0)); if (argb == 0) argb = Color.LightBlue.ToArgb(); - InitColors(Color.FromArgb(argb)); + if (ColorTheme == Color.Empty) + InitColors(Color.FromArgb(argb)); + else + InitColors(ColorTheme); } public static void InitColors(Color c) { ColorBorder = HSLColor.Convert(c).ToColorSetLuminosity(100); ColorChecked = HSLColor.Convert(c).ToColorSetLuminosity(200); - ColorBottom = HSLColor.Convert(c).ToColorSetLuminosity(220); - ColorBackground = HSLColor.Convert(c).ToColorSetLuminosity(230); + ColorSelection = HSLColor.Convert(c).ToColorSetLuminosity(180); + ColorBackground = HSLColor.Convert(c).ToColorSetLuminosity(210); ColorTop = HSLColor.Convert(c).ToColorSetLuminosity(240); + if (ColorTheme == Color.Black) + { + ColorBorder = Color.White; + ColorBackground = Color.FromArgb(50, 50, 50); + ColorSelection = Color.FromArgb(80, 80, 80); + ColorForeground = Color.White; + } + ColorToolStrip1 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 1))); ColorToolStrip2 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.7f))); ColorToolStrip3 = ControlPaint.LightLight(ControlPaint.LightLight(ControlPaint.Light(ColorBorder, 0.1f))); @@ -205,7 +219,10 @@ public class ToolStripRendererEx : ToolStripSystemRenderer protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) { - ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, Color.FromArgb(160, 175, 195), ButtonBorderStyle.Solid); + Rectangle r = e.AffectedBounds; + r.Inflate(-1, -1); + ControlPaint.DrawBorder(e.Graphics, r, ColorBackground, ButtonBorderStyle.Solid); + ControlPaint.DrawBorder(e.Graphics, e.AffectedBounds, ColorBorder, ButtonBorderStyle.Solid); } protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) @@ -222,6 +239,7 @@ public class ToolStripRendererEx : ToolStripSystemRenderer else TextOffset = Convert.ToInt32(e.Item.Height * 0.2); + e.TextColor = ColorForeground; e.TextRectangle = new Rectangle(TextOffset, Convert.ToInt32((e.Item.Height - rect.Height) / 2.0), rect.Width, rect.Height); } @@ -235,9 +253,7 @@ public class ToolStripRendererEx : ToolStripSystemRenderer Rectangle r = new Rectangle(-1, -1, e.AffectedBounds.Width, e.AffectedBounds.Height); using (SolidBrush b = new SolidBrush(ColorToolStrip2)) - { e.Graphics.FillRectangle(b, r); - } } } @@ -252,52 +268,14 @@ public class ToolStripRendererEx : ToolStripSystemRenderer if (e.Item.Selected && e.Item.Enabled) { - if (e.Item.Owner is MenuStrip) - DrawButton(e); - else - { - g.SmoothingMode = SmoothingMode.AntiAlias; - var r2 = new Rectangle(r.X + 2, r.Y, r.Width - 4, r.Height - 1); - r2.Inflate(-1, -1); - using (SolidBrush b = new SolidBrush(ColorChecked)) - g.FillRectangle(b, r2); - } + g.SmoothingMode = SmoothingMode.AntiAlias; + var r2 = new Rectangle(r.X + 2, r.Y, r.Width - 4, r.Height - 1); + r2.Inflate(-1, -1); + using (SolidBrush b = new SolidBrush(ColorSelection)) + g.FillRectangle(b, r2); } } - public void DrawButton(ToolStripItemRenderEventArgs e) - { - var gx = e.Graphics; - var rect = new Rectangle(Point.Empty, e.Item.Size); - var rect2 = new Rectangle(rect.X, rect.Y, rect.Width - 1, rect.Height - 1); - - using (Pen pen = new Pen(ColorBorder)) - gx.DrawRectangle(pen, rect2); - - rect2.Inflate(-1, -1); - var tsb = e.Item as ToolStripButton; - - if (tsb != null && tsb.Checked) - using (SolidBrush brush = new SolidBrush(ColorChecked)) - gx.FillRectangle(brush, rect2); - else - using (SolidBrush brush = new SolidBrush(ColorBottom)) - gx.FillRectangle(brush, rect2); - } - - protected override void OnRenderDropDownButtonBackground(ToolStripItemRenderEventArgs e) - { - if (e.Item.Selected) - DrawButton(e); - } - - protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e) - { - var button = (ToolStripButton)e.Item; - if (e.Item.Selected || button.Checked) - DrawButton(e); - } - protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e) { if (e.Direction == ArrowDirection.Down) throw new NotImplementedException(); @@ -309,10 +287,13 @@ public class ToolStripRendererEx : ToolStripSystemRenderer float y3 = e.Item.Height * 0.75f; e.Graphics.SmoothingMode = SmoothingMode.HighQuality; - using (Pen p = new Pen(Brushes.Black, Control.DefaultFont.Height / 20f)) + using (Brush b = new SolidBrush(ColorForeground)) { - e.Graphics.DrawLine(p, x1, y1, x2, y2); - e.Graphics.DrawLine(p, x2, y2, x3, y3); + using (Pen p = new Pen(b, Control.DefaultFont.Height / 20f)) + { + e.Graphics.DrawLine(p, x1, y1, x2, y2); + e.Graphics.DrawLine(p, x2, y2, x3, y3); + } } } @@ -324,25 +305,14 @@ public class ToolStripRendererEx : ToolStripSystemRenderer protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e) { - if (e.Item.IsOnDropDown) - { - e.Graphics.Clear(ColorBackground); - int right = e.Item.Width - Convert.ToInt32(TextOffset / 5.0); - int top = e.Item.Height / 2; - top -= 1; - using (Pen p = new Pen(Color.Gray)) - e.Graphics.DrawLine(p, new Point(TextOffset, top), new Point(right, top)); - } - else if (e.Vertical) - { - var bounds = e.Item.Bounds; - using (Pen p = new Pen(SystemColors.ControlDarkDark)) - e.Graphics.DrawLine(p, - Convert.ToInt32(bounds.Width / 2.0), - Convert.ToInt32(bounds.Height * 0.15), - Convert.ToInt32(bounds.Width / 2.0), - Convert.ToInt32(bounds.Height * 0.85)); - } + e.Graphics.Clear(ColorBackground); + int top = e.Item.Height / 2; + top -= 1; + int offset = Convert.ToInt32(e.Item.Font.Height * 0.7); + using (Pen p = new Pen(ColorBorder)) + e.Graphics.DrawLine(p, + new Point(offset, top), + new Point(e.Item.Width - offset, top)); } } diff --git a/mpv.net/Misc.cs b/mpv.net/Misc.cs index 1005a46..4ba3065 100644 --- a/mpv.net/Misc.cs +++ b/mpv.net/Misc.cs @@ -15,6 +15,14 @@ namespace mpvnet public static string GetFilter(IEnumerable values) => "*." + String.Join(";*.", values) + "|*." + String.Join(";*.", values) + "|All Files|*.*"; + + public static bool IsDarkTheme { + get { + object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1); + if (value is null) value = 1; + return (int)value == 0; + } + } } public class StringLogicalComparer : IComparer, IComparer diff --git a/mpv.net/Properties/AssemblyInfo.cs b/mpv.net/Properties/AssemblyInfo.cs index 3afbdcc..767c497 100644 --- a/mpv.net/Properties/AssemblyInfo.cs +++ b/mpv.net/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("mpv.net")] -[assembly: AssemblyCopyright("Copyright © 2017 stax76")] +[assembly: AssemblyCopyright("Copyright © 2017-2019 stax76")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.6.0.0")] -[assembly: AssemblyFileVersion("2.6.0.0")] +[assembly: AssemblyVersion("2.7.0.0")] +[assembly: AssemblyFileVersion("2.7.0.0")] diff --git a/mpv.net/Resources/input.conf.txt b/mpv.net/Resources/input.conf.txt index 9cc4dd3..5b98adb 100644 --- a/mpv.net/Resources/input.conf.txt +++ b/mpv.net/Resources/input.conf.txt @@ -123,23 +123,21 @@ Ctrl+t set ontop yes #menu: View > On Top > Enable Ctrl+T set ontop no #menu: View > On Top > Disable - i script-message mpv.net show-info #menu: View > File Info - t script-binding stats/display-stats #menu: View > Show Statistics - T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics + i script-message mpv.net show-info #menu: View > File Info + t script-binding stats/display-stats #menu: View > Show Statistics + T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics + Del script-binding osc/visibility #menu: View > Toggle OSC Visibility + F8 show-text ${playlist} 5000 #menu: View > Show Playlist + F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List - _ script-message mpv.net set-setting hwdec yes #menu: Settings > Hardware Decoding > Enable - _ script-message mpv.net set-setting hwdec no #menu: Settings > Hardware Decoding > Disable Ctrl+c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor Ctrl+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder - h script-message mpv.net show-history #menu: Tools > Show History - l ab-loop #menu: Tools > Set/clear A-B loop points - L cycle-values loop-file "inf" "no" #menu: Tools > Toggle Infinite Looping - Del script-binding osc/visibility #menu: Tools > Toggle OSC Visibility + h script-message mpv.net show-history #menu: Tools > Show History + l ab-loop #menu: Tools > Set/clear A-B loop points + L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding - F8 show-text ${playlist} 5000 #menu: Tools > Show Playlist - F9 show-text ${track-list} 5000 #menu: Tools > Show Audio/Video/Subtitle List _ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command... _ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Show mpv manual diff --git a/mpv.net/mp.cs b/mpv.net/mp.cs index 4d97e0f..21138af 100644 --- a/mpv.net/mp.cs +++ b/mpv.net/mp.cs @@ -10,6 +10,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; + using VBNET; using static mpvnet.libmpv; using static mpvnet.Native; @@ -60,6 +61,7 @@ namespace mpvnet public static string mpvConfFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\"; public static string InputConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\input.conf"; public static string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf"; + public static string mpvNetConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpvnet.conf"; public static List PythonScripts => new List(); public static AutoResetEvent AutoResetEvent = new AutoResetEvent(false); @@ -80,6 +82,23 @@ namespace mpvnet } } + private static Dictionary _mpvNetConf; + + public static Dictionary mpvNetConf { + get { + if (_mpvNetConf == null) + { + _mpvNetConf = new Dictionary(); + + if (File.Exists(mpvNetConfPath)) + foreach (string i in File.ReadAllLines(mpvNetConfPath)) + if (i.Contains("=") && !i.StartsWith("#")) + _mpvNetConf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim(); + } + return _mpvNetConf; + } + } + public static void Init() { if (!Directory.Exists(mp.mpvConfFolderPath)) diff --git a/mpvConfEdit/Controls.cs b/mpvConfEdit/Controls.cs index a29229e..0c654f3 100644 --- a/mpvConfEdit/Controls.cs +++ b/mpvConfEdit/Controls.cs @@ -9,7 +9,7 @@ namespace Controls public static Brush ThemeBrush { get { if (Environment.OSVersion.Version.Major < 10) - return new SolidColorBrush(Colors.DarkSlateGray); + return new SolidColorBrush(SystemColors.WindowTextColor); else return SystemParameters.WindowGlassBrush; } diff --git a/mpvConfEdit/DynamicGUI/DynamicGUI.cs b/mpvConfEdit/DynamicGUI/DynamicGUI.cs index ec1054a..b4e48e4 100644 --- a/mpvConfEdit/DynamicGUI/DynamicGUI.cs +++ b/mpvConfEdit/DynamicGUI/DynamicGUI.cs @@ -54,7 +54,6 @@ namespace DynamicGUI baseSetting.Filter = setting["filter"]; if (setting.HasKey("help")) baseSetting.Help = setting["help"]; if (setting.HasKey("helpurl")) baseSetting.HelpURL = setting["helpurl"]; - if (setting.HasKey("alias")) baseSetting.Alias = setting["alias"]; if (setting.HasKey("width")) baseSetting.Width = setting["width"]; settingsList.Add(baseSetting); } @@ -65,8 +64,9 @@ namespace DynamicGUI public abstract class SettingBase { public string Name { get; set; } - public string Alias { get; set; } + public string Value { get; set; } public string Help { get; set; } + public string Default { get; set; } public string HelpURL { get; set; } public string Filter { get; set; } public int Width { get; set; } @@ -74,15 +74,11 @@ namespace DynamicGUI public class StringSetting : SettingBase { - public string Default { get; set; } - public string Value { get; set; } public bool IsFolder { get; set; } } public class OptionSetting : SettingBase { - public string Default { get; set; } - public string Value { get; set; } public List Options = new List(); } diff --git a/mpvConfEdit/DynamicGUI/OptionSettingControl.xaml b/mpvConfEdit/DynamicGUI/OptionSettingControl.xaml index ad030a6..f76b986 100644 --- a/mpvConfEdit/DynamicGUI/OptionSettingControl.xaml +++ b/mpvConfEdit/DynamicGUI/OptionSettingControl.xaml @@ -8,18 +8,18 @@ d:DesignHeight="450" d:DesignWidth="800"> - + - - + + - + diff --git a/mpvConfEdit/DynamicGUI/StringSettingControl.xaml b/mpvConfEdit/DynamicGUI/StringSettingControl.xaml index 07b6d74..e6d6c9a 100644 --- a/mpvConfEdit/DynamicGUI/StringSettingControl.xaml +++ b/mpvConfEdit/DynamicGUI/StringSettingControl.xaml @@ -9,16 +9,16 @@ d:DesignWidth="800" > - + - + - + diff --git a/mpvConfEdit/MainWindow.xaml b/mpvConfEdit/MainWindow.xaml index 3298510..59761fa 100644 --- a/mpvConfEdit/MainWindow.xaml +++ b/mpvConfEdit/MainWindow.xaml @@ -4,7 +4,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" - Height="600" Width="800" Loaded="MainWindow1_Loaded" WindowStartupLocation="CenterScreen"> + Height="500" Width="700" Loaded="MainWindow1_Loaded" WindowStartupLocation="CenterScreen"> @@ -14,12 +14,12 @@ - + - + @@ -31,7 +31,7 @@ Open config folder Show mpv manual Show support forum - Write config to mpv.conf - + Write config to disk + \ No newline at end of file diff --git a/mpvConfEdit/MainWindow.xaml.cs b/mpvConfEdit/MainWindow.xaml.cs index 9ce68fd..3f7d7a4 100644 --- a/mpvConfEdit/MainWindow.xaml.cs +++ b/mpvConfEdit/MainWindow.xaml.cs @@ -8,14 +8,20 @@ using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using System.Windows.Media; using DynamicGUI; +using Microsoft.Win32; namespace mpvConfEdit { public partial class MainWindow : Window { - public string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf"; - private List DynamicSettings = Settings.LoadSettings(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\mpvConfEdit.toml"); + public string MpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf"; + public string MpvNetConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpvnet.conf"; + private List MpvSettingsDefinitions = Settings.LoadSettings(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\mpvConf.toml"); + private List MpvNetSettingsDefinitions = Settings.LoadSettings(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\mpvNetConf.toml"); + public ObservableCollection FilterStrings { get; } = new ObservableCollection(); + private Dictionary> Comments = new Dictionary>(); public MainWindow() { @@ -23,24 +29,66 @@ namespace mpvConfEdit DataContext = this; Title = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0] as AssemblyProductAttribute).Product + " " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged; + LoadSettings(MpvSettingsDefinitions, MpvConf); + LoadSettings(MpvNetSettingsDefinitions, MpvNetConf); + SearchControl.Text = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\mpv.net", "conf editor search", ""); + SetDarkTheme(); + } - foreach (var setting in DynamicSettings) + public Brush Foreground2 { + get { return (Brush)GetValue(Foreground2Property); } + set { SetValue(Foreground2Property, value); } + } + + public static readonly DependencyProperty Foreground2Property = + DependencyProperty.Register("Foreground2", typeof(Brush), typeof(MainWindow), new PropertyMetadata(Brushes.DarkSlateGray)); + + void SetDarkTheme() + { + string darkMode = MpvNetSettingsDefinitions.Where(item => item.Name == "dark-mode").First().Value; + + object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1); + if (value is null) value = 1; + bool isDarkTheme = (int)value == 0; + + if (!((darkMode == "system" && isDarkTheme) || darkMode == "always")) + return; + + //Background = new SolidColorBrush(Colors.Black); + + Foreground = Brushes.White; + Foreground2 = Brushes.Silver; + Background = Brushes.Black; + + //foreach (var i in MainStackPanel.Children) + //{ + // switch (i) + // { + // case OptionSettingControl c: + // c.Foreground = Brushes.White; + // c.Background = Brushes.Black; + // break; + // } + //} + } + + private void LoadSettings(List settingsDefinitions, + Dictionary confSettings) + { + foreach (var setting in settingsDefinitions) { if (!FilterStrings.Contains(setting.Filter)) FilterStrings.Add(setting.Filter); - foreach (var pair in mpvConf) + + foreach (var pair in confSettings) { - if (setting.Name == pair.Key || setting.Alias == pair.Key) - switch (setting) - { - case StringSetting s: - s.Value = pair.Value; - continue; - case OptionSetting s: - s.Value = pair.Value; - break; - } + if (setting.Name == pair.Key) + { + setting.Value = pair.Value; + continue; + } } + switch (setting) { case StringSetting s: @@ -59,103 +107,96 @@ namespace mpvConfEdit private Dictionary _mpvConf; - public Dictionary mpvConf { + public Dictionary MpvConf { get { - if (_mpvConf == null) - { - _mpvConf = new Dictionary(); - - if (File.Exists(mpvConfPath)) - foreach (var i in File.ReadAllLines(mpvConfPath)) - if (i.Contains("=") && !i.Trim().StartsWith("#")) - { - int pos = i.IndexOf("="); - _mpvConf[i.Substring(0, pos).Trim()] = i.Substring(pos + 1).Trim(); - } - } + if (_mpvConf == null) _mpvConf = LoadConf(MpvConfPath); return _mpvConf; } } - public ObservableCollection FilterStrings { get; } = new ObservableCollection(); + private Dictionary _mpvNetConf; + + public Dictionary MpvNetConf { + get { + if (_mpvNetConf == null) _mpvNetConf = LoadConf(MpvNetConfPath); + return _mpvNetConf; + } + } + + private Dictionary LoadConf(string filePath) + { + Dictionary conf = new Dictionary(); + Comments[filePath] = new Dictionary(); + + if (File.Exists(filePath)) + { + foreach (string i in File.ReadAllLines(filePath)) + { + if (i.Contains("=")) + { + int pos = i.IndexOf("="); + string left = i.Substring(0, pos).Replace(" ", "").ToLower(); + string right = i.Substring(pos + 1).Trim(); + + if (left.StartsWith("#")) + { + Comments[filePath][left.TrimStart("#".ToCharArray())] = right; + continue; + } + + if (left == "fs") left = "fullscreen"; + if (left == "loop") left = "loop-file"; + conf[left] = right; + } + } + } + return conf; + } protected override void OnClosed(EventArgs e) { base.OnClosed(e); WriteToDisk(); + Registry.SetValue(@"HKEY_CURRENT_USER\Software\mpv.net", "conf editor search", SearchControl.Text); } void WriteToDisk() { - foreach (var mpvSetting in DynamicSettings) - { - switch (mpvSetting) - { - case StringSetting s: - if ((s.Value ?? "") != s.Default || mpvConf.ContainsKey(s.Name) || mpvConf.ContainsKey(s.Alias ?? "")) - mpvConf[s.Name] = s.Value; - break; - case OptionSetting s: - if ((s.Value ?? "") != s.Default || mpvConf.ContainsKey(s.Name) || mpvConf.ContainsKey(s.Alias ?? "")) - mpvConf[s.Name] = s.Value; - break; - } - } + WriteToDisk(MpvConfPath, MpvConf, MpvSettingsDefinitions); + WriteToDisk(MpvNetConfPath, MpvNetConf, MpvNetSettingsDefinitions); - if (!File.Exists(mpvConfPath)) - File.WriteAllText(mpvConfPath, ""); - - List lines = File.ReadAllLines(mpvConfPath).ToList(); - - foreach (var mpvSetting in DynamicSettings) - { - foreach (var line in lines.ToArray()) - { - string test = line.Replace("#", "").Replace(" ", ""); - if (test.StartsWith(mpvSetting.Alias + "=")) - { - lines.Remove(line); - foreach (var pair in mpvConf.ToArray()) - if (test.StartsWith(pair.Key + "=")) - mpvConf.Remove(pair.Key); - } - } - } - - foreach (var pair in mpvConf) - { - bool changed = false; - - for (int i = 0; i < lines.Count; i++) - { - if (lines[i].Contains("=") && - lines[i].Substring(0, lines[i].IndexOf("=")).Trim("# ".ToCharArray()) == pair.Key) - { - lines[i] = pair.Key + " = " + pair.Value; - changed = true; - } - } - - if (!changed) - lines.Add(pair.Key + " = " + pair.Value); - } - - foreach (var mpvSetting in DynamicSettings) - { - foreach (var line in lines.ToArray()) - { - string test = line.Replace("#", "").Replace(" ", ""); - - if (test.StartsWith(mpvSetting.Name + "=") && !mpvConf.ContainsKey(mpvSetting.Name)) - lines.Remove(line); - } - } - - File.WriteAllText(mpvConfPath, String.Join(Environment.NewLine, lines)); MessageBox.Show("Changes will be available on next startup of mpv(.net).", Title, MessageBoxButton.OK, MessageBoxImage.Information); } + void WriteToDisk(string filePath, + Dictionary confSettings, + List settings) + { + string content = ""; + + foreach (var i in Comments[filePath]) + content += $"#{i.Key} = {i.Value}\r\n"; + + foreach (var setting in settings) + { + if ((setting.Value ?? "") != setting.Default) + confSettings[setting.Name] = setting.Value; + + if (confSettings.ContainsKey(setting.Name) && + (setting.Value ?? "") == setting.Default || + (setting.Value ?? "") == "") + { + confSettings.Remove(setting.Name); + } + } + + foreach (var i in confSettings) + content = content + $"{i.Key} = {i.Value}\r\n"; + + File.WriteAllText(filePath, content); + } + private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) { string activeFilter = ""; @@ -197,7 +238,7 @@ namespace mpvConfEdit private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e) { - Process.Start(Path.GetDirectoryName(mpvConfPath)); + Process.Start(Path.GetDirectoryName(MpvConfPath)); } private void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e) diff --git a/mpvConfEdit/Properties/AssemblyInfo.cs b/mpvConfEdit/Properties/AssemblyInfo.cs index 9f29518..11c8a30 100644 --- a/mpvConfEdit/Properties/AssemblyInfo.cs +++ b/mpvConfEdit/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ using System.Windows; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("mpv(.net) conf edit")] -[assembly: AssemblyCopyright("Copyright © 2017 stax76")] +[assembly: AssemblyCopyright("Copyright © 2017-2019 stax76")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -51,5 +51,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] +[assembly: AssemblyVersion("1.6.0.0")] +[assembly: AssemblyFileVersion("1.6.0.0")] diff --git a/mpvConfEdit/SearchTextBoxUserControl.xaml b/mpvConfEdit/SearchTextBoxUserControl.xaml index 5435326..901b17c 100644 --- a/mpvConfEdit/SearchTextBoxUserControl.xaml +++ b/mpvConfEdit/SearchTextBoxUserControl.xaml @@ -5,9 +5,9 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - - - - + + + + \ No newline at end of file diff --git a/mpvConfEdit/SearchTextBoxUserControl.xaml.cs b/mpvConfEdit/SearchTextBoxUserControl.xaml.cs index 8235d12..40730a7 100644 --- a/mpvConfEdit/SearchTextBoxUserControl.xaml.cs +++ b/mpvConfEdit/SearchTextBoxUserControl.xaml.cs @@ -21,7 +21,7 @@ namespace Controls private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) { - SearchTextBlock.Text = SearchTextBox.Text == "" ? "Find a setting" : ""; + HintTextBlock.Text = SearchTextBox.Text == "" ? "Find a setting" : ""; if (SearchTextBox.Text == "") SearchClearButton.Visibility = Visibility.Hidden; diff --git a/mpvConfEdit/mpvConfEdit.toml b/mpvConfEdit/mpvConf.toml similarity index 98% rename from mpvConfEdit/mpvConfEdit.toml rename to mpvConfEdit/mpvConf.toml index 17b21f8..3ff1724 100644 --- a/mpvConfEdit/mpvConfEdit.toml +++ b/mpvConfEdit/mpvConf.toml @@ -146,12 +146,38 @@ default = "100" filter = "Audio" help = "--volume= Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\"). Default: 100" +[[settings]] +name = "alang" +default = "" +filter = "Audio" +help = "--alang= Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also --aid.\n\nExamples\n\nmpv dvd://1 --alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv --alang=jpn example.mkv plays a Matroska file with Japanese audio." + +[[settings]] +name = "audio-file-auto" +default = "no" +filter = "Audio" +help = "--audio-file-auto=, --no-audio-file-auto Load additional audio files matching the video filename. The parameter specifies how external audio files are matched." +options = [{ name = "no", help = "Don't automatically load external audio files (default)." }, + { name = "exact", help = "Load the media filename with audio file extension." }, + { name = "fuzzy", help = "Load all audio files containing media filename." }, + { name = "all", help = "Load all audio files in the current and --audio-file-paths directories." }] + [[settings]] name = "slang" default = "" filter = "Subtitle" help = "--slang= Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also --sid." +[[settings]] +name = "sub-auto" +default = "exact" +filter = "Subtitle" +help = "--sub-auto=, --no-sub-auto Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default." +options = [{ name = "no", help = "Don't automatically load external subtitle files." }, + { name = "exact", help = "Load the media filename with subtitle file extension (Default)." }, + { name = "fuzzy", help = "Load all subs containing media filename." }, + { name = "all", help = "Load all subs in the current and --sub-file-paths directories." }] + [[settings]] name = "screen" default = "" @@ -163,18 +189,31 @@ name = "osd-playing-msg" default = "" width = 300 filter = "Screen" -help = "--osd-playing-msg= Show a message on OSD when playback starts. The string is expanded for properties, e.g. --osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename.\n\nFor more information visit:" +help = "--osd-playing-msg= Show a message on OSD when playback starts. The string is expanded for properties, e.g. --osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:" helpurl = "https://mpv.io/manual/master/#property-expansion" [[settings]] name = "fullscreen" -alias = "fs" default = "no" filter = "Screen" help = "--fullscreen=, fs= Start the player in fullscreen mode. Default: no." options = [{ name = "yes" }, { name = "no" }] +[[settings]] +name = "screenshot-directory" +default = "" +width = 500 +folder = true +filter = "Screen" +help = "--screenshot-directory= Store screenshots in this directory. This path is joined with the filename generated by --screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop." + +[[settings]] +name = "autofit" +default = "50%" +filter = "Screen" +help = "--autofit= Set the initial window size in percent. Please note that this setting is only partly implemented in mpv.net, accepted are only integer values with percent sign added. Default: 50%." + [[settings]] name = "keep-open-pause" default = "yes" @@ -194,7 +233,6 @@ options = [{ name = "yes", help = "Don't terminate if the current file is the [[settings]] name = "loop-file" -alias = "loop" default = "" filter = "Playback" help = "--loop-file=, loop= Loop a single file N times. inf means forever, no means normal playback. For compatibility, --loop-file and --loop-file=yes are also accepted, and are the same as --loop-file=inf.\n\nThe difference to --loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file.\n\n--loop is an alias for this option." @@ -207,14 +245,6 @@ help = "--save-position-on-quit= Always save the current playback positi options = [{ name = "yes" }, { name = "no" }] -[[settings]] -name = "screenshot-directory" -default = "" -width = 500 -folder = true -filter = "Screen" -help = "--screenshot-directory= Store screenshots in this directory. This path is joined with the filename generated by --screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop." - [[settings]] name = "input-ar-delay" default = "" @@ -227,12 +257,6 @@ default = "" filter = "Input" help = "--input-ar-rate= Number of key presses to generate per second on autorepeat." -[[settings]] -name = "alang" -default = "" -filter = "Audio" -help = "--alang= Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also --aid.\n\nExamples\n\nmpv dvd://1 --alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv --alang=jpn example.mkv plays a Matroska file with Japanese audio." - [[settings]] name = "hr-seek" default = "absolute" @@ -255,24 +279,4 @@ options = [{ name = "yes" }, name = "loop-playlist" default = "" filter = "Playback" -help = "--loop-playlist=, --loop-playlist Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. --loop-playlist is the same as --loop-playlist=inf.\n\nThe force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions." - -[[settings]] -name = "audio-file-auto" -default = "no" -filter = "Audio" -help = "--audio-file-auto=, --no-audio-file-auto Load additional audio files matching the video filename. The parameter specifies how external audio files are matched." -options = [{ name = "no", help = "Don't automatically load external audio files (default)." }, - { name = "exact", help = "Load the media filename with audio file extension." }, - { name = "fuzzy", help = "Load all audio files containing media filename." }, - { name = "all", help = "Load all audio files in the current and --audio-file-paths directories." }] - -[[settings]] -name = "sub-auto" -default = "exact" -filter = "Subtitle" -help = "--sub-auto=, --no-sub-auto Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default." -options = [{ name = "no", help = "Don't automatically load external subtitle files." }, - { name = "exact", help = "Load the media filename with subtitle file extension (Default)." }, - { name = "fuzzy", help = "Load all subs containing media filename." }, - { name = "all", help = "Load all subs in the current and --sub-file-paths directories." }] \ No newline at end of file +help = "--loop-playlist=, --loop-playlist Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. --loop-playlist is the same as --loop-playlist=inf.\n\nThe force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions." \ No newline at end of file diff --git a/mpvConfEdit/mpvConfEdit.csproj b/mpvConfEdit/mpvConfEdit.csproj index 28b8980..09dbef6 100644 --- a/mpvConfEdit/mpvConfEdit.csproj +++ b/mpvConfEdit/mpvConfEdit.csproj @@ -50,6 +50,7 @@ + @@ -125,6 +126,9 @@ Resources.Designer.cs + + Always + SettingsSingleFileGenerator Settings.Designer.cs @@ -134,7 +138,7 @@ - + Always diff --git a/mpvConfEdit/mpvNetConf.toml b/mpvConfEdit/mpvNetConf.toml new file mode 100644 index 0000000..9ec7a9f --- /dev/null +++ b/mpvConfEdit/mpvNetConf.toml @@ -0,0 +1,8 @@ +[[settings]] +name = "dark-mode" +default = "system" +filter = "mpv.net" +help = "Enables a dark theme." +options = [{ name = "always" }, + { name = "system" , help = "Windows 10+" }, + { name = "never" }] \ No newline at end of file