Skip to content

Commit

Permalink
new menu items and bindings to open mpv.conf and input.conf with a te…
Browse files Browse the repository at this point in the history
…xt editor
  • Loading branch information
stax76 committed Dec 14, 2023
1 parent 9d4779f commit cd54e67
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 173 deletions.
5 changes: 3 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
3 changes: 3 additions & 0 deletions src/MpvNet.Windows/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
56 changes: 54 additions & 2 deletions src/MpvNet.Windows/GuiCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -99,6 +104,53 @@ public void Open_DVD_Or_BD_Folder(IList<string> args)
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())
Expand Down Expand Up @@ -249,7 +301,7 @@ public void ShowMediaInfo(IList<string> args)
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
Expand All @@ -262,7 +314,7 @@ public void ShowMediaInfo(IList<string> args)

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()
{
Expand Down
126 changes: 126 additions & 0 deletions src/MpvNet.Windows/Help/WinApiHelp.cs
Original file line number Diff line number Diff line change
@@ -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 "";
}
}
93 changes: 7 additions & 86 deletions src/MpvNet.Windows/Native/WinApi.cs
Original file line number Diff line number Diff line change
@@ -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);

Expand Down Expand Up @@ -60,69 +59,28 @@ public static extern bool SetWindowPos(
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);

[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
{
Expand Down Expand Up @@ -171,41 +129,4 @@ public struct CopyDataStruct
[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);
}
}
Loading

0 comments on commit cd54e67

Please sign in to comment.