new menu items and bindings to open mpv.conf and input.conf with a text editor
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
|
||||
# v7.0.0.3 Beta (2023-??-??)
|
||||
|
||||
- New menu item `Settings/Setup/Add mpv.net to Path environment variable' added.
|
||||
- New menu item `Settings/Edit mpv.conf` added for opening mpv.conf with a text editor. Default binding `c`.
|
||||
- New menu item `Settings/Edit input.conf` added for opening input.conf with a text editor. Default binding `k`.
|
||||
- mpv.net can no longer be downloaded from the Microsoft store due
|
||||
to a general very poor experience with the package creation and submission.
|
||||
This means winget download support is unavailable until a new winget solution is implemented.
|
||||
- New menu item added at Settings/Setup to add mpv.net to the path environment variable.
|
||||
- Improved conf file reader/writer.
|
||||
- Conf editor support added for the mpv options:
|
||||
`reset-on-next-file`, `input-ipc-server`, `background`, `title`
|
||||
|
||||
# v7.0.0.2 Beta (2023-12-13)
|
||||
|
||||
- Besides a portable download there is now again a setup installer.
|
||||
|
||||
@@ -26,3 +26,6 @@ dotnet_diagnostic.CA1822.severity = none
|
||||
|
||||
# IDE0057: Use range operator
|
||||
csharp_style_prefer_range_operator = false
|
||||
|
||||
# CA1401: P/Invokes should not be visible
|
||||
dotnet_diagnostic.CA1401.severity = none
|
||||
|
||||
@@ -11,6 +11,9 @@ using MpvNet.Windows.WinForms;
|
||||
using MpvNet.Windows.WPF.Views;
|
||||
using MpvNet.Windows.WPF;
|
||||
using MpvNet.Windows.WPF.MsgBox;
|
||||
using MpvNet.Help;
|
||||
using System.Text.Json;
|
||||
using MpvNet.Windows.Help;
|
||||
|
||||
namespace MpvNet;
|
||||
|
||||
@@ -46,6 +49,8 @@ public class GuiCommand
|
||||
["show-bindings"] = args => ShowBindings(),
|
||||
["show-playlist"] = args => ShowPlaylist(),
|
||||
["add-to-path"] = args => AddToPath(),
|
||||
["edit-conf-file"] = EditCongFile,
|
||||
["show-commands"] = args => ShowCommands(),
|
||||
|
||||
|
||||
// deprecated
|
||||
@@ -99,6 +104,53 @@ public class GuiCommand
|
||||
Player.LoadDiskFolder(dialog.SelectedPath);
|
||||
}
|
||||
|
||||
public void EditCongFile(IList<string> args)
|
||||
{
|
||||
string file = Player.ConfigFolder + args[0];
|
||||
|
||||
if (File.Exists(file))
|
||||
ProcessHelp.ShellExecute(WinApiHelp.GetAppPathForExtension("txt"), "\"" + file + "\"");
|
||||
}
|
||||
|
||||
public static void ShowTextWithEditor(string name, string text)
|
||||
{
|
||||
string file = Path.Combine(Path.GetTempPath(), name + ".txt");
|
||||
App.TempFiles.Add(file);
|
||||
File.WriteAllText(file, BR + text.Trim() + BR);
|
||||
ProcessHelp.ShellExecute(WinApiHelp.GetAppPathForExtension("txt"), "\"" + file + "\"");
|
||||
}
|
||||
|
||||
public static void ShowCommands()
|
||||
{
|
||||
string json = Core.GetPropertyString("command-list");
|
||||
var enumerator = JsonDocument.Parse(json).RootElement.EnumerateArray();
|
||||
var commands = enumerator.OrderBy(it => it.GetProperty("name").GetString());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (var cmd in commands)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(cmd.GetProperty("name").GetString());
|
||||
|
||||
foreach (var args in cmd.GetProperty("args").EnumerateArray())
|
||||
{
|
||||
string value = args.GetProperty("name").GetString() + " <" +
|
||||
args.GetProperty("type").GetString()!.ToLower() + ">";
|
||||
|
||||
if (args.GetProperty("optional").GetBoolean())
|
||||
value = "[" + value + "]";
|
||||
|
||||
sb.AppendLine(" " + value);
|
||||
}
|
||||
}
|
||||
|
||||
string header = BR +
|
||||
"https://mpv.io/manual/master/#list-of-input-commands" + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts#command_palette" + BR;
|
||||
|
||||
ShowTextWithEditor("Input Commands", header + sb.ToString());
|
||||
}
|
||||
|
||||
public void OpenFromClipboard(IList<string> args)
|
||||
{
|
||||
if (System.Windows.Forms.Clipboard.ContainsFileDropList())
|
||||
@@ -249,7 +301,7 @@ public class GuiCommand
|
||||
text = text.TrimEx();
|
||||
|
||||
if (editor)
|
||||
Command.ShowTextWithEditor("media-info", text);
|
||||
ShowTextWithEditor("media-info", text);
|
||||
else if (osd)
|
||||
Command.ShowText(text.Replace("\r", ""), 5000, 16);
|
||||
else
|
||||
@@ -262,7 +314,7 @@ public class GuiCommand
|
||||
|
||||
public static string FormatTime(double value) => ((int)value).ToString("00");
|
||||
|
||||
public void ShowBindings() => Command.ShowTextWithEditor("Bindings", Player.UsedInputConfContent);
|
||||
public void ShowBindings() => ShowTextWithEditor("Bindings", Player.UsedInputConfContent);
|
||||
|
||||
public void AddToPath()
|
||||
{
|
||||
|
||||
126
src/MpvNet.Windows/Help/WinApiHelp.cs
Normal file
126
src/MpvNet.Windows/Help/WinApiHelp.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
using static MpvNet.Windows.Native.WinApi;
|
||||
|
||||
namespace MpvNet.Windows.Help;
|
||||
|
||||
public class WinApiHelp
|
||||
{
|
||||
public static Version WindowsTen1607 { get; } = new Version(10, 0, 14393); // Windows 10 1607
|
||||
|
||||
public static int GetResizeBorder(int v)
|
||||
{
|
||||
switch (v)
|
||||
{
|
||||
case 1 /* WMSZ_LEFT */ : return 3;
|
||||
case 3 /* WMSZ_TOP */ : return 2;
|
||||
case 2 /* WMSZ_RIGHT */ : return 3;
|
||||
case 6 /* WMSZ_BOTTOM */ : return 2;
|
||||
case 4 /* WMSZ_TOPLEFT */ : return 1;
|
||||
case 5 /* WMSZ_TOPRIGHT */ : return 1;
|
||||
case 7 /* WMSZ_BOTTOMLEFT */ : return 3;
|
||||
case 8 /* WMSZ_BOTTOMRIGHT */ : return 3;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractWindowBorders(IntPtr hwnd, ref Rect rc, int dpi)
|
||||
{
|
||||
Rect r = new Rect(0, 0, 0, 0);
|
||||
AddWindowBorders(hwnd, ref r, dpi);
|
||||
rc.Left -= r.Left;
|
||||
rc.Top -= r.Top;
|
||||
rc.Right -= r.Right;
|
||||
rc.Bottom -= r.Bottom;
|
||||
}
|
||||
|
||||
public static void AddWindowBorders(IntPtr hwnd, ref Rect rc, int dpi)
|
||||
{
|
||||
uint windowStyle = (uint)GetWindowLong(hwnd, -16); // GWL_STYLE
|
||||
uint windowStyleEx = (uint)GetWindowLong(hwnd, -20); // GWL_EXSTYLE
|
||||
|
||||
if (Environment.OSVersion.Version >= WindowsTen1607)
|
||||
AdjustWindowRectExForDpi(ref rc, windowStyle, false, windowStyleEx, (uint)dpi);
|
||||
else
|
||||
AdjustWindowRect(ref rc, windowStyle, false);
|
||||
}
|
||||
|
||||
public static Rectangle GetWorkingArea(IntPtr handle, Rectangle workingArea)
|
||||
{
|
||||
if (handle != IntPtr.Zero && GetDwmWindowRect(handle, out Rect dwmRect) &&
|
||||
GetWindowRect(handle, out Rect rect))
|
||||
{
|
||||
int left = workingArea.Left;
|
||||
int top = workingArea.Top;
|
||||
int right = workingArea.Right;
|
||||
int bottom = workingArea.Bottom;
|
||||
|
||||
left += rect.Left - dwmRect.Left;
|
||||
top -= rect.Top - dwmRect.Top;
|
||||
right -= dwmRect.Right - rect.Right;
|
||||
bottom -= dwmRect.Bottom - rect.Bottom;
|
||||
|
||||
return new Rectangle(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
return workingArea;
|
||||
}
|
||||
|
||||
public static bool GetDwmWindowRect(IntPtr handle, out Rect rect)
|
||||
{
|
||||
const uint DWMWA_EXTENDED_FRAME_BOUNDS = 9;
|
||||
|
||||
return 0 == DwmGetWindowAttribute(handle, DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||
out rect, (uint)Marshal.SizeOf<Rect>());
|
||||
}
|
||||
|
||||
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return GetWindowLongPtr(hWnd, nIndex);
|
||||
else
|
||||
return GetWindowLong32(hWnd, nIndex);
|
||||
}
|
||||
|
||||
public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return SetWindowLongPtr(hWnd, nIndex, dwNewLong);
|
||||
else
|
||||
return SetWindowLong32(hWnd, nIndex, dwNewLong);
|
||||
}
|
||||
|
||||
public static string GetAppPathForExtension(params string[] extensions)
|
||||
{
|
||||
foreach (string it in extensions)
|
||||
{
|
||||
string extension = it;
|
||||
|
||||
if (!extension.StartsWith("."))
|
||||
extension = "." + extension;
|
||||
|
||||
uint c = 0U;
|
||||
|
||||
if (AssocQueryString(0x40, 2, extension, null, null, ref c) == 1)
|
||||
{
|
||||
if (c > 0L)
|
||||
{
|
||||
var sb = new StringBuilder((int)c);
|
||||
|
||||
if (0 == AssocQueryString(0x40, 2, extension, default, sb, ref c))
|
||||
{
|
||||
string ret = sb.ToString();
|
||||
|
||||
if (File.Exists(ret))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace MpvNet.Windows.Native;
|
||||
|
||||
public static class WinApi
|
||||
{
|
||||
public static Version WindowsTen1607 { get; } = new Version(10, 0, 14393); // Windows 10 1607
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool AttachConsole(int dwProcessId);
|
||||
|
||||
@@ -60,18 +59,10 @@ public static class WinApi
|
||||
IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
||||
|
||||
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return GetWindowLongPtr(hWnd, nIndex);
|
||||
else
|
||||
return GetWindowLong32(hWnd, nIndex);
|
||||
}
|
||||
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||
public static extern IntPtr SetWindowLong32(IntPtr hWnd, int nIndex, uint dwNewLong);
|
||||
@@ -79,50 +70,17 @@ public static class WinApi
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, uint dwNewLong);
|
||||
|
||||
public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return SetWindowLongPtr(hWnd, nIndex, dwNewLong);
|
||||
else
|
||||
return SetWindowLong32(hWnd, nIndex, dwNewLong);
|
||||
}
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||
|
||||
[DllImport("shlwapi", CharSet = CharSet.Auto)]
|
||||
public static extern uint AssocQueryString(
|
||||
uint flags, uint str, string? pszAssoc, string? pszExtra, [Out] StringBuilder? pszOut, ref uint pcchOut);
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmGetWindowAttribute(
|
||||
IntPtr hwnd, uint dwAttribute, out Rect pvAttribute, uint cbAttribute);
|
||||
|
||||
public static bool GetDwmWindowRect(IntPtr handle, out Rect rect)
|
||||
{
|
||||
const uint DWMWA_EXTENDED_FRAME_BOUNDS = 9;
|
||||
|
||||
return 0 == DwmGetWindowAttribute(handle, DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||
out rect, (uint)Marshal.SizeOf<Rect>());
|
||||
}
|
||||
|
||||
public static Rectangle GetWorkingArea(IntPtr handle, Rectangle workingArea)
|
||||
{
|
||||
if (handle != IntPtr.Zero && GetDwmWindowRect(handle, out Rect dwmRect) &&
|
||||
GetWindowRect(handle, out Rect rect))
|
||||
{
|
||||
int left = workingArea.Left;
|
||||
int top = workingArea.Top;
|
||||
int right = workingArea.Right;
|
||||
int bottom = workingArea.Bottom;
|
||||
|
||||
left += rect.Left - dwmRect.Left;
|
||||
top -= rect.Top - dwmRect.Top;
|
||||
right -= dwmRect.Right - rect.Right;
|
||||
bottom -= dwmRect.Bottom - rect.Bottom;
|
||||
|
||||
return new Rectangle(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
return workingArea;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Rect
|
||||
{
|
||||
@@ -171,41 +129,4 @@ public static class WinApi
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string lpData;
|
||||
}
|
||||
|
||||
public static int GetResizeBorder(int v)
|
||||
{
|
||||
switch (v)
|
||||
{
|
||||
case 1 /* WMSZ_LEFT */ : return 3;
|
||||
case 3 /* WMSZ_TOP */ : return 2;
|
||||
case 2 /* WMSZ_RIGHT */ : return 3;
|
||||
case 6 /* WMSZ_BOTTOM */ : return 2;
|
||||
case 4 /* WMSZ_TOPLEFT */ : return 1;
|
||||
case 5 /* WMSZ_TOPRIGHT */ : return 1;
|
||||
case 7 /* WMSZ_BOTTOMLEFT */ : return 3;
|
||||
case 8 /* WMSZ_BOTTOMRIGHT */ : return 3;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SubtractWindowBorders(IntPtr hwnd, ref Rect rc, int dpi)
|
||||
{
|
||||
Rect r = new Rect(0, 0, 0, 0);
|
||||
AddWindowBorders(hwnd, ref r, dpi);
|
||||
rc.Left -= r.Left;
|
||||
rc.Top -= r.Top;
|
||||
rc.Right -= r.Right;
|
||||
rc.Bottom -= r.Bottom;
|
||||
}
|
||||
|
||||
public static void AddWindowBorders(IntPtr hwnd, ref Rect rc, int dpi)
|
||||
{
|
||||
uint windowStyle = (uint)GetWindowLong(hwnd, -16); // GWL_STYLE
|
||||
uint windowStyleEx = (uint)GetWindowLong(hwnd, -20); // GWL_EXSTYLE
|
||||
|
||||
if (Environment.OSVersion.Version >= WindowsTen1607)
|
||||
AdjustWindowRectExForDpi(ref rc, windowStyle, false, windowStyleEx, (uint)dpi);
|
||||
else
|
||||
AdjustWindowRect(ref rc, windowStyle, false);
|
||||
}
|
||||
}
|
||||
|
||||
39
src/MpvNet.Windows/WinForms/MainForm.Designer.cs
generated
39
src/MpvNet.Windows/WinForms/MainForm.Designer.cs
generated
@@ -29,36 +29,35 @@ partial class MainForm
|
||||
/// </summary>
|
||||
void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
this.CursorTimer = new System.Windows.Forms.Timer(this.components);
|
||||
this.ProgressTimer = new System.Windows.Forms.Timer(this.components);
|
||||
this.SuspendLayout();
|
||||
CursorTimer = new System.Windows.Forms.Timer(components);
|
||||
ProgressTimer = new System.Windows.Forms.Timer(components);
|
||||
SuspendLayout();
|
||||
//
|
||||
// CursorTimer
|
||||
//
|
||||
this.CursorTimer.Enabled = true;
|
||||
this.CursorTimer.Interval = 1000;
|
||||
this.CursorTimer.Tick += new System.EventHandler(this.CursorTimer_Tick);
|
||||
CursorTimer.Enabled = true;
|
||||
CursorTimer.Interval = 1000;
|
||||
CursorTimer.Tick += CursorTimer_Tick;
|
||||
//
|
||||
// ProgressTimer
|
||||
//
|
||||
this.ProgressTimer.Tick += new System.EventHandler(this.ProgressTimer_Tick);
|
||||
ProgressTimer.Tick += ProgressTimer_Tick;
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(288F, 288F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(857, 444);
|
||||
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.Name = "MainForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.ResumeLayout(false);
|
||||
|
||||
AllowDrop = true;
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(288F, 288F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||
BackColor = System.Drawing.Color.Black;
|
||||
ClientSize = new System.Drawing.Size(1243, 720);
|
||||
Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon");
|
||||
Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
Name = "MainForm";
|
||||
StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -210,7 +210,7 @@ public partial class MainForm : Form
|
||||
{
|
||||
BeginInvoke(() => {
|
||||
Screen screen = Screen.FromControl(this);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
@@ -521,7 +521,7 @@ public partial class MainForm : Form
|
||||
}
|
||||
|
||||
Screen screen = Screen.FromControl(this);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
int autoFitHeight = Convert.ToInt32(workingArea.Height * Player.Autofit);
|
||||
|
||||
if (App.AutofitAudio > 1)
|
||||
@@ -610,7 +610,7 @@ public partial class MainForm : Form
|
||||
|
||||
void SetSize(int width, int height, Screen screen, bool checkAutofit = true)
|
||||
{
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
|
||||
int maxHeight = workingArea.Height - (Height - ClientSize.Height) - 2;
|
||||
int maxWidth = workingArea.Width - (Width - ClientSize.Width);
|
||||
@@ -653,7 +653,7 @@ public partial class MainForm : Form
|
||||
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var rect = new Rect(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
AddWindowBorders(Handle, ref rect, GetDpi(Handle));
|
||||
WinApiHelp.AddWindowBorders(Handle, ref rect, GetDpi(Handle));
|
||||
|
||||
int left = middlePos.X - rect.Width / 2;
|
||||
int top = middlePos.Y - rect.Height / 2;
|
||||
@@ -668,10 +668,10 @@ public partial class MainForm : Form
|
||||
|
||||
Screen[] screens = Screen.AllScreens;
|
||||
|
||||
int minLeft = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).X).Min();
|
||||
int maxRight = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).Right).Max();
|
||||
int minTop = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).Y).Min();
|
||||
int maxBottom = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).Bottom).Max();
|
||||
int minLeft = screens.Select(val => WinApiHelp.GetWorkingArea(Handle, val.WorkingArea).X).Min();
|
||||
int maxRight = screens.Select(val => WinApiHelp.GetWorkingArea(Handle, val.WorkingArea).Right).Max();
|
||||
int minTop = screens.Select(val => WinApiHelp.GetWorkingArea(Handle, val.WorkingArea).Y).Min();
|
||||
int maxBottom = screens.Select(val => WinApiHelp.GetWorkingArea(Handle, val.WorkingArea).Bottom).Max();
|
||||
|
||||
if (left < minLeft)
|
||||
left = minLeft;
|
||||
@@ -734,7 +734,7 @@ public partial class MainForm : Form
|
||||
|
||||
public int GetHorizontalLocation(Screen screen)
|
||||
{
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle rect = new Rectangle(Left - workingArea.X, Top - workingArea.Y, Width, Height);
|
||||
|
||||
if (workingArea.Width / (float)Width < 1.1)
|
||||
@@ -751,7 +751,7 @@ public partial class MainForm : Form
|
||||
|
||||
public int GetVerticalLocation(Screen screen)
|
||||
{
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle rect = new Rectangle(Left - workingArea.X, Top - workingArea.Y, Width, Height);
|
||||
|
||||
if (workingArea.Height / (float)Height < 1.1)
|
||||
@@ -1018,7 +1018,7 @@ public partial class MainForm : Form
|
||||
{
|
||||
Rect rc = Marshal.PtrToStructure<Rect>(m.LParam);
|
||||
Rect r = rc;
|
||||
SubtractWindowBorders(Handle, ref r, GetDpi(Handle));
|
||||
WinApiHelp.SubtractWindowBorders(Handle, ref r, GetDpi(Handle));
|
||||
|
||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||
Size videoSize = Player.VideoSize;
|
||||
@@ -1032,7 +1032,7 @@ public partial class MainForm : Form
|
||||
|
||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
||||
int corner = GetResizeBorder(m.WParam.ToInt32());
|
||||
int corner = WinApiHelp.GetResizeBorder(m.WParam.ToInt32());
|
||||
|
||||
if (corner >= 0)
|
||||
corners[corner] -= d_corners[corner];
|
||||
@@ -1384,7 +1384,7 @@ public partial class MainForm : Form
|
||||
|
||||
public static int GetDpi(IntPtr hwnd)
|
||||
{
|
||||
if (Environment.OSVersion.Version >= WindowsTen1607 && hwnd != IntPtr.Zero)
|
||||
if (Environment.OSVersion.Version >= WinApiHelp.WindowsTen1607 && hwnd != IntPtr.Zero)
|
||||
return GetDpiForWindow(hwnd);
|
||||
else
|
||||
using (Graphics gx = Graphics.FromHwnd(hwnd))
|
||||
|
||||
@@ -1,4 +1,64 @@
|
||||
<root>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using MpvNet.Windows.Help;
|
||||
using MpvNet.Windows.Native;
|
||||
|
||||
using static MpvNet.Windows.Native.WinApi;
|
||||
|
||||
namespace MpvNet.Windows.WinForms;
|
||||
|
||||
public class SnapManager
|
||||
@@ -35,7 +34,7 @@ public class SnapManager
|
||||
void FindSnap(ref Rectangle effectiveBounds)
|
||||
{
|
||||
Screen currentScreen = Screen.FromPoint(effectiveBounds.Location);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, currentScreen.WorkingArea);
|
||||
Rectangle workingArea = WinApiHelp.GetWorkingArea(Handle, currentScreen.WorkingArea);
|
||||
|
||||
if (InSnapRange(effectiveBounds.Left, workingArea.Left + AnchorDistance))
|
||||
effectiveBounds.X = workingArea.Left + AnchorDistance;
|
||||
|
||||
@@ -18,7 +18,6 @@ public class Command
|
||||
["play-pause"] = PlayPause,
|
||||
["shell-execute"] = args => ProcessHelp.ShellExecute(args[0]),
|
||||
["show-text"] = args => ShowText(args[0], Convert.ToInt32(args[1]), Convert.ToInt32(args[2])),
|
||||
["show-commands"] = args => ShowCommands(),
|
||||
["cycle-audio"] = args => CycleAudio(),
|
||||
["cycle-subtitles"] = args => CycleSubtitles(),
|
||||
["playlist-first"] = args => PlaylistFirst(),
|
||||
@@ -52,37 +51,6 @@ public class Command
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowCommands()
|
||||
{
|
||||
string json = Core.GetPropertyString("command-list");
|
||||
var enumerator = JsonDocument.Parse(json).RootElement.EnumerateArray();
|
||||
var commands = enumerator.OrderBy(it => it.GetProperty("name").GetString());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (var cmd in commands)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(cmd.GetProperty("name").GetString());
|
||||
|
||||
foreach (var args in cmd.GetProperty("args").EnumerateArray())
|
||||
{
|
||||
string value = args.GetProperty("name").GetString() + " <" +
|
||||
args.GetProperty("type").GetString()!.ToLower() + ">";
|
||||
|
||||
if (args.GetProperty("optional").GetBoolean())
|
||||
value = "[" + value + "]";
|
||||
|
||||
sb.AppendLine(" " + value);
|
||||
}
|
||||
}
|
||||
|
||||
string header = BR +
|
||||
"https://mpv.io/manual/master/#list-of-input-commands" + BR2 +
|
||||
"https://github.com/stax76/mpv-scripts#command_palette" + BR;
|
||||
|
||||
ShowTextWithEditor("Input Commands", header + sb.ToString());
|
||||
}
|
||||
|
||||
public static void ShowText(string text, int duration = 0, int fontSize = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
@@ -98,14 +66,6 @@ public class Command
|
||||
"}${osd-ass-cc/1}" + text + "\" " + duration);
|
||||
}
|
||||
|
||||
public static void ShowTextWithEditor(string name, string text)
|
||||
{
|
||||
string file = Path.Combine(Path.GetTempPath(), name + ".txt");
|
||||
App.TempFiles.Add(file);
|
||||
File.WriteAllText(file, BR + text.Trim() + BR);
|
||||
ProcessHelp.ShellExecute(file);
|
||||
}
|
||||
|
||||
public static void CycleAudio()
|
||||
{
|
||||
Player.UpdateExternalTracks();
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
namespace MpvNet.Help;
|
||||
|
||||
namespace MpvNet.Help;
|
||||
|
||||
public static class ProcessHelp
|
||||
{
|
||||
public static void Execute(string file, string arguments = "", bool shellExecute = false)
|
||||
{
|
||||
using Process proc = new Process();
|
||||
proc.StartInfo.FileName = file;
|
||||
proc.StartInfo.Arguments = arguments;
|
||||
proc.StartInfo.UseShellExecute = shellExecute;
|
||||
proc.Start();
|
||||
try
|
||||
{
|
||||
using Process proc = new Process();
|
||||
proc.StartInfo.FileName = file;
|
||||
proc.StartInfo.Arguments = arguments;
|
||||
proc.StartInfo.UseShellExecute = shellExecute;
|
||||
proc.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Terminal.WriteError(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShellExecute(string file, string arguments = "") => Execute(file, arguments, true);
|
||||
|
||||
@@ -149,6 +149,10 @@ public static class InputHelp
|
||||
|
||||
new (_("Settings"), _("Show Config Editor"), "script-message-to mpvnet show-conf-editor", "Ctrl+,"),
|
||||
new (_("Settings"), _("Show Input Editor"), "script-message-to mpvnet show-input-editor", "Ctrl+i"),
|
||||
new (_("Settings"), "-"),
|
||||
new (_("Settings"), _("Edit mpv.conf"), "script-message-to mpvnet edit-conf-file mpv.conf", "c"),
|
||||
new (_("Settings"), _("Edit input.conf"), "script-message-to mpvnet edit-conf-file input.conf", "k"),
|
||||
new (_("Settings"), "-"),
|
||||
new (_("Settings"), _("Open Config Folder"), "script-message-to mpvnet open-conf-folder", "Ctrl+f"),
|
||||
new (_("Settings") + " > " + _("Setup"), _("Register video file associations"), "script-message-to mpvnet reg-file-assoc video"),
|
||||
new (_("Settings") + " > " + _("Setup"), _("Register audio file associations"), "script-message-to mpvnet reg-file-assoc audio"),
|
||||
|
||||
Reference in New Issue
Block a user